高帧率扑克牌识别技术详解一(可用于车牌识别,字符识别,人脸检测,验证码识别等等成熟领域)

67 篇文章 6 订阅
27 篇文章 3 订阅
 

高帧率扑克牌识别技术详解一(可用于车牌识别,字符识别,人脸检测,验证码识别等等成熟领域)

分类: 扑克牌识别系统   283人阅读  评论(1)  收藏  举报

本文主要介绍目前主流的adaboost目标检测算法,和CNN卷积神经网络字符识别算法。以扑克牌识别技术为题介绍相关的开发流程和经验。

整个系统包括,

1、摄像头采集,这里以USB摄像头通过directShow采集为例进行介绍。一个线程做采集,一个线程做检测识别。

2、字符检测正负样本得取。后面会详细介绍怎么在只有视频的情况下,

(1)自己写个鼠标拉框手工割取样本的软件,采用OpenCV的鼠标相应控件很容易实现。

(2)或者通过灰度化,自适应二值化,ROI找轮廓,轮廓筛选,ROI轮廓分割,自动割取样本;

(3)以及通过pictureRelate进行重复高样本自动剔除等等筛选。

3、adaboost字符检测:

(1)用adaboost+haar特征训练第2步中得取的样本。

(2)进一步将测试分割出的误识别样本,进行筛选,重复2,3两步。直到获得满意的检测率。

4、识别样本得取

(1)字符识别样本读取,分为0-10,JQK,共14个类别。

(2)花色样本得取,共桃杏梅方四个类。

5、采用CNN组进行样本训练识别。这里为了提高识别率,采用两个CNN分别识别4.1和4.2,采用两个CNN并行思路提升识别速度。

(1)针对4.1的14各类,训练一个CNN分类器;

(2)针对4.2的4各类训练一个CNN分类器。


在介绍系统之前先对本文涉及的两大算法做简要的介绍:

1、adaboost算法实例介绍,这里不上理论,直接来实例对照着学boosting的思路。

http://www.sigvc.org/bbs/thread-727-1-1.html





2、CNN算法详细介绍。

http://www.cnblogs.com/tornadomeet/archive/2013/05/05/3061457.html




 

高帧率扑克牌识别技术详解三--字符检测的正负样本得取(利用鼠标画框抠图)

分类: 扑克牌识别系统   193人阅读  评论(0)  收藏  举报

第二部分主要讲解做目标检测时候,怎么得取正负样本以及如何对正负样本进行筛选。


(1)自己写个鼠标拉框手工割取样本的软件,采用OpenCV的鼠标相应控件很容易实现。

         前面已经通过directShow实现了视频采集和保存了,下面将用OpenCV实现一个手动拉框,自动保存ROI区域的工具来获取样本。

OpenCV里面采用setMouseCallback(window_name,mouse_function,&mouse); 来回调mouse_function,其中mouse_function里面通过CV_EVENT_LBUTTONDOWN等事件判断相应不同的操作。比如以下代码,可以在窗口画框,这时候你只要将框CvRect坐标保存,就可以实现cvSetImageROI截取区域咯:

  1. #include <cv.h>  
  2. #include <highgui.h>  
  3.    
  4. // Define our callback which we will install for  
  5. // mouse events.  
  6. //  
  7. void my_mouse_callback(  
  8.    int event, int x, int y, int flags, void* param   
  9. );  
  10.    
  11. CvRect box;  
  12. bool drawing_box = false;  
  13.    
  14. // A litte subroutine to draw a box onto an image  
  15. //  
  16. void draw_box( IplImage* img, CvRect rect ) {  
  17.   cvRectangle (  
  18.     img,   
  19.     cvPoint(box.x,box.y),  
  20.     cvPoint(box.x+box.width,box.y+box.height),  
  21.     cvScalar(0xff,0x00,0x00)    /* red */  
  22.   );  
  23. }  
  24.    
  25. int main( int argc, char* argv[] ) {  
  26.     
  27.   box = cvRect(-1,-1,0,0);  
  28.   
  29.   IplImage* image = cvCreateImage(   
  30.     cvSize(200,200),  
  31.     IPL_DEPTH_8U,  
  32.     3  
  33.   );  
  34.   cvZero( image );  
  35.   IplImage* temp = cvCloneImage( image );  
  36.     
  37.   cvNamedWindow( "Box Example" );  
  38.    
  39.   // Here is the crucial moment that we actually install  
  40.   // the callback.  Note that we set the value ‘param’ to  
  41.   // be the image we are working with so that the callback  
  42.   // will have the image to edit.  
  43.   //  
  44.   cvSetMouseCallback(   
  45.     "Box Example",   
  46.     my_mouse_callback,   
  47.     (void*) image   
  48.   );  
  49.    
  50.   // The main program loop.  Here we copy the working image  
  51.   // to the ‘temp’ image, and if the user is drawing, then  
  52.   // put the currently contemplated box onto that temp image.  
  53.   // display the temp image, and wait 15ms for a keystroke,  
  54.   // then repeat…  
  55.   //  
  56.   while( 1 ) {  
  57.    
  58.     cvCopyImage( image, temp );  
  59.     if( drawing_box ) draw_box( temp, box );   
  60.     cvShowImage( "Box Example", temp );  
  61.    
  62.     if( cvWaitKey( 15 )==27 ) break;  
  63.   }  
  64.    
  65.   // Be tidy  
  66.   //  
  67.   cvReleaseImage( &image );  
  68.   cvReleaseImage( &temp );  
  69.   cvDestroyWindow( "Box Example" );  
  70. }  
  71.    
  72. // This is our mouse callback.  If the user  
  73. // presses the left button, we start a box.  
  74. // when the user releases that button, then we  
  75. // add the box to the current image.  When the  
  76. // mouse is dragged (with the button down) we   
  77. // resize the box.  
  78. //  
  79. void my_mouse_callback(  
  80.    int event, int x, int y, int flags, void* param )  
  81. {  
  82.    
  83.   IplImage* image = (IplImage*) param;  
  84.   
  85.   switch( event ) {  
  86.     case CV_EVENT_MOUSEMOVE: {  
  87.       if( drawing_box ) {  
  88.         box.width  = x-box.x;  
  89.         box.height = y-box.y;  
  90.       }  
  91.     }  
  92.     break;  
  93.     case CV_EVENT_LBUTTONDOWN: {  
  94.       drawing_box = true;  
  95.       box = cvRect( x, y, 0, 0 );  
  96.     }  
  97.     break;     
  98.     case CV_EVENT_LBUTTONUP: {  
  99.       drawing_box = false;   
  100.       if( box.width<0  ) {   
  101.         box.x+=box.width;    
  102.         box.width *=-1;   
  103.       }  
  104.       if( box.height<0 ) {   
  105.         box.y+=box.height;   
  106.         box.height*=-1;   
  107.       }  
  108.       draw_box( image, box );  
  109.     }  
  110.     break;     
  111.   }  
  112. }  



