博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单的验证码识别(opecv)
阅读量:4552 次
发布时间:2019-06-08

本文共 4943 字,大约阅读时间需要 16 分钟。

       opencv版本: 3.0.0

           处理验证码: 纯数字验证码 (颜色不同,有噪音,和带有较多的划痕)

             测试时间 :  一天+一晚

                  效果: 比较挫,可能是由于测试的图片是在太小了的缘故.

               原理:

         验证码识别作为身份证号机器识别的一个衍生,夹杂了很多干扰的噪音,所以加大了二值化的难度。以及轮廓追踪的不好协调。

        操作过程大过程有以下几个:

                  (1) 待测试的图片灰度化并二值化

                  (2)预先装载特征库(这里分为多样,形式不一)

                  (3)物体轮廓检测                  

                  (4)扫描待测图片,并进行特征码比对,匹配优先

       处理图片展示:

                

 

 

        代码演示:

         

1 #include
2 3 #include
4 #include
5 6 struct DataBase{ 7 int value; //库特征对应的值 8 vector
sample; //特征库 9 DataBase(int var , Mat & sam){ 10 value = var; 11 sample.push_back(sam); 12 } 13 }; 14 15 typedef struct DataBase dataBase; 16 17 18 19 20 //加载图片 21 bool loadImage(Mat &src , Mat &gray ,String &filename){ 22 23 Mat cbgray ; //合成后图像 24 int chans; //bgR分量 25 src = imread( filename , true ); 26 if( src.empty() ) return false; 27 chans = src.channels(); 28 vector
bgR( chans ) ; 29 //分割通道 30 split(src,bgR); 31 //直方图均衡化 32 for(int chan=0 ; chan < chans ; ++chan ){ 33 equalizeHist(bgR[chan] , bgR[chan]); 34 } 35 //单通道合并 36 merge(bgR , cbgray ); 37 //灰度化 38 cvtColor(cbgray ,gray ,CV_RGB2GRAY); 39 return true ; 40 } 41 42 //二值化 43 bool binImage(Mat& src , Mat& dst , int _size , int lparam ,int mediansize){ 44 //采用自适应二值化 45 adaptiveThreshold(src,src,255,CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY,_size , lparam); 46 //中值滤波 47 medianBlur(src,dst,mediansize); 48 return true; 49 } 50 51 //装载特征库 52 /*通常来说这个应该是预先被加载好,以数据库或者其他的形式保存起来 53 在这地方由于东西比较少,直接现场处理 54 */ 55 int loadProperty(vector
&db ,int index[] 56 , int _size = 31 , int lparam = 7 , int mediansize = 3 ){ 57 58 //固定路径 59 char filename[30]; 60 61 for(int i=0; i<20 ; ++i){ 62 sprintf(filename,"D:\\yzm\\tzk\\%d.png",index[i]); 63 Mat tmp; 64 String path =filename; 65 loadImage(tmp,tmp,path); //装载并灰度化 66 binImage(tmp,tmp,_size,lparam,mediansize); //二值化 67 //imshow("sample",tmp); 68 //waitKey(0); 69 db.push_back( dataBase( index[i]%10 , tmp ) ); 70 } 71 72 return true; 73 } 74 75 76 //对于模块进行匹配 77 int StartMatch(Mat src , vector< dataBase > db , Point &curpx){ 78 79 int res ; 80 double maxValue , minValue ,resValue ; 81 Point minloc , maxloc ,resloc; 82 83 vector< dataBase >::iterator it; 84 vector< Mat >::iterator m_it; 85 86 Mat sample ,result; 87 int curcols , currows; 88 resValue =1.; 89 90 for( it = db.begin() ; it !=db.end() ; it++ ){ 91 92 for( m_it = it->sample.begin() ; m_it != it->sample.end() ; m_it++ ){ 93 94 sample = *m_it; 95 int res_rows = src.rows - sample.rows + 1 ; 96 int res_cols = src.cols - sample.cols + 1 ; 97 if( res_rows < 1 || res_cols< 1 ) break; 98 result = cv::cvarrToMat(cvCreateImage(cvSize(res_cols, res_rows), 1, 1)); 99 100 matchTemplate(src, sample , result ,CV_TM_SQDIFF_NORMED); //模板匹配算法,平方差匹配101 102 minMaxLoc(result, &minValue, &maxValue, &minloc, &maxloc,Mat() );103 if(resValue > minValue){104 resValue = minValue;105 resloc = minloc;106 res = it->value; //记录这个值的大小107 curcols = sample.cols;108 currows = sample.rows;109 }110 }111 }112 113 // rectangle(srcResult, matchLoc, cvPoint(matchLoc.x + curtemplatW, matchLoc.y+ curtemplatH), cvScalar(0,0,255));114 //设定一个阈值115 if(resValue<0.2){116 //++curpx.x;117 curpx.x += resloc.x + curcols/2.; 118 rectangle(src,resloc,cvPoint(resloc.x + curcols , resloc.y + currows ),cvScalar(0,0,255));119 }120 else{121 ++curpx.x;122 res=-1;123 }124 return res;125 }126 127 //逐步的扫描128 vector< int > ScanImage( Mat &src , vector< dataBase > db , int window_width=12 ,int window_height=12 ){129 130 Point srcp;131 132 window_height = src.rows;133 vector< int > ans ; 134 while(srcp.x
src.cols)137 window_width = src.cols - srcp.x;138 Mat tmp = src( Rect(srcp.x,srcp.y,window_width,window_height) );139 140 //轮廓检测141 /* vector< vector
>reg;142 Mat newtmp = tmp.clone();143 findContours(newtmp, reg,CV_RETR_EXTERNAL , CV_CHAIN_APPROX_NONE);144 if( reg.empty() ) break;145 Rect rect = boundingRect(Mat(reg[0]));146 Mat ttmp = tmp(rect);147 imshow("ttmp",ttmp);148 waitKey(0);*/149 150 int ansvalue =StartMatch(tmp,db,srcp);151 if(ansvalue !=-1){152 ans.push_back( ansvalue);153 printf("%d ",ansvalue);154 }155 }156 puts("");157 return ans;158 }159 160 int main()161 {162 163 Mat check;164 vector< dataBase > dblist;165 int dex[20];//{0,1,2,3,4,5,6,7,8,9}; //建立一个索引166 for(int i=0;i<20 ; dex[i]=i++);167 loadProperty(dblist,dex,7,33,3); 168 169 for(int i=0;i<9;i++)170 {171 char path[30];172 173 if(i<9) sprintf(path,"D:/yzm/%d.jpg",i+1);174 else sprintf(path,"D:/yzm/%d.png",i-8);175 176 loadImage(check,check,String(path));177 imshow("check",check);178 waitKey(0);179 180 binImage(check,check,17,50,3);181 182 ScanImage(check,dblist,11,3);183 imshow("final",check);184 waitKey(0);185 }186 waitKey(0);187 return 0;188 }

          

                 

   

  

   可能是由于测试的图片太小了,导致二值化的时候,图片很不理想,只好取消轮廓检测,然后改为手动设置窗口大小,虽然比较原始,,但是对于比较清晰的图片多能较好的

识别出来!

    

                         

转载于:https://www.cnblogs.com/gongxijun/p/5152099.html

你可能感兴趣的文章
编译器DIY——词法分析
查看>>
20145203盖泽双《Java程序设计》第三周学习总结
查看>>
pm2 的使用
查看>>
WPF使用Canvas绘制可变矩形
查看>>
ansible-playbook的配置语法 参数
查看>>
基于folly的AtomicIntrusiveLinkedList无锁队列进行简单封装的多生产多消费模型
查看>>
django-给外键关系传值,删除外键关系
查看>>
Daily Scrum M2 11-13
查看>>
函数调用在回调,委托与事件在程序设计中的应用
查看>>
洛谷 2966 2966 [USACO09DEC]牛收费路径Cow Toll Paths
查看>>
tensorflow学习之路-----卷积神经网络个人总结
查看>>
多角色分库情况下shiro开发
查看>>
ios 文件下载 FTP下载
查看>>
一些英文面试题(Android)
查看>>
Unity3D ——强大的跨平台3D游戏开发工具(六)
查看>>
在centos6编译配置httpd2.4的N种方法
查看>>
STM32F4 External interrupts
查看>>
【题解】数颜色 STL vector数组
查看>>
传统项目转前端工程化——路由跳转时出现浏览器锁死和白屏【该死的同步ajax】...
查看>>
一次谷歌面试趣事
查看>>