vs2012+opencv2.4.7 實現單張人臉識別


參考:http://blog.sina.com.cn/s/blog_593c85f20100ncnj.html

OpenCV的庫中帶有檢測正面人臉的 Haar迭代算法Haar Cascade Face Detector (also known as the Viola-Jones method)。Shervin Emami在他的blog(http://www.shervinemami./introToOpenCV.html)中介紹了相關function的使用。他的檢測代碼教簡單快速,但是沒有提供直觀的人臉檢測后識別人臉的矩形框圖,因此,下面結合他的程序加入檢測后圖像顯示功能,可較為直觀感受OpenCV帶來的便捷。

 

如何新建一個工程和C++文件,已在《OpenCV入門一:安裝配置(with VC++ 2008/2010 Express)》中介紹過,這里不再重復。建好所需的工程和C++文件后,按照下面幾個步驟,課生成如圖一所示的人臉檢測圖像:

 

 

步驟一:C++代碼

新建faceDetector工程,任意取名其中包含的C++文件名,實用下列代碼:

 

#include <stdio.h> // For printf()
#include <cv.h>  // Main OpenCV library.
#include <highgui.h> // OpenCV functions for files and graphical windows.
 
using namespace std;
using namespace cv;
 
// Initialize a sub funcion using after main
CvRect detectFaceInImage( IplImage *inputImg, CvHaarClassifierCascade* cascade);
 
int main(int argc, char* argv[])
{
    CvPoint pt1, pt2;    // For draw rectangle
    // Check the input is correct when call executable file
    if (argc != 2)
    {
         printf("Usage: faceDetector.exe <imagename>\n");
         exit(-1);
    }
 
    char * imgName = argv[1];    // Copy the second input as the image name
    // Load image
    IplImage* inputImg = cvLoadImage(imgName, CV_LOAD_IMAGE_UNCHANGED);
    if (!inputImg) {
         printf("Error: Could not open the image file! \n");
         exit(-1);
    }
 
    // Haar Cascade file, used for Face Detection.
    // Note: you could change this directory as your installed OpenCV2.1 location
    char *faceCascadeFilename = "C:/OpenCV2.1/data/haarcascades/haarcascade_frontalface_alt.xml";
    // Load the HaarCascade classifier for face detection.
    CvHaarClassifierCascade* faceCascade;
    faceCascade = (CvHaarClassifierCascade*)cvLoad(faceCascadeFilename, 0, 0, 0);
    if( !faceCascade ) {
         printf("Couldnt load Face detector '%s'\n", faceCascadeFilename);
         exit(-1);
    }

    // Perform face detection on the input image, using the given Haar classifier
    CvRect faceRect = detectFaceInImage(inputImg, faceCascade);
    // Make sure a valid face was detected then draw the rect location.
    if (faceRect.width > 0) 
    {
         printf("Detected a face at (%d,%d)!\n", faceRect.x, faceRect.y);
 
         // Get the pointer of the face rectangle
         pt1.x = faceRect.x;
         pt2.x = faceRect.x + faceRect.width;
         pt1.y = faceRect.y;
          pt2.y = faceRect.y + faceRect.height;
 
         // Draw the rectangle in the input image
          cvRectangle( inputImg, pt1, pt2, CV_RGB(255,0,0), 2, 8, 0 );

         // Show the detected face image on the screen.
         cvNamedWindow("Detected face", CV_WINDOW_AUTOSIZE);
         // Show the image in the window named "Detected face", you could change as you like
         cvShowImage( "Detected face", inputImg );

         // Wait for the user to press something on the graphical window.
         // Note: cvWaitKey() is needed for time to draw on the screen.
         cvWaitKey(0);
 
         // Free the resources.
         cvDestroyWindow("Detected face");
         cvReleaseImage( &inputImg );
     }
 
    // Free the Face Detector resources when the program is finished
    cvReleaseHaarClassifierCascade( &faceCascade );
    return 0;
}
 
// Perform face detection on the input image, using the given Haar Cascade.
// Returns a rectangle for the detected region in the given image.
CvRect detectFaceInImage(IplImage *inputImg, CvHaarClassifierCascade* cascade)
{
    // Smallest face size.
    CvSize minFeatureSize = cvSize(20, 20);
    // Only search for 1 face.
    int flags = CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_DO_ROUGH_SEARCH;
    // How detailed should the search be.
    float search_scale_factor = 1.1f;
    IplImage *detectImg;
    IplImage *greyImg = 0;
    CvMemStorage* storage;
    CvRect rc;
    //double t;
    CvSeq* rects;
    CvSize size;
    int nFaces;
    //int i, ms; 
    storage = cvCreateMemStorage(0);
    cvClearMemStorage( storage );
 
    // If the image is color, use a greyscale copy of the image.
    detectImg = (IplImage*)inputImg;
    if (inputImg->nChannels > 1) {
        size = cvSize(inputImg->width, inputImg->height);
        greyImg = cvCreateImage(size, IPL_DEPTH_8U, 1 );
        cvCvtColor( inputImg, greyImg, CV_BGR2GRAY );
        detectImg = greyImg; // Use the greyscale image.
    }
 
    // Detect all the faces in the greyscale image.
    //t = (double)cvGetTickCount();
    rects = cvHaarDetectObjects( detectImg, cascade, storage,
    search_scale_factor, 3, flags, minFeatureSize);
    //t = (double)cvGetTickCount() - t;
    //ms = cvRound( t / ((double)cvGetTickFrequency() * 1000.0) );
    nFaces = rects->total;
    //printf("Face Detection took %d ms and found %d objects\n", ms, nFaces);
    // Get the first detected face (the biggest).
    if (nFaces > 0)
        rc = *(CvRect*)cvGetSeqElem( rects, 0 );
    else
        rc = cvRect(-1,-1,-1,-1); // Couldn't find the face.

    if (greyImg)
    {
        cvReleaseImage( &greyImg );
    }
    cvReleaseMemStorage( &storage );
    return rc; // Return the biggest face found, or (-1,-1,-1,-1).
} 

步驟二:編譯(只是編譯 ,這一步還看不到圖片)

如果編譯出錯,比如找不到cv打頭的function(比如CvHaarClassifierCascade等),或者找不到頭文件、資源文件等,都有可能是工程配置不對。請參考之前提到的配置文章查看自己的配置。

Debug之后,在此新建工程中Debug文件夾里找到可執行文件。如果你新建的工程名是faceDetector,無論你的C++文件名是什么,debug之后可執行文件的名字都是faceDetector.exe。

 

步驟三:調用可執行文件

Start -> Run 在輸入框中輸入 cmd 然后回車,出現dos命令行窗口。

按圖二所示,輸入faceDetector工程Debug文件夾的地址,輸入 “可執行文件名(紅色框內)圖片名”,然后回車,就會得到檢測出人臉的圖像(圖一)以及圖中矩形框左上角的其實坐標。

 

 

注意: 需要依賴的lib庫如下 項目/屬性/連接器

opencv_core247d.lib
opencv_highgui247d.lib
opencv_imgproc247d.lib
opencv_features2d247d.lib
opencv_calib3d247d.lib
opencv_objdetect247d.lib

 


免責聲明!

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



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