基於OpenCV讀取攝像頭進行人臉檢測和人臉識別


前段時間使用 OpenCV的庫函數實現了人臉檢測和人臉識別,筆者的實驗環境為VS2010+OpenCV2.4.4, opencv的環境配置網上有很多,不再贅述。檢測的代碼網上很多,記不清楚從哪兒copy的了,識別的代碼是從OpenCV官網上找到的:http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_api.html

需要注意的是,opencv的FaceRecogizer目前有三個類實現了它,特征臉和fisherface方法最少訓練圖像為兩張,而LBP可以單張圖像訓練。本人的實驗采用的圖片是100x100大小的,所以如果要添加自己的圖像進行識別的話務必調整為100x100,不然會報錯。當然在recog_and_draw這個函數里,筆者也將每次檢測到的人臉進行了保存,拖出來重命名就可以,路徑自己找吧。使用不同的方法識別時,其閾值設置也不同,LBP大概在100,其他兩種方法大概在1000。本人的代碼已共享,下載鏈接:http://download.csdn.net/detail/u010944555/6749725

ps:有人說代碼的檢測率不高,其實可以歸結為兩方面的原因,第一人臉檢測率不高,這個可以通過嵌套檢測嘴角、眼睛等來降低,或者背景、光照固定的話可以通過圖像差分來解決;第二是識別方法本身的問題,如果想提高識別率,可以添加多張不同姿態、光照下的人臉作為訓練的樣本,如果有時間的話可以在采集圖像時給出一個人臉框,引導用戶對齊人臉進行采集,三星手機解除鎖屏就有這么一個功能。

效果圖:

廢話不多說,上傳代碼。

main:

 

