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.
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?
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!
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.