浅谈OpenCV人脸检测.docx

上传人:b****8 文档编号:23646736 上传时间:2023-05-19 格式:DOCX 页数:24 大小:21.99KB
下载 相关 举报
浅谈OpenCV人脸检测.docx_第1页
第1页 / 共24页
浅谈OpenCV人脸检测.docx_第2页
第2页 / 共24页
浅谈OpenCV人脸检测.docx_第3页
第3页 / 共24页
浅谈OpenCV人脸检测.docx_第4页
第4页 / 共24页
浅谈OpenCV人脸检测.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

浅谈OpenCV人脸检测.docx

《浅谈OpenCV人脸检测.docx》由会员分享,可在线阅读,更多相关《浅谈OpenCV人脸检测.docx(24页珍藏版)》请在冰豆网上搜索。

浅谈OpenCV人脸检测.docx

浅谈OpenCV人脸检测

浅谈OpenCV人脸检测

OpenCV的人脸检测主要是调用训练好的cascade(Haar分类器)来进行模式匹配。

cvHaarDetectObjects,先将图像灰度化,根据传入参数判断是否进行canny边缘处理(默认不使用),再进行匹配。

匹配后收集找出的匹配块,过滤噪声,计算相邻个数如果超过了规定值(传入的min_neighbors)就当成输出结果,否则删去。

匹配循环:

将匹配分类器放大scale(传入值)倍,同时原图缩小scale倍,进行匹配,直到匹配分类器的大小大于原图,则返回匹配结果。

匹配的时候调用cvRunHaarClassifierCascade来进行匹配,将所有结果存入CvSeq*Seq (可动态增长元素序列),将结果传给cvHaarDetectObjects。

cvRunHaarClassifierCascade函数整体是根据传入的图像和cascade来进行匹配。

并且可以根据传入的cascade类型不同(树型、stump(不完整的树)或其他的),进行不同的匹配方式。

函数cvRunHaarClassifierCascade用于对单幅图片的检测。

在函数调用前首先利用cvSetImagesForHaarClassifierCascade设定积分图和合适的比例系数(=>窗口尺寸)。

当分析的矩形框全部通过级联分类器每一层的时返回正值(这是一个候选目标),否则返回0或负值。

为了了解OpenCV人脸检测中寻找匹配图像的详细过程,就把cvHaarDetectObjects和cvRunHaarClassifierCascade的源文件详细看了一遍,并打上了注释。

方便大家阅读。

附cvHaarDetectObjects代码:

CV_IMPLCvSeq*

cvHaarDetectObjects(constCvArr*_img, 

                    CvHaarClassifierCascade*cascade,

                    CvMemStorage*storage,doublescale_factor,

                    intmin_neighbors,intflags,CvSizemin_size)

