c++opencvface-recognitionface-detection

OpenCV Face Detection ROI Assertion Failed


I'm kinda new in OpenCV and I wanted to practice with a simple face detection and image cropping.

Specifically, I load images from a folder using cv::glob, then I detect the faces, draw a rectangle on the detected face and then crop only the detected face region.

Everything works fine, the face is detected, the rectangle is drawn right at the spot. Except the last part: cropping. I get the infamous Assertion Failed error. Below is my code and the error I'm having:

void faceDetectFolder()
{
    Mat source;

    CascadeClassifier face_cascade;
    face_cascade.load("C:/OpenCV-3.2.0/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml");

    String path(path on my PC);
    std::vector<cv::String> fn;
    glob(path, fn, true);

    for (size_t i = 0; i < fn.size(); i++)
    {
        source = imread(fn[i]);
        if (source.empty()) continue;

        std::string imgname = fn[i].substr(45, std::string::npos); //File name
        std::vector<Rect> faces;
        face_cascade.detectMultiScale(source, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));

        for (int i = 0; i < faces.size(); i++)
        {

            if (faces[i].width > 80 && faces[i].height*0.5 > 80) //Threshold, some detections are false
            {
                int x = faces[i].x;
                int y = faces[i].y;
                int h = y + faces[i].height;
                int w = x + faces[i].width;

                rectangle(source, Point(x, y), Point(w, h), Scalar(255, 0, 0), 2, 8, 0); //Drawing rectangle on detected face

                imshow(imgname, source);

                Rect roi;
                roi.x = x;
                roi.y = y;
                roi.height = h;
                roi.width = w;      

                Mat detectedface = source(roi);

                imshow("cropped image", detectedface);

                waitKey(0);
            }
        }
    }
}

And the error:

OpenCV Error: Assertion failed (0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows) in cv::Mat::Mat, file C:\build\master_winpack-build-win64-vc14\opencv\modules\core\src\matrix.cpp, line 522

Now I understand that the error shows up because the roi is out of bounds. Here's what troubles me though.

  1. Shouldn't I get this error when I try to draw the rectangle in the first place? Why do I get the error on the roi but NOT on the rectangle I'm drawing?

  2. Why is the roi out of bounds? I show the image with the rectangle drawn on it and everything looks fine. Why I get this error when the roi has the same values as the drawn rectangle?

Please excuse me for any rookie mistakes, we all start somewhere. Thank you for reading and have a nice day!


Solution

  • In the roi.height and roi.width, try giving faces[i].height and faces[i].width respectively. Indeed you'd think that the error should come before but it works with drawing as rectangle takes as argument two diagonally opposite vertexes and not width/height in the case of your Rect roi. You could initialize the Rect instead with Point(x, y) and Point(w,h) and it should work fine.