最近的研究要用到定位瞳孔的位置,所以上網搜了下相關的代碼。總結如下:
1) 定位瞳孔可以直接使用opencv中的自帶的分類器(haarcascade_eye_tree_eyeglasses.xml)來實現,以前聽師兄說用opencv自帶的這個方法定位瞳孔不准,但我自己做了實驗后發現在正面人臉的情況下定位還是很准確的,后面有圖。分析了下原因,師兄是他之前實驗時感覺不准有可能是他的Opencv版本還不是很高,我這里用的是opencv2.4.4,相信opencv也在它的后續版本中不斷的優化它的Machine learning中相關庫以提高准確率。
當然,在復雜情況下的人眼精准定位本身就是一個熱門的研究課題。所以如果是復雜情況下的精准定位,opencv可能就沒那么給力了。
2)用opencv中檢測人臉、眼睛、嘴巴等都是用的CascadeClassifier分類器,具體使用時可以使用C的函數,也可以使用opencv中使用C++封裝好的類。下面是它們檢測目標時的函數形式(從opencv官網復制的)
C: CvSeq* cvHaarDetectObjects(const CvArr* image, CvHaarClassifierCascade* cascade,CvMemStorage* storage, double scale_factor=1.1, int min_neighbors=3, int flags=0, CvSize min_size=cvSize(0,0), CvSize max_size=cvSize(0,0) )
C++: void CascadeClassifier::detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())
這兩者最大的區別在於,用C封裝的函數要自己手動分配內存,而用C++的形式則不用自己去分配內存,這就是很多同學在網上找到的代碼有些要分配內存,有些又不用分配內存的原因。顯然C++的形式更簡潔,所以我下面的代碼也是用的C++的函數。
直接上代碼,注意下面的haarcascade_eye_tree_eyeglasses.xml文件在opencv安裝目錄下的data文件夾中。
完整的代碼在http://download.csdn.net/detail/computerme/7680383
- <span style="font-size:14px;">#include "highgui.h"
- #include "cv.h"
- #include <iostream>
- #include <stdio.h>
- using namespace std;
- using namespace cv;
- void DetectAndDraw(IplImage* img, CascadeClassifier& cascade);
- //String cascadeName = "haarcascade_frontalface_alt.xml";
- String cascadeName = "haarcascade_eye_tree_eyeglasses.xml";//nestedCascadeName
- int main( )
- {
- CascadeClassifier cascade;
- cascade.load( cascadeName );
- cvNamedWindow( "result", 1 );
- IplImage* iplImg = cvLoadImage("1.jpg");
- DetectAndDraw( iplImg, cascade );
- cvWaitKey(0);
- cvDestroyWindow("result");
- return 0;
- }
- void DetectAndDraw(IplImage* img, CascadeClassifier& cascade)
- {
- int i = 0;
- double t = 0;
- vector<Rect> faces;
- const static Scalar colors[] = { CV_RGB(0,0,255),
- CV_RGB(0,128,255),
- CV_RGB(0,255,255),
- CV_RGB(0,255,0),
- CV_RGB(255,128,0),
- CV_RGB(255,255,0),
- CV_RGB(255,0,0),
- CV_RGB(255,0,255)} ;
- IplImage* gray = cvCreateImage(cvGetSize(img),8,1);
- cvCvtColor( img, gray, CV_BGR2GRAY );
- cvEqualizeHist( gray, gray );
- t = (double)cvGetTickCount();
- cascade.detectMultiScale( gray , faces,
- 1.1, 2, 0
- //|CV_HAAR_FIND_BIGGEST_OBJECT
- //|CV_HAAR_DO_ROUGH_SEARCH
- |CV_HAAR_SCALE_IMAGE
- ,
- Size(30, 30) );
- t = (double)cvGetTickCount() - t;
- printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
- for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ )
- {
- Point center;
- Scalar color = colors[i%8];
- int radius;
- //center可以作為瞳孔的坐標
- center.x = cvRound(r->x + r->width*0.5);
- center.y = cvRound(r->y + r->height*0.5);
- //radius = (int)(cvRound(r->width + r->height)*0.25);
- radius =2;
- cvCircle( img, center, radius, color, 3, 8, 0 );
- cvShowImage( "result", img );
- }
- cvShowImage( "result", img );
- }</span>
運行結果:
網址:http://blog.csdn.net/computerme/article/details/38142125