[cpp]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
 
  1. #include "stdafx.h"  
  2. #include "cv.h"  
  3. #include "highgui.h"  
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <string.h>  
  7. #include <assert.h>  
  8. #include <math.h>  
  9. #include <float.h>  
  10. #include <limits.h>  
  11. #include <time.h>  
  12. #include <ctype.h>  
  13. #include <opencv2\contrib\contrib.hpp>    
  14. #include <opencv2\core\core.hpp>    
  15. #include <opencv2\highgui\highgui.hpp>   
  16. #include <iostream>  
  17. #include <fstream>  
  18. #include <sstream>  
  19. #include "detect_recog.h"  
  20.   
  21. using namespace std;  
  22. using namespace cv;  
  23. #ifdef _EiC  
  24. #define WIN32  
  25. #endif  
  26.   
  27. CvMemStorage* storage = 0;  
  28. CvHaarClassifierCascade* cascade = 0;  
  29. CvHaarClassifierCascade* nested_cascade = 0;  
  30. int use_nested_cascade = 0;  
  31. const char* cascade_name =  
  32.     "./data/haarcascade_frontalface_alt.xml";//別人已經訓練好的人臉檢測xml數據  
  33. const char* nested_cascade_name =  
  34.     "./data/haarcascade_eye_tree_eyeglasses.xml";  
  35. CvCapture* capture = 0;  
  36. IplImage *frame, *frame_copy = 0;  
  37. IplImage *image = 0;  
  38. const char* scale_opt = "--scale="; // 分類器選項指示符號   
  39. int scale_opt_len = (int)strlen(scale_opt);  
  40. const char* cascade_opt = "--cascade=";  
  41. int cascade_opt_len = (int)strlen(cascade_opt);  
  42. const char* nested_cascade_opt = "--nested-cascade";  
  43. int nested_cascade_opt_len = (int)strlen(nested_cascade_opt);  
  44. double scale = 1;  
  45. int num_components = 9;  
  46. double facethreshold = 9.0;  
  47. //opencv的FaceRecogizer目前有三個類實現了他,特征臉和fisherface方法最少訓練圖像為兩張,而LBP可以單張圖像訓練  
  48. //cv::Ptr<cv::FaceRecognizer> model = cv::createEigenFaceRecognizer();  
  49. //cv::Ptr<cv::FaceRecognizer> model = cv::createFisherFaceRecognizer();  
  50. cv::Ptr<cv::FaceRecognizer> model = cv::createLBPHFaceRecognizer();//LBP的這個方法在單個人臉驗證方面效果最好  
  51.   
  52. vector<Mat> images;//兩個容器images,labels來存放圖像數據和對應的標簽  
  53. vector<int> labels;  
  54.   
  55.   
  56. int main( int argc, char** argv )  
  57. {  
  58.     cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0); //加載分類器   
  59.     if(!cascade)   
  60.     {  
  61.         fprintf( stderr, "ERROR: Could not load classifier cascade\n" );  
  62.         getchar();  
  63.         return -1;  
  64.     }  
  65.     model->set("threshold", 2100.0);  
  66.     string output_folder;  
  67.     output_folder = string("./einfacedata");  
  68.   
  69.     //讀取你的CSV文件路徑  
  70.     string fn_csv = string("./einfacedata/at.txt");  
  71.     try  
  72.     {  
  73.         //通過./einfacedata/at.txt這個文件讀取里面的訓練圖像和類別標簽  
  74.         read_csv(fn_csv, images, labels);     
  75.     }  
  76.     catch(cv::Exception &e)  
  77.     {  
  78.         cerr<<"Error opening file "<<fn_csv<<". Reason: "<<e.msg<<endl;  
  79.         exit(1);  
  80.     }  
  81.     /* 
  82.     //read_img這個函數直接從einfacedata/trainingdata目錄下讀取圖像數據並默認將圖像置為0 
  83.     //所以如果用這個函數只能用來單個人臉驗證 
  84.     if(!read_img(images, labels)) 
  85.     { 
  86.         cout<< "Error in reading images!"; 
  87.         images.clear(); 
  88.         labels.clear(); 
  89.         return 0; 
  90.     } 
  91.     */  
  92.     cout << images.size() << ":" << labels.size()<<endl;  
  93.     //如果沒有讀到足夠的圖片,就退出  
  94.     if(images.size() <= 2)  
  95.     {  
  96.         string error_message = "This demo needs at least 2 images to work.";  
  97.         CV_Error(CV_StsError, error_message);  
  98.     }  
  99.   
  100.     //得到第一張照片的高度,在下面對圖像變形到他們原始大小時需要  
  101.     //int height = images[0].rows;  
  102.     //移除最后一張圖片,用於做測試  
  103.     //Mat testSample = images[images.size() - 1];  
  104.     //cv::imshow("testSample", testSample);  
  105.     //int testLabel = labels[labels.size() - 1];  
  106.     //images.pop_back();  
  107.     //labels.pop_back();  
  108.   
  109.     //下面創建一個特征臉模型用於人臉識別,  
  110.     // 通過CSV文件讀取的圖像和標簽訓練它。  
  111.   
  112.     //進行訓練  
  113.     model->train(images, labels);  
  114.   
  115.     storage = cvCreateMemStorage(0); // 創建內存存儲器     
  116.     capture = cvCaptureFromCAM(0); // 創建視頻讀取結構   
  117.     cvNamedWindow( "result", 1 );  
  118.     if( capture ) // 如過是視頻或攝像頭采集圖像,則循環處理每一幀   
  119.     {  
  120.         for(;;)  
  121.         {  
  122.             if( !cvGrabFrame( capture ))  
  123.                 break;  
  124.             frame = cvRetrieveFrame( capture );  
  125.             if( !frame )  
  126.                 break;  
  127.             if( !frame_copy )  
  128.                 frame_copy = cvCreateImage( cvSize(640,480),IPL_DEPTH_8U, frame->nChannels );  
  129.             if( frame->origin == IPL_ORIGIN_TL )  
  130.                 cvCopy( frame, frame_copy, 0 );  
  131.             else  
  132.                 cvFlip( frame, frame_copy, 0 );  
  133.               
  134.             //detect_and_draw( frame_copy ); // 如果調用這個函數,只是實現人臉檢測  
  135.             //cout << frame_copy->width << "x" << frame_copy->height << endl;  
  136.             recog_and_draw( frame_copy );//該函數實現人臉檢測和識別  
  137.             if( cvWaitKey( 100 ) >= 0 )//esc鍵值好像是100  
  138.                 goto _cleanup_;  
  139.         }  
  140.         cvWaitKey(0);  
  141.         _cleanup_: // 標記使用,在匯編里用過,C語言,我還沒見用過   
  142.         cvReleaseImage( &frame_copy );  
  143.         cvReleaseCapture( &capture );  
  144.     }      
  145.     cvDestroyWindow("result");  
  146.     return 0;  
  147. }  

 

