如何使用opencv显示面部检测的最终决定

时间:2016-04-21 16:10:34

标签: c++ opencv visual-studio-2013

我是使用opencv的初学者。我在VS2013上使用opencv 2.4。我开发了面部检测代码并取得了成功,但所做出的决定是逐帧进行的。如何通过组合所有帧或帧平均来做出最终决定?例如,当检测到的总面部检测到90%时,最终的决定是“面部检测”,反之亦然。

这是我的代码:

int main(int argc, char** argv)
{   
    CvCapture* capture;
    capture = cvCaptureFromFile("C:/Users/user/Desktop/Face and Motion/45.avi");

    //assert(capture != NULL); //terminate if capture is NULL
    IplImage* frame;

while (true)
{
    frame = cvQueryFrame(capture);
    if (!frame)
        break;
    cvShowImage("original", frame); //show
    CvMemStorage* storage = cvCreateMemStorage(0);
    CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad("C:/opencv2410/sources/data/haarcascades/haarcascade_frontalface_alt.xml");

    cvClearMemStorage(storage);
    CvSeq* faces = cvHaarDetectObjects(frame, cascade, storage, 1.1, 4, 0, cvSize(40, 50));
    CvRect* r;

    if (faces) //change from (!faces) to (faces)
    {
        for (int i = 0; i < (faces ? faces->total : 0); i++)
        {

            r = (CvRect*)cvGetSeqElem(faces, i);
            //cvRectangle(frame, cvPoint(100, 50), cvPoint(200, 200), CV_RGB(255, 0, 0), 5, 8);
            cvRectangle(frame, cvPoint(r->x, r->y), cvPoint(r->x + r->width, r->y + r->height), CV_RGB(255, 0, 0));

            cvShowImage("RESULTS", frame);

            char c = cvWaitKey(1000);
        }
    }
    else
    {
        cvShowImage("RESULT", frame); 
    }


    printf("%d Face Found !\n", faces ? faces->total : 0);


    if ((faces ? faces->total : 0) == 0)
    {
        printf("FACE NOT DETECTED !\n\n");
    }
    else
    {
        printf("FACE DETECTED !\n\n");
    }


}
return (0);

}

1 个答案:

答案 0 :(得分:0)

你需要两个变量,比如

int frame_count = 0;
int detected_face_count = 0;

您应该为每一帧增加frame_count,并在检测到面部时增加detected_face_count。最后detected_face_count / frame_count给出了你想要的价值。

然而,我对你的代码做了一些修改(我无法测试)

评论解释的变化。我希望它会有用。

int main(int argc, char** argv)
{
    CvCapture* capture;
    capture = cvCaptureFromFile("C:/Users/user/Desktop/Face and Motion/45.avi");

    //assert(capture != NULL); //terminate if capture is NULL
    IplImage* frame;

    //you need two variables
    int frame_count = 0;
    int detected_face_count = 0;

    // these lines should not be in the loop
    CvMemStorage* storage = cvCreateMemStorage(0);
    CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad("C:/opencv2410/sources/data/haarcascades/haarcascade_frontalface_alt.xml");

    while (true)
    {
        frame = cvQueryFrame(capture);
        if (!frame)
            break;

        frame_count++; // increase frame_count
        cvShowImage("original", frame); //show

        cvClearMemStorage(storage);
        CvSeq* faces = cvHaarDetectObjects(frame, cascade, storage, 1.1, 4, 0, cvSize(40, 50));
        CvRect* r;

        for (int i = 0; i < (faces ? faces->total : 0); i++)
        {
            r = (CvRect*)cvGetSeqElem(faces, i);
            //cvRectangle(frame, cvPoint(100, 50), cvPoint(200, 200), CV_RGB(255, 0, 0), 5, 8);
            cvRectangle(frame, cvPoint(r->x, r->y), cvPoint(r->x + r->width, r->y + r->height), CV_RGB(255, 0, 0));
        }

        cvShowImage("RESULT", frame);
        char c = cvWaitKey(1000);

        printf("%d Face Found !\n", faces ? faces->total : 0);


        if ((faces ? faces->total : 0) == 0)
        {
            printf("FACE NOT DETECTED !\n\n");
        }
        else
        {
            detected_face_count ++; // increase detected_face_count
            printf("FACE DETECTED !\n\n");
        }

    }

    if( (float)(detected_face_count / frame_count) > 0.89 )
    {
        printf("FACES DETECTED over %90 of frames!\n\n");
    }
    return (0);
}

正如@Miki所说,你不应该使用弃用的C api

使用C ++ api(使用OpenCV 3.1测试)查看下面的代码

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    VideoCapture capture("C:/Users/user/Desktop/Face and Motion/45.avi");
    if(!capture.isOpened())
    {
        printf("Video file could not be opened !\n");
        return -1;
    }

    Mat frame;

    //you need two variables
    int frame_count = 0;
    int detected_face_count = 0;

    // these lines should not be in the loop
    CascadeClassifier cascade;
    if( !cascade.load( "C:/opencv2410/sources/data/haarcascades/haarcascade_frontalface_alt.xml" ) )
    {
        cerr << "ERROR: Could not load classifier cascade" << endl;
        return -1;
    }

    while (true)
    {
        capture >>frame;
        if (frame.empty())
            break;

        frame_count++; // increase frame_count
        imshow("original", frame); //show

        vector<Rect> faces;
        cascade.detectMultiScale(frame, faces,1.1, 4, 0, Size(40, 50));

        for (int i = 0; i < faces.size(); i++)
        {
            rectangle(frame, faces[i], Scalar(0, 0, 255));
        }

        imshow("RESULT", frame);
        char c = waitKey(10);

        printf("%d Face Found !\n", faces.size());


        if ( faces.size() == 0 )
        {
            printf("FACE NOT DETECTED !\n\n");
        }
        else
        {
            detected_face_count ++; // increase detected_face_count
            printf("FACE DETECTED !\n\n");
        }

    }
    printf("count of frames : %d \n", frame_count);
    printf("count of frames has detected face : %d \n", detected_face_count);
    printf("Face Found %d percent of frames!\n", (int)(100 * detected_face_count / frame_count));

    if( (float)(detected_face_count / frame_count) > 0.89 )
    {
        printf("FACES DETECTED over %90 of frames!\n\n");
    }
    return (0);
}