{

   intsplit_stage=2;

 

  CvMatstub,*img=(CvMat*)_img;  //CvMat多通道矩阵 *img=_img指针代换传入图

   CvMat*temp=0,*sum=0,*tilted=0,*sqsum=0,*norm_img=0,*sumcanny=0,*img_small=0;

   CvSeq*seq=0;

   CvSeq*seq2=0;                //CvSeq可动态增长元素序列

   CvSeq*idx_seq=0;

   CvSeq*result_seq=0;

   CvMemStorage*temp_storage=0;

   CvAvgComp*comps=0;

   inti;

   #ifdef_OPENMP

   CvSeq*seq_thread[CV_MAX_THREADS]={0};

   intmax_threads=0;

#endif

   

   CV_FUNCNAME(“cvHaarDetectObjects”);

 

   __BEGIN__;

 

   doublefactor;

   intnpass=2,coi;                                                                                                                //npass=2

   intdo_canny_pruning=flags&CV_HAAR_DO_CANNY_PRUNING;                //true做canny边缘处理

 

   if(!

CV_IS_HAAR_CLASSIFIER(cascade))

       CV_ERROR(!

cascade?

CV_StsNullPtr:

CV_StsBadArg,“Invalidclassifiercascade”);

 

   if(!

storage)

       CV_ERROR(CV_StsNullPtr,“Nullstoragepointer”);

 

   CV_CALL(img=cvGetMat(img,&stub,&coi));

   if(coi)

       CV_ERROR(CV_BadCOI,“COIisnotsupported”); //一些出错代码

 

   if(CV_MAT_DEPTH(img->type)!

=CV_8U)

       CV_ERROR(CV_StsUnsupportedFormat,“Only8-bitimagesaresupported”);

 

   CV_CALL(temp=cvCreateMat(img->rows,img->cols,CV_8UC1));

   CV_CALL(sum=cvCreateMat(img->rows+1,img->cols+1,CV_32SC1));

   CV_CALL(sqsum=cvCreateMat(img->rows+1,img->cols+1,CV_64FC1));

   CV_CALL(temp_storage=cvCreateChildMemStorage(storage));

 

#ifdef_OPENMP

   max_threads=cvGetNumThreads();

   for(i=0;i

   {

       CvMemStorage*temp_storage_thread;

       CV_CALL(temp_storage_thread=cvCreateMemStorage(0));                //CV_CALL就是运行,假如出错就报错。

       CV_CALL(seq_thread[i]=cvCreateSeq(0,sizeof(CvSeq),               //CvSeq可动态增长元素序列

 

    sizeof(CvRect),temp_storage_thread));

   }

#endif

 

   if(!

cascade->hid_cascade)

       CV_CALL(icvCreateHidHaarClassifierCascade(cascade));

 

   if(cascade->hid_cascade->has_tilted_features)

       tilted=cvCreateMat(img->rows+1,img->cols+1,CV_32SC1);        //多通道矩阵图像长宽+14通道

 

   seq=cvCreateSeq(0,sizeof(CvSeq),sizeof(CvRect),temp_storage);       //创建序列seq 矩形

   seq2=cvCreateSeq(0,sizeof(CvSeq),sizeof(CvAvgComp),temp_storage);   //创建序列seq2 矩形和邻近

   result_seq=cvCreateSeq(0,sizeof(CvSeq),sizeof(CvAvgComp),storage);  //创建序列result_seq 矩形和邻近

 

   if(min_neighbors==0)

       seq=result_seq;

 

   if(CV_MAT_CN(img->type)>1)

   {

       cvCvtColor(img,temp,CV_BGR2GRAY);  //img转为灰度

       img=temp;                                                                                                                                

   }

   

   if(flags&CV_HAAR_SCALE_IMAGE)                                                                                        //flag&&匹配图

   {

       CvSizewin_size0=cascade->orig_window_size; //CvSizewin_size0为分类器的原始大小

       intuse_ipp=cascade->hid_cascade->ipp_stages!

=0&&              

      icvApplyHaarClassifier_32s32f_C1R_p!

=0; //IPP相关函数

 

       if(use_ipp)

           CV_CALL(norm_img=cvCreateMat(img->rows,img->cols,CV_32FC1));          //图像的矩阵化4通道.

       CV_CALL(img_small=cvCreateMat(img->rows+1,img->cols+1,CV_8UC1));      //小图矩阵化单通道长宽+1

 

for(factor=1;;factor*=scale_factor) //成scale_factor倍数匹配

       {

           intpositive=0;

           intx,y;

           CvSizewin_size={cvRound(win_size0.width*factor),

                               cvRound(win_size0.height*factor)};                      //winsize        分类器行列(扩大factor倍)        

           CvSizesz={cvRound(img->cols/factor),cvRound(img->rows/factor)};  //sz图像行列(缩小factor倍)三个Cvsize

           CvSizesz1={sz.width–win_size0.width,sz.height–win_size0.height};   //sz1图像减分类器行列

           CvRectrect1={icv_object_win_border,icv_object_win_border,

win_size0.width–icv_object_win_border*2,   //icv_object_win_border(int)初始值=1

win_size0.height–icv_object_win_border*2}; //矩形框rect1

     CvMatimg1,sum1,sqsum1,norm1,tilted1,mask1;     //多通道矩阵

           CvMat*_tilted=0;

 

           if(sz1.width<=0||sz1.height<=0)                                      //图片宽或高小于分类器–>跳出

               break;

           if(win_size.width继续

               continue;

//CV_8UC1见定义.

//#defineCV_MAKETYPE(depth,cn)((depth)+(((cn)-1)<

//深度+(cn-1)左移3位  depth,depth+8,depth+16,depth+24.

           img1=cvMat(sz.height,sz.width,CV_8UC1,img_small->data.ptr);           //小图的矩阵化img1单通道    

           sum1=cvMat(sz.height+1,sz.width+1,CV_32SC1,sum->data.ptr);            //长宽+14通道8位           多通道矩阵

           sqsum1=cvMat(sz.height+1,sz.width+1,CV_64FC1,sqsum->data.ptr);        //长宽+14通道16位

           if(tilted)

           {

               tilted1=cvMat(sz.height+1,sz.width+1,CV_32SC1,tilted->data.ptr);  //长宽+14通道8位

               _tilted=&tilted1;                                                                 //长宽+14通道8位

           }

           norm1=cvMat(sz1.height,sz1.width,CV_32FC1,norm_img?

norm_img->data.ptr:

0); //norm1图像减分类器行列4通道

           mask1=cvMat(sz1.height,sz1.width,CV_8UC1,temp->data.ptr);                     //mask1灰度图

            cvResize(img,&img1,CV_INTER_LINEAR);                //img双线性插值输出到img1

   cvIntegral(&img1,&sum1,&sqsum1,_tilted);    //计算积分图像

 

           if(use_ipp&&icvRectStdDev_32s32f_C1R_p(sum1.data.i,sum1.step,

               sqsum1.data.db,sqsum1.step,norm1.data.fl,norm1.step,sz1,rect1)<0)

               use_ipp=0;

 

           if(use_ipp)                                                                                //如果ipp=true  (intel视频处理加速等的函数库)

           {

               positive=mask1.cols*mask1.rows;                                                                                 //mask1长乘宽–>positive

               cvSet(&mask1,cvScalarAll(255));   //mask1赋值为255

               for(i=0;icount;i++)

               {

                   if(icvApplyHaarClassifier_32s32f_C1R_p(sum1.data.i,sum1.step,

                       norm1.data.fl,norm1.step,mask1.data.ptr,mask1.step,

                       sz1,&positive,cascade->hid_cascade->stage_classifier[i].threshold,

                       cascade->hid_cascade->ipp_stages[i])<0)

                   {

                       use_ipp=0;                 //ipp=false;

                       break;

                   }

                   if(positive<=0)

                       break;

               }

           }

           

           if(!

use_ipp)                                                                                        //如果ipp=false

           {

               cvSetImagesForHaarClassifierCascade(cascade,&sum1,&sqsum1,0,1.);

               for(y=0,positive=0;y

                   for(x=0;x

                   {

                       mask1.data.ptr[mask1.step*y+x]=

                           cvRunHaarClassifierCascade(cascade,cvPoint(x,y),0)>0;  //匹配图像.

                       positive+=mask1.data.ptr[mask1.step*y+x];

                   }

           }

 

           if(positive>0)

           {

               for(y=0;y

                   for(x=0;x

                       if(mask1.data.ptr[mask1.step*y+x]!

=0)

                       {

                           CvRectobj_rect={cvRound(y*factor),cvRound(x*factor),    

                                win_size.width,win_size.height};

                           cvSeqPush(seq,&obj_rect);  //将匹配块放到seq中

                       }

           }

       }

   }

   else                                                                                                        //!

(flag&&匹配图)

   {

       cvIntegral(img,sum,sqsum,tilted);

          if(do_canny_pruning)

       {

           sumcanny=cvCreateMat(img->rows+1,img->cols+1,CV_32SC1);                 //如果做canny边缘检测

           cvCanny(img,temp,0,50,3);

           cvIntegral(temp,sumcanny);

       }

   

       if((unsigned)split_stage>=(unsigned)cascade->count||

           cascade->hid_cascade->is_tree)                                                         {

           split_stage=cascade->count;

           npass=1;

       }

 

       for(factor=1;factor*cascade-

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1