detect_recog.cpp:

 

[cpp]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
 
  1. #include "stdafx.h"  
  2. #include "cv.h"  
  3. #include "highgui.h"  
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <string.h>  
  7. #include <assert.h>  
  8. #include <math.h>  
  9. #include <float.h>  
  10. #include <limits.h>  
  11. #include <time.h>  
  12. #include <ctype.h>  
  13. #include "detect_recog.h"  
  14. #include <opencv2\contrib\contrib.hpp>    
  15. #include <opencv2\core\core.hpp>    
  16. #include <opencv2\highgui\highgui.hpp>   
  17. #include <iostream>  
  18. #include <fstream>  
  19. #include <sstream>  
  20. #include <stdio.h>  
  21. #include <io.h>    
  22. #include <direct.h>   
  23.   
  24. using namespace std;  
  25. using namespace cv;  
  26.   
  27. //檢測並圈出人臉,並將檢測到的人臉進行判斷屬於訓練圖像中的哪一類  
  28. void recog_and_draw( IplImage* img )   
  29. {  
  30.     static CvScalar colors[] =   
  31.     {  
  32.         {{0,0,255}},  
  33.         {{0,128,255}},  
  34.         {{0,255,255}},  
  35.         {{0,255,0}},  
  36.         {{255,128,0}},  
  37.         {{255,255,0}},  
  38.         {{255,0,0}},  
  39.         {{255,0,255}}  
  40.     };  
  41.     IplImage *gray, *small_img;  
  42.     int i, j;  
  43.     gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );  
  44.     small_img = cvCreateImage( cvSize( cvRound (img->width/scale),  
  45.                          cvRound (img->height/scale)), 8, 1 );  
  46.     cvCvtColor( img, gray, CV_BGR2GRAY ); // 彩色RGB圖像轉為灰度圖像   
  47.     cvResize( gray, small_img, CV_INTER_LINEAR );  
  48.     cvEqualizeHist( small_img, small_img ); // 直方圖均衡化   
  49.     cvClearMemStorage( storage );  
  50.     if( cascade )  
  51.     {  
  52.         double t = (double)cvGetTickCount();   
  53.         CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,  
  54.                                             1.1, 2, 0  
  55.                                             //|CV_HAAR_FIND_BIGGEST_OBJECT  
  56.                                             //|CV_HAAR_DO_ROUGH_SEARCH  
  57.                                             |CV_HAAR_DO_CANNY_PRUNING  
  58.                                             //|CV_HAAR_SCALE_IMAGE  
  59.                                             ,  
  60.                                             cvSize(30, 30) );  
  61.         t = (double)cvGetTickCount() - t; // 統計檢測使用時間   
  62.         //printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );  
  63.         for( i = 0; i < (faces ? faces->total : 0); i++ )  
  64.         {  
  65.             CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); // 將faces數據從CvSeq轉為CvRect   
  66.             CvMat small_img_roi;  
  67.             CvSeq* nested_objects;  
  68.             CvPoint center;  
  69.             CvScalar color = colors[i%8]; // 使用不同顏色繪制各個face,共八種色   
  70.             int radius;  
  71.             center.x = cvRound((r->x + r->width*0.5)*scale); // 找出faces中心   
  72.             center.y = cvRound((r->y + r->height*0.5)*scale);  
  73.             radius = cvRound((r->width + r->height)*0.25*scale);   
  74.                   
  75.             cvGetSubRect( small_img, &small_img_roi, *r );  
  76.               
  77.             //截取檢測到的人臉區域作為識別的圖像  
  78.             IplImage *result;  
  79.             CvRect roi;  
  80.             roi = *r;  
  81.             result = cvCreateImage( cvSize(r->width, r->height), img->depth, img->nChannels );  
  82.             cvSetImageROI(img,roi);  
  83.             // 創建子圖像  
  84.             cvCopy(img,result);  
  85.             cvResetImageROI(img);  
  86.               
  87.             IplImage *resizeRes;  
  88.             CvSize dst_cvsize;  
  89.             dst_cvsize.width=(int)(100);  
  90.             dst_cvsize.height=(int)(100);  
  91.             resizeRes=cvCreateImage(dst_cvsize,result->depth,result->nChannels);  
  92.             //檢測到的區域可能不是100x100大小,所以需要插值處理到統一大小,圖像的大小可以自己指定的  
  93.             cvResize(result,resizeRes,CV_INTER_NN);  
  94.             IplImage* img1 = cvCreateImage(cvGetSize(resizeRes), IPL_DEPTH_8U, 1);//創建目標圖像    
  95.             cvCvtColor(resizeRes,img1,CV_BGR2GRAY);//cvCvtColor(src,des,CV_BGR2GRAY)  
  96.             cvShowImage( "resize", resizeRes );  
  97.             cvCircle( img, center, radius, color, 3, 8, 0 ); // 從中心位置畫圓,圈出臉部區域  
  98.             int predictedLabel = -1;  
  99.             Mat test = img1;  
  100.             //images[images.size() - 1] = test;  
  101.             model->train(images, labels);  
  102.               
  103.             //如果調用read_img函數時 chdir將默認目錄做了更改,所以output.jpg自己找一下吧  
  104.             imwrite("../ouput.jpg",test);  
  105.   
  106.             //在這里對人臉進行判別  
  107.             double predicted_confidence = 0.0;  
  108.             model->predict(test,predictedLabel,predicted_confidence);  
  109.             if(predictedLabel == 0)  
  110.                 cvText(img, "yes", r->x+r->width*0.5, r->y);   
  111.             else  
  112.                 cvText(img, "no", r->x+r->width*0.5, r->y);   
  113.             //cout << "predict:"<<model->predict(test) << endl;  
  114.             cout << "predict:"<< predictedLabel << "\nconfidence:" << predicted_confidence << endl;  
  115.   
  116.             if( !nested_cascade )  
  117.                 continue;  
  118.               
  119.             nested_objects = cvHaarDetectObjects( &small_img_roi, nested_cascade, storage,  
  120.                                         1.1, 2, 0  
  121.                                         //|CV_HAAR_FIND_BIGGEST_OBJECT  
  122.                                         //|CV_HAAR_DO_ROUGH_SEARCH  
  123.                                         //|CV_HAAR_DO_CANNY_PRUNING  
  124.                                         //|CV_HAAR_SCALE_IMAGE  
  125.                                         ,  
  126.                                         cvSize(0, 0) );  
  127.             for( j = 0; j < (nested_objects ? nested_objects->total : 0); j++ )  
  128.             {  
  129.                 CvRect* nr = (CvRect*)cvGetSeqElem( nested_objects, j );  
  130.                 center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);  
  131.                 center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);  
  132.                 radius = cvRound((nr->width + nr->height)*0.25*scale);  
  133.                 cvCircle( img, center, radius, color, 3, 8, 0 );  
  134.             }  
  135.         }  
  136.     }  
  137.     cvShowImage( "result", img );  
  138.     cvReleaseImage( &gray );  
  139.     cvReleaseImage( &small_img );  
  140. }  
  141. void cvText(IplImage* img, const char* text, int x, int y)    
  142. {    
  143.     CvFont font;    
  144.     double hscale = 1.0;    
  145.     double vscale = 1.0;    
  146.     int linewidth = 2;    
  147.     cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX | CV_FONT_ITALIC,hscale,vscale,0,linewidth);    
  148.     CvScalar textColor =cvScalar(0,255,255);    
  149.     CvPoint textPos =cvPoint(x, y);    
  150.     cvPutText(img, text, textPos, &font,textColor);    
  151. }  
  152.   
  153. Mat norm_0_255(cv::InputArray _src)  
  154. {  
  155.     Mat src = _src.getMat();  
  156.     Mat dst;  
  157.   
  158.     switch(src.channels())  
  159.     {  
  160.     case 1:  
  161.         cv::normalize(_src, dst, 0, 255, cv::NORM_MINMAX, CV_8UC1);  
  162.         break;  
  163.     case 3:  
  164.         cv::normalize(_src, dst, 0, 255, cv::NORM_MINMAX, CV_8UC3);  
  165.         break;  
  166.     default:  
  167.         src.copyTo(dst);  
  168.         break;  
  169.     }  
  170.   
  171.     return dst;  
  172. }  
  173. //讀取文件中的圖像數據和類別,存入images和labels這兩個容器  
  174. void read_csv(const string &filename, vector<Mat> &images, vector<int> &labels, char separator)  
  175. {  
  176.     std::ifstream file(filename.c_str(), ifstream::in);  
  177.     if(!file)  
  178.     {  
  179.         string error_message = "No valid input file was given.";  
  180.         CV_Error(CV_StsBadArg, error_message);  
  181.     }  
  182.   
  183.     string line, path, classlabel;  
  184.     while(getline(file, line))  
  185.     {  
  186.         stringstream liness(line);  
  187.         getline(liness, path, separator);  //遇到分號就結束  
  188.         getline(liness, classlabel);     //繼續從分號后面開始,遇到換行結束  
  189.         if(!path.empty() && !classlabel.empty())  
  190.         {  
  191.             images.push_back(imread(path, 0));  
  192.             labels.push_back(atoi(classlabel.c_str()));  
  193.         }  
  194.     }  
  195. }  
  196. bool read_img(vector<Mat> &images, vector<int> &labels)  
  197. {  
  198.       
  199.     long file;    
  200.     struct _finddata_t find;    
  201.     
  202.     _chdir("./einfacedata/trainingdata/");    
  203.     if((file=_findfirst("*.*", &find))==-1L) {    
  204.         //printf("空白!/n");    
  205.         return false;    
  206.     }    
  207.     //fileNum = 0;    
  208.     //strcpy(fileName[fileNum], find.name);  
  209.     int i = 0;  
  210.     while(_findnext(file, &find)==0)    
  211.     {    
  212.         if(i == 0)  
  213.         {  
  214.             i++;  
  215.             continue;  
  216.         }  
  217.         images.push_back(imread(find.name, 0));  
  218.         labels.push_back(0);    
  219.         cout << find.name << endl;  
  220.     }    
  221.     _findclose(file);  
  222.     return true;  
  223. }  
  224. // 只是檢測人臉,並將人臉圈出   
  225. void detect_and_draw( IplImage* img )   
  226. {  
  227.     static CvScalar colors[] =   
  228.     {  
  229.         {{0,0,255}},  
  230.         {{0,128,255}},  
  231.         {{0,255,255}},  
  232.         {{0,255,0}},  
  233.         {{255,128,0}},  
  234.         {{255,255,0}},  
  235.         {{255,0,0}},  
  236.         {{255,0,255}}  
  237.     };  
  238.     IplImage *gray, *small_img;  
  239.     int i, j;  
  240.     gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );  
  241.     small_img = cvCreateImage( cvSize( cvRound (img->width/scale),  
  242.                          cvRound (img->height/scale)), 8, 1 );  
  243.     cvCvtColor( img, gray, CV_BGR2GRAY ); // 彩色RGB圖像轉為灰度圖像   
  244.     cvResize( gray, small_img, CV_INTER_LINEAR );  
  245.     cvEqualizeHist( small_img, small_img ); // 直方圖均衡化   
  246.     cvClearMemStorage( storage );  
  247.     if( cascade )  
  248.     {  
  249.         double t = (double)cvGetTickCount();   
  250.         CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,  
  251.                                             1.1, 2, 0  
  252.                                             //|CV_HAAR_FIND_BIGGEST_OBJECT  
  253.                                             //|CV_HAAR_DO_ROUGH_SEARCH  
  254.                                             |CV_HAAR_DO_CANNY_PRUNING  
  255.                                             //|CV_HAAR_SCALE_IMAGE  
  256.                                             ,  
  257.                                             cvSize(30, 30) );  
  258.         t = (double)cvGetTickCount() - t; // 統計檢測使用時間   
  259.         printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );  
  260.         for( i = 0; i < (faces ? faces->total : 0); i++ )  
  261.         {  
  262.             CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); // 將faces數據從CvSeq轉為CvRect   
  263.             CvMat small_img_roi;  
  264.             CvSeq* nested_objects;  
  265.             CvPoint center;  
  266.             CvScalar color = colors[i%8]; // 使用不同顏色繪制各個face,共八種色   
  267.             int radius;  
  268.             center.x = cvRound((r->x + r->width*0.5)*scale); // 找出faces中心   
  269.             center.y = cvRound((r->y + r->height*0.5)*scale);  
  270.             radius = cvRound((r->width + r->height)*0.25*scale);   
  271.             cvCircle( img, center, radius, color, 3, 8, 0 ); // 從中心位置畫圓,圈出臉部區域   
  272.             if( !nested_cascade )  
  273.                 continue;  
  274.             cvGetSubRect( small_img, &small_img_roi, *r );  
  275.             nested_objects = cvHaarDetectObjects( &small_img_roi, nested_cascade, storage,  
  276.                                         1.1, 2, 0  
  277.                                         //|CV_HAAR_FIND_BIGGEST_OBJECT  
  278.                                         //|CV_HAAR_DO_ROUGH_SEARCH  
  279.                                         //|CV_HAAR_DO_CANNY_PRUNING  
  280.                                         //|CV_HAAR_SCALE_IMAGE  
  281.                                         ,cvSize(0, 0) );  
  282.             for( j = 0; j < (nested_objects ? nested_objects->total : 0); j++ )  
  283.             {  
  284.                 CvRect* nr = (CvRect*)cvGetSeqElem( nested_objects, j );  
  285.                 center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);  
  286.                 center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);  
  287.                 radius = cvRound((nr->width + nr->height)*0.25*scale);  
  288.                 cvCircle( img, center, radius, color, 3, 8, 0 );  
  289.             }  
  290.         }  
  291.     }  
  292.     cvShowImage( "result", img );  
  293.     cvReleaseImage( &gray );  
  294.     cvReleaseImage( &small_img );  
  295. }  

 

