织梦CMS - 轻松建站从此开始!

罗索

训练自己的haar-like特征分类器并识别物体(3)

落鹤生 发布于 2015-04-12 13:31 点击:次 
本文将着重说明最后一个阶段——目标识别,也即利用前面训练出来的分类器文件(.xml文件)对图片中的物体进行识别,并在图中框出在该物体。由于逻辑比较简单,这里直接上代码
TAG: 分类器  haar  

在前两篇文章中,我介绍了《训练自己的haar-like特征分类器并识别物体》的前三个步骤:

1.准备训练样本图片,包括正例及反例样本

2.生成样本描述文件

3.训练样本

4.目标识别

==============

本文将着重说明最后一个阶段——目标识别,也即利用前面训练出来的分类器文件(.xml文件)对图片中的物体进行识别,并在图中框出在该物体。由于逻辑比较简单,这里直接上代码:

  1. int _tmain(int argc, _TCHAR* argv[]) 
  2.     char *cascade_name = CASCADE_HEAD_MY; //上文最终生成的xml文件命名为"CASCADE_HEAD_MY.xml" 
  3.     cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); //加载xml文件 
  4.   
  5.     if( !cascade ) 
  6.     { 
  7.         fprintf( stderr, "ERROR: Could not load classifier cascade\n" ); 
  8.         system("pause"); 
  9.         return -1; 
  10.     } 
  11.     storage = cvCreateMemStorage(0); 
  12.     cvNamedWindow( "face", 1 ); 
  13.   
  14.     const char* filename = "(12).bmp"
  15.     IplImage* image = cvLoadImage( filename, 1 ); 
  16.   
  17.     if( image ) 
  18.     { 
  19.         detect_and_draw( image ); //函数见下方 
  20.         cvWaitKey(0); 
  21.         cvReleaseImage( &image );   
  22.     } 
  23.     cvDestroyWindow("result"); 
  24.     return 0; 

实际检测的实现代码:

  1. void detect_and_draw(IplImage* img )  
  2. {  
  3.     double scale=1.2;  
  4.     static CvScalar colors[] = {  
  5.         {{0,0,255}},{{0,128,255}},{{0,255,255}},{{0,255,0}},  
  6.         {{255,128,0}},{{255,255,0}},{{255,0,0}},{{255,0,255}}  
  7.     };//Just some pretty colors to draw with 
  8.  
  9.     //Image Preparation  
  10.     //  
  11.     IplImage* gray = cvCreateImage(cvSize(img->width,img->height),8,1);  
  12.     IplImage* small_img=cvCreateImage(cvSize(cvRound(img->width/scale)
  13. ,cvRound(img->height/scale)),8,1);  
  14.     cvCvtColor(img,gray, CV_BGR2GRAY);  
  15.     cvResize(gray, small_img, CV_INTER_LINEAR); 
  16.  
  17.     cvEqualizeHist(small_img,small_img); //直方图均衡 
  18.  
  19.     //Detect objects if any  
  20.     //  
  21.     cvClearMemStorage(storage);  
  22.     double t = (double)cvGetTickCount();  
  23.     CvSeq* objects = cvHaarDetectObjects(small_img,  
  24.         cascade,  
  25.         storage,  
  26.         1.1,  
  27.         2,  
  28.         0/*CV_HAAR_DO_CANNY_PRUNING*/,  
  29.         cvSize(30,30)); 
  30.  
  31.     t = (double)cvGetTickCount() - t;  
  32.     printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) ); 
  33.  
  34.     //Loop through found objects and draw boxes around them  
  35.     for(int i=0;i<(objects? objects->total:0);++i)  
  36.     {  
  37.         CvRect* r=(CvRect*)cvGetSeqElem(objects,i);  
  38.         cvRectangle(img, cvPoint(r->x*scale,r->y*scale)
  39. , cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8]);  
  40.     }  
  41.     forint i = 0; i < (objects? objects->total : 0); i++ )  
  42.     {  
  43.         CvRect* r = (CvRect*)cvGetSeqElem( objects, i );  
  44.         CvPoint center;  
  45.         int radius;  
  46.         center.x = cvRound((r->x + r->width*0.5)*scale);  
  47.         center.y = cvRound((r->y + r->height*0.5)*scale);  
  48.         radius = cvRound((r->width + r->height)*0.25*scale);  
  49.         cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );  
  50.     } 
  51.  
  52.     cvShowImage( "result", img );  
  53.     cvReleaseImage(&gray);  
  54.     cvReleaseImage(&small_img);  

===================================

其实上面的代码可以运用于大部分模式识别问题,无论是自己生成的xml文件还是opencv自带的xml文件。在opencv的工程目录opencv\data文件夹下有大量的xml文件,这些都是opencv开源项目中的程序员们自己训练出来的。然而,效果一般不会合你预期,所以才有了本系列文章。天下没有免费的午餐,想要获得更高的查准率与查全率,不付出点努力是不行的!

(wengzilin)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201504/17274.html]
本文出处:博客园 作者:wengzilin 原文
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容