




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第如何基于opencv实现简单的数字识别目录前言要解决的问题解决问题的思路总结
前言
由于自己学识尚浅,不能用python深度学习来识别这里的数字,所以就完全采用opencv来识别数字,然后在这里分享、记录一下自己在学习过程中的一些所见所得和所想
要解决的问题
这是一个要识别的数字,我这里首先是对图像进行一个ROI的提取,提取结果就仅仅剩下数字,把其他的一些无关紧要的要素排除在外,
这是ROI图片,我们要做的就是识别出该照片中的数字,
解决问题的思路
1、先把这个图片中的数字分割,分割成为5张小图片,每张图片包含一个数字,为啥要分割呢?因为我们没办法让计算机知道这个数字是多少,所以只能根据特征,让计算机去识别特征,然后每一个特征对应一个值,首先贴出分割图片的程序,然后在程序下方会有一段思路解释
#includeopencv2/core/core.hpp
#includeopencv.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/features2d/features2d.hpp
#includeopencv2/imgproc/imgproc.hpp
#includeiostream
#includectime
usingnamespacestd;
usingnamespacecv;
#includemap
Matsrc_threshold;
Matsrc_dil;
intsunImage(Matimage);
vectorMatROI_image;//待测图片
intmain()
clock_tstart,finish;
start=clock();
Matsrc;
src=imread("D:\\vspic\\picture\\number6.jpg");
resize(src,src,Size(src.cols/7,src.rows/7));
imshow("src",src);
Matsrc_gray;
cvtColor(src,src_gray,COLOR_BGR2GRAY);
//imshow("gsrc_ray",src_gray);
Matsrc_blur;
blur(src_gray,src_blur,Size(9,9));
//GaussianBlur(src_gray,src_blur,Size(11,11),1,1);
Matsrc_threshold;
threshold(src_blur,src_threshold,150,255,THRESH_OTSU);
//imshow("src_threshold",src_threshold);
Matsrc_canny;
Canny(src_threshold,src_canny,125,255,3);
//imshow("src_canny",src_canny);
vectorvectorPointcontours_src;
vectorVec4ihierarchy_src(contours_src.size());
findContours(src_canny,contours_src,hierarchy_src,RETR_EXTERNAL,CHAIN_APPROX_NONE);
Rectrect_s;
Rectchoose_rect;
for(size_ti=0;icontours_src.size();i++)
rect_s=boundingRect(contours_src[i]);
doublewidth=rect_s.width;
doubleheight=rect_s.height;
doublebizhi=width/height;
if(bizhi1.5height50)
/*rectangle(src,rect_s.tl(),rect_s.br(),Scalar(255,255,255),1,1,0);*/
choose_rect=Rect(rect_s.x+20,rect_s.y+30,rect_s.x-30,rect_s.y-108);
Matroi;
roi=src(choose_rect);
//imshow("src_",roi);
Matimg=roi;
Matgray_img;
//生成灰度图像
cvtColor(img,gray_img,CV_BGR2GRAY);
//高斯模糊
Matimg_gau;
GaussianBlur(gray_img,img_gau,Size(3,3),0,0);
//阈值分割
Matimg_seg;
threshold(img_gau,img_seg,0,255,THRESH_BINARY+THRESH_OTSU);
Matelement;
element=getStructuringElement(MORPH_RECT,Size(8,8));
erode(img_seg,src_dil,element);
//imshow("src_dil",src_dil);
//边缘检测,提取轮廓
Matimg_canny;
Canny(src_dil,img_canny,200,100);
//imshow("canny",img_canny);
vectorvectorPointcontours;
vectorVec4ihierarchy(contours.size());
findContours(img_canny,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE,Point());//寻找轮廓
intsize=(int)(contours.size());//轮廓的数量
//coutsizeendl;6个
//保存符号边框的序号
vectorintnum_order;//定义一个整型int容器
mapint,intnum_map;//容器,需要关键字和模板对象两个模板参数,此处定义一个int作为索引,并拥有相关连的指向int的指针
for(inti=0;isize;i++)
//获取边框数据
Rectnumber_rect=boundingRect(contours[i]);
intwidth=number_rect.width;//获取矩形的宽
intheight=number_rect.height;//获取矩形的高
//去除较小的干扰边框,筛选出合适的区域
if(widthimg.cols/20)
rectangle(img,number_rect.tl(),number_rect.br(),Scalar(255,255,255),1,1,0);//绘制矩形
imshow("img",img);//显示矩形框
num_order.push_back(number_rect.x);//把矩形的x坐标放入number_order容器中,将一个新的元素添加到vector的最后面,
//位置为当前元素的下一个元素
num_map[number_rect.x]=i;//向map中存入键值对,number_rect.x是关键字,i是值
/*把矩形框的x坐标与对应的i值一起放入map容器中,形成一一对应的键值对
//按符号顺序提取
sort(num_order.begin(),num_order.end());/*把number_order容器中的内容按照从小到大的顺序排列,这里面是X的坐标*/
for(inti=0;inum_order.size();i++){
Rectnumber_rect=boundingRect(contours[num_map.find(num_order[i])-second]);//num_order里面放的是坐标
//cout"num_map的值是:"num_map.find(num_order[i])-secondendl;
Rectchoose_rect(number_rect.x,0,number_rect.width,img.rows);//矩形左上角x,y的坐标以及矩形的宽和高
Matnumber_img=img(choose_rect);
resize(number_img,number_img,Size(30,100));//归一化尺寸
ROI_image.push_back(number_img);//保存为待测图片
//imshow("number"+to_string(i),number_img);
charname[50];
sprintf_s(name,"D:\\vs2012\\model\\%d.jpg",i);//保存模板
imwrite(name,number_img);
cout"图片分割完毕"endl;
//加载模板
vectorMattemptImage;//存放模板
for(inti=0;ii++)
charname[50];
sprintf_s(name,"D:\\vs2012\\model\\%d.jpg",i);
Mattemp;
temp=imread(name);
//cout"加载模板图片通道数:"temp.channels()endl;
temptImage.push_back(temp);
vectorint//存放顺序结果
for(inti=0;iROI_image.size();i++)
MatsubImage;
intsum=0;
intmin=50000;
intseq_min=0;//记录最小的和对应的数字
for(intj=0;jj++)
absdiff(ROI_image[i],temptImage[j],subImage);//待测图片像素减去模板图片像素
sum=sunImage(subImage);//统计像素和
if(summin)
min=sum;
seq_min=j;
sum=0;
seq.push_back(seq_min);
cout"输出数字匹配结果:";//endl是换行的意思
for(inti=0;iseq.size();i++)//输出结果,小数点固定在第3位
coutseq[i];
if(i==1)
cout".";
finish=clock();
doubleall_time=double(finish-start)/CLOCKS_PER_SEC;
/*cout"运行总时间是:"all_timeendl;*/
waitKey(0);
return0;
//计算像素和
intsunImage(Matimage)
intsum=0;
for(inti=0;iimage.cols;i++)
for(intj=0;jimage.rows;j++)
sum+=image.atuchar(j,i);
returnsum;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025农产品买卖合同模板
- 水闸消防安全知识培训课件
- 水粉画草丛中的鸭子课件
- 乡镇水源保护方案
- 小升初语文古诗鉴赏知识点衔接-《曲》练习(含答案)
- 桥梁检测设备选型与使用方案
- 学生宿舍节能设计与技术应用方案
- 水电验收课件第五元素
- 水电站业务知识培训课件简报
- 二零二五年度新能源设备采购及运营合作协议
- 陕西省特种设备隐患排查清单(2025年)
- 快递行业交通安全培训
- 货款转让协议书
- 燃气公司加气站操作规程及安全要求
- 装修砸墙安全协议书
- DB4407∕T 70-2021 地理标志产品 新会陈皮
- 送水工劳务合同协议
- 读博协议和合同
- 2025CACA子宫颈癌诊疗指南解读
- 2025年第34届全国中学生物理竞赛预赛试卷及答案(完整版)
- 骨科护理10分钟小讲课
评论
0/150
提交评论