detect_recog.h:

 

[cpp]  view plain copy 在CODE上查看代碼片 派生到我的代碼片
 
 
  1. #include "stdafx.h"  
  2. #include "cv.h"  
  3. #include "highgui.h"  
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <string.h>  
  7. #include <assert.h>  
  8. #include <math.h>  
  9. #include <float.h>  
  10. #include <limits.h>  
  11. #include <time.h>  
  12. #include <ctype.h>  
  13. //////////////////////////////////s///////////////////////////////////  
  14. #include <opencv2\contrib\contrib.hpp>    
  15. #include <opencv2\core\core.hpp>    
  16. #include <opencv2\highgui\highgui.hpp>   
  17. #include <iostream>  
  18. #include <fstream>  
  19. #include <sstream>  
  20. using namespace std;  
  21. using namespace cv;  
  22.   
  23. #ifndef DETECT_RECOG_H  
  24. #define DETECT_RECOG_H  
  25.   
  26. extern CvMemStorage* storage;  
  27. extern CvHaarClassifierCascade* cascade;  
  28. extern CvHaarClassifierCascade* nested_cascade;  
  29. extern int use_nested_cascade;  
  30. extern const char* cascade_name;  
  31. extern const char* nested_cascade_name;  
  32. extern double scale;  
  33.   
  34. extern cv::Ptr<cv::FaceRecognizer> model;  
  35. extern vector<Mat> images;  
  36. extern vector<int> labels;  
  37.   
  38. void detect_and_draw( IplImage* img ); // 檢測和繪畫   
  39. void recog_and_draw( IplImage* img ); // 檢測和繪畫   
  40. void read_csv(const string &filename, vector<Mat> &images, vector<int> &labels, char separator = ';');  
  41. bool read_img(vector<Mat> &images, vector<int> &labels);  
  42. Mat norm_0_255(cv::InputArray _src);  
  43. void cvText(IplImage* img, const char* text, int x, int y);  
  44. #endif  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM