Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Face Detection

I have a code that detects faces and saves multiple cropped area images of them to a file path. My code doesn't stop saving images of detected faces until I physically close the program. For every one second a face is detected on a webcam, my code saves 6 images of the face.

Is it possible to have it save just one image per face detected? For example, if there is one face, only one image, if two faces, an image of both faces are saved etc. My code is below. Can anyone help me?

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

void detectAndDisplay(Mat frame);

string face_cascade_name = "C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml";
CascadeClassifier face_cascade;
string window_name = "Window";
int filenumber; 
string filename;


int main(void)
{
    VideoCapture capture(0);

    if (!capture.isOpened())  
        return -1;

    if (!face_cascade.load(face_cascade_name))
    {
        cout << "error" << endl;
        return (-1);
    };

    Mat frame;

    for (;;)
    {
        capture >> frame;

        if (!frame.empty())
        {
            detectAndDisplay(frame);
        }
        else
        {
            cout << "error2" << endl;
            break;
        }

        int c = waitKey(10);

        if (27 == char(c))
        {
            break;
        }
    }

    return 0;
}

void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;
    Mat crop;
    Mat res;
    Mat gray;
    string text;
    stringstream sstm;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);

    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

    cv::Rect roi_b;
    cv::Rect roi_c;

    size_t ic = 0; 
    int ac = 0; 

    size_t ib = 0; 
    int ab = 0; 

    for (ic = 0; ic < faces.size(); ic++) 

    {
        roi_c.x = faces[ic].x;
        roi_c.y = faces[ic].y;
        roi_c.width = (faces[ic].width);
        roi_c.height = (faces[ic].height);

        ac = roi_c.width * roi_c.height; 

        roi_b.x = faces[ib].x;
        roi_b.y = faces[ib].y;
        roi_b.width = (faces[ib].width);
        roi_b.height = (faces[ib].height);


        crop = frame(roi_b);
        resize(crop, res, Size(128, 128), 0, 0, INTER_LINEAR); 
        cvtColor(crop, gray, CV_BGR2GRAY); 

        filename = "C:\\Users\\Desktop\\Faces\\face";
        stringstream ssfn;
        ssfn << filename.c_str() << filenumber << ".jpg";
        filename = ssfn.str();
        cv::imwrite(filename, res); 
        filenumber++;


        Point pt1(faces[ic].x, faces[ic].y); 
        Point pt2((faces[ic].x + faces[ic].height), (faces[ic].y + faces[ic].width));
        rectangle(frame, pt1, pt2, Scalar(0, 255, 0), 2, 8, 0);
    }


    sstm << "Crop area size: " << roi_b.width << "x" << roi_b.height << " Filename: " << filename;


    if (!crop.empty())
    {
        imshow("detected", crop);
    }
    else
        destroyWindow("detected");

}

Face Detection

I have a code that detects faces and saves multiple cropped area images of them to a file path. My code doesn't stop saving images of detected faces until I physically close the program. For every one second a face is detected on a webcam, my code saves 6 images of the face.

Is it possible to have it save just one image per face detected? For example, if there is one face, only one image, if two faces, an image of both faces are saved etc. My code is below. Can anyone help me?

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

void detectAndDisplay(Mat frame);

string face_cascade_name = "C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml";
CascadeClassifier face_cascade;
string window_name = "Window";
int filenumber; 
string filename;


int main(void)
{
    VideoCapture capture(0);

    if (!capture.isOpened())  
        return -1;

    if (!face_cascade.load(face_cascade_name))
    {
        cout << "error" << endl;
        return (-1);
    };

    Mat frame;

    for (;;)
    {
        capture >> frame;

        if (!frame.empty())
        {
            detectAndDisplay(frame);
        }
        else
        {
            cout << "error2" << endl;
            break;
        }

        int c = waitKey(10);

        if (27 == char(c))
        {
            break;
        }
    }

    return 0;
}

void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;
    Mat crop;
    Mat res;
    Mat gray;
    string text;
    stringstream sstm;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);

    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

    cv::Rect roi_b;
    cv::Rect roi_c;

    size_t ic = 0; 
    int ac = 0; 

    size_t ib = 0; 
    int ab = 0; 

    for (ic = 0; ic < faces.size(); ic++) 

    {
        roi_c.x = faces[ic].x;
        roi_c.y = faces[ic].y;
        roi_c.width = (faces[ic].width);
        roi_c.height = (faces[ic].height);

        ac = roi_c.width * roi_c.height; 

        roi_b.x = faces[ib].x;
        roi_b.y = faces[ib].y;
        roi_b.width = (faces[ib].width);
        roi_b.height = (faces[ib].height);


        crop = frame(roi_b);
        resize(crop, res, Size(128, 128), 0, 0, INTER_LINEAR); 
        cvtColor(crop, gray, CV_BGR2GRAY); 

        filename = "C:\\Users\\Desktop\\Faces\\face";
        stringstream ssfn;
        ssfn << filename.c_str() << filenumber << ".jpg";
        filename = ssfn.str();
        cv::imwrite(filename, res); 
        filenumber++;


        Point pt1(faces[ic].x, faces[ic].y); 
        Point pt2((faces[ic].x + faces[ic].height), (faces[ic].y + faces[ic].width));
        rectangle(frame, pt1, pt2, Scalar(0, 255, 0), 2, 8, 0);
    }


    sstm << "Crop area size: " << roi_b.width << "x" << roi_b.height << " Filename: " << filename;


    if (!crop.empty())
    {
        imshow("detected", crop);
    }
    else
        destroyWindow("detected");

}