(2)或者通过灰度化,自适应二值化,ROI找轮廓,轮廓筛选,ROI轮廓分割,自动割取样本;


(3)以及通过pictureRelate进行重复高样本自动剔除等等筛选。


高帧率扑克牌识别技术详解五--采用LBP+HOG SVM做目标分类,车牌检测,字符检测等

分类: 扑克牌识别系统   164人阅读  评论(0)  收藏  举报

       在样本数量比较少的情况下,可以采用HOG、SVM对样本进行初步的筛选出,正负样本,本文接着上一节二值化出来部分样本后,用pictureRelate做初步筛选出正负样本各500,准确训练。


1、pictureRelate使用http://www.walthelm.net/picture-relate/

   可以用来比较图片的相似程度,或找出类似的图片文件的图像处理工具。在同一个视窗里浏览不同文件夹和硬盘驱动器中的图片文件#支持查看,改名,删除,剪贴,拖动,切换至文件管理器等操作#可处理多达50000多张图片!支持JPG, BMP, PNG, TIFF, PPM, PGM, PBM, RAS等格式#可以通过导入过滤命令行读取任何其它格式。



      这里HOG LBP特征可以采用VLfeat(http://www.vlfeat.org/这个开源库里面的特征,或者用OpenCV里面的也可以,分类器SVM采用的是OpenCV里面的。

2、下面介绍下VLfeat里面的HOG特征


左图是原图,右图是HOG变化后的可视化效果。可以仔细对比,房子的轮廓还是可见的。


3、HOG+SVM训练目标检测的流程(OpenCV自带):

http://blog.csdn.net/carson2005/article/details/7841443

(1)准备训练样本集合;包括正样本集和负样本集;

(2)收集到足够的训练样本之后,你需要手动裁剪样本。例如,你想用Hog+SVM来对商业步行街的监控画面中进行行人检测,那么,你就应该用收集到的训练样本集合,手动裁剪画面中的行人(可以写个简单程序,只需要鼠标框选一下,就将框选区域保存下来--这一步在上一节有介绍)。

(3)裁剪得到训练样本之后,将所有正样本放在一个文件夹中;将所有负样本放在另一个文件夹中;并将所有训练样本缩放到同样的尺寸大小。本文是采用90*24的区域训练的。

(4)提取所有正样本的Hog特征;

(5)提取所有负样本的Hog特征;

(6)对所有正负样本赋予样本标签;例如,所有正样本标记为1,所有负样本标记为0

(7)将正负样本的Hog特征,正负样本的标签,都输入到SVM中进行训练;Dalal在论文中考虑到速度问题,建议采用线性SVM进行训练。这里,不妨也采用线性SVM

(8)SVM训练之后,将结果保存为文本文件。

(9)线性SVM进行训练之后得到的文本文件里面,有一个数组,叫做support vector,还有一个数组,叫做alpha,有一个浮点数,叫做rho;alpha矩阵同support vector相乘,注意,alpha*supportVector,将得到一个列向量。之后,再该列向量的最后添加一个元素rho。如此,变得到了一个分类器,利用该分类器,直接替换opencv中行人检测默认的那个分类器(cv::HOGDescriptor::setSVMDetector()),就可以利用你的训练样本训练出来的分类器进行检测了。


效果显示:



  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值