1
votes

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!

1
Well that worked pretty smooth. Much more simple than I thought it would be. Thank you Rick for your super-quick answer! Really appreciate it. - Michael Pappas
Glad it helped! I added the comment as an answer instead! Welcome to StackOverflow! - Rick M.
And I approved it. Nice to meet you all. I've been getting lots of answers from SO, but just decided to join. Hope we can talk again in the near future. Have a nice day! - Michael Pappas

1 Answers

2
votes

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.