c++ - OpenCV: Why does Haar classifier only detect one face and one eye? -
i absolutely newcomer opencv , haar classifiers. have copied following code , works fine, returns 1 face , 1 eye. second eye , face?
const char[] eyescascadefilename = "haarcascade_eye.xml"; const char[] facecascadefilename = "haarcascade_frontalface_alt2.xml"; const int haaroptions = cv_haar_do_rough_search; // prepare image fast processing mat grayimage; cvtcolor(colorimage, grayimage, cv_bgr2gray); equalizehist(grayimage, grayimage); // detect faces on image std::vector<cv::rect> faces; facecascade.detectmultiscale(grayimage, faces, 1.1, 2, haaroptions, cv::size(60, 60)); (int = 0; < faces.size(); i++) { // visualize faces cv::point pt1(faces[i].x + faces[i].width, faces[i].y + faces[i].height); cv::point pt2(faces[i].x, faces[i].y); cv::rectangle(colorimage, pt1, pt2, cvscalar(0, 255, 0, 0), 1, 8 ,0); // detect eyes within facial roi cv::rect rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); cv::mat roi = grayimage(rect); std::vector<cv::rect> eyes; // here's problem ...: eyescascade.detectmultiscale(roi, eyes, 1.1, 2, haaroptions, cv::size(30, 30)); //eyescascade.detectmultiscale(roi, eyes); (int = 0; < eyes.size(); i++) { // visualize eyes cv::point pt1(faces[i].x + eyes[i].x + eyes[i].width, faces[i].y + eyes[i].y + eyes[i].height); cv::point pt2(faces[i].x + eyes[i].x, faces[i].y + eyes[i].y); cv::rectangle(colorimage, pt1, pt2, cvscalar(0, 210, 255, 0), 1, 8 ,0); } }
here's looks like:
edit
in code, in inner for
loop, making new variable same name iteration variable of outer for
loop (i
). since in different scopes allowed, , variable in inner scope "owns" name. not able access outer-scoped i
inside inner scope.
the loop declaration part of scope of loop, counts part of inner-scope in case of second i
.
in case, translates fact able draw 1 eye @ time given face, if 2 detected. can't reach eye(2) face(1). lucky code didn't crash: due fact both face , eye vector of same size (2).
in debug mode got eye.size == 1
because @ particular moment algorithm able detect 1 eye. @ next iteration eye.size
have been 2.
so, use, let's say, int j = 0 in inner loop iterate through eye vector, , you'll fine!
end edit
this own (working) version of algorithm:
#include "facedetectionhaar.h" facedetectionhaar::facedetectionhaar() { face_cascade_name = "haarcascade_frontalface_alt.xml"; eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml"; if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)error loading\n");}; if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)error loading\n");}; } void facedetectionhaar::execute(iplimage in) { mat imgmat(&in); std::vector<rect> faces; mat frame_gray; cvtcolor( imgmat, frame_gray, cv_bgr2gray ); equalizehist( frame_gray, frame_gray ); //-- detect faces face_cascade.detectmultiscale( frame_gray, faces, 1.1, 2, 0|cv_haar_scale_image, size(30, 30) ); for( int = 0; < faces.size(); i++ ) { point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 ); ellipse( imgmat, center, size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, scalar( 255, 0, 255 ), 4, 8, 0 ); mat faceroi = frame_gray( faces[i] ); std::vector<rect> eyes; //-- in each face, detect eyes eyes_cascade.detectmultiscale( faceroi, eyes, 1.1, 2, 0 |cv_haar_scale_image, size(30, 30) ); for( int j = 0; j < eyes.size(); j++ ) { point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 ); int radius = cvround( (eyes[j].width + eyes[i].height)*0.25 ); circle( imgmat, center, radius, scalar( 255, 0, 0 ), 4, 8, 0 ); } } in = imgmat; }
the code way simpler yours roi part. , maybe use of haar option cv_haar_scale_image
instead of cv_haar_do_rough_search
help.
this code part copy of 1 given on opencv website. should try haar cascades xml files provide too, both faces , eyes.
Comments
Post a Comment