Reputation: 121
I am using Haarcascades for detecting faces and eyes. My problem is, its bounding many boxes as eyes. My syntax is
face_cascade = cv2.CascadeClassifier('haarcascades\haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascades\haarcascade_eye.xml')
img = cv2.imread('SAM7.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,1.2,6)
I am currently using 1.2 and 6. What should be the value of the parameters in faces(5 line) like scaleFactor, minNeighbors ??
Upvotes: 2
Views: 3149
Reputation: 1465
You really need to play with the parameters and find the ones works fine for you. Always there is a better way to do it but remember you'll never achieve 100% accuracy. You can learn about the parameters here.
An example of face and eyes detection in python that works for me:
import cv2
face_cascade = cv2.CascadeClassifier("../haarcascades/haarcascade_frontalface_default.xml")
eye_cascade = cv2.CascadeClassifier("../haarcascades/haarcascade_eye.xml")
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if ret:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.3,
minNeighbors=5,
minSize=(50, 50)
)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0),2)
roi_gray = gray[y:y + h, x:x + w]
roi_color = frame[y:y + h, x:x + w]
eyes = eye_cascade.detectMultiScale(
roi_gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(10, 10)
)
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (255, 0, 0), 2)
cv2.imshow("Faces found", frame)
k = cv2.waitKey(10) & 0xff
if k == 27:
break
cv2.destroyAllWindows()
cap.release()
I hope this helps you. If you need help with the code let me know.
Upvotes: 1
Reputation: 391
To find parameters, a very good real-time implementation has been implemented here for face and eye detection. In this project, he first detects face region and then eyes. If you go through the code, you will find the section you can also draw the bounding box for face:
main.cpp : Detecting Face and Eyes
//-- Detect faces
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE|CV_HAAR_FIND_BIGGEST_OBJECT, cv::Size(150, 150) );
// findSkin(debugImage);
for( int i = 0; i < faces.size(); i++ )
{
rectangle(debugImage, faces[i], 1234);
}
//-- Show what you got
if (faces.size() > 0) {
findEyes(frame_gray, faces[0]);
}
It uses face ROI to detect eyes:
void findEyes(cv::Mat frame_gray, cv::Rect face) {
cv::Mat faceROI = frame_gray(face);
cv::Mat debugFace = faceROI;
if (kSmoothFaceImage) {
double sigma = kSmoothFaceFactor * face.width;
GaussianBlur( faceROI, faceROI, cv::Size( 0, 0 ), sigma);
}
//-- Find eye regions and draw them
int eye_region_width = face.width * (kEyePercentWidth/100.0);
int eye_region_height = face.width * (kEyePercentHeight/100.0);
int eye_region_top = face.height * (kEyePercentTop/100.0);
cv::Rect leftEyeRegion(face.width*(kEyePercentSide/100.0),
eye_region_top,eye_region_width,eye_region_height);
cv::Rect rightEyeRegion(face.width - eye_region_width - face.width*(kEyePercentSide/100.0),
eye_region_top,eye_region_width,eye_region_height);
//-- Find Eye Centers
cv::Point leftPupil = findEyeCenter(faceROI,leftEyeRegion,"Left Eye");
cv::Point rightPupil = findEyeCenter(faceROI,rightEyeRegion,"Right Eye");
// get corner regions
cv::Rect leftRightCornerRegion(leftEyeRegion);
leftRightCornerRegion.width -= leftPupil.x;
leftRightCornerRegion.x += leftPupil.x;
leftRightCornerRegion.height /= 2;
leftRightCornerRegion.y += leftRightCornerRegion.height / 2;
cv::Rect leftLeftCornerRegion(leftEyeRegion);
leftLeftCornerRegion.width = leftPupil.x;
leftLeftCornerRegion.height /= 2;
leftLeftCornerRegion.y += leftLeftCornerRegion.height / 2;
cv::Rect rightLeftCornerRegion(rightEyeRegion);
rightLeftCornerRegion.width = rightPupil.x;
rightLeftCornerRegion.height /= 2;
rightLeftCornerRegion.y += rightLeftCornerRegion.height / 2;
cv::Rect rightRightCornerRegion(rightEyeRegion);
rightRightCornerRegion.width -= rightPupil.x;
rightRightCornerRegion.x += rightPupil.x;
rightRightCornerRegion.height /= 2;
rightRightCornerRegion.y += rightRightCornerRegion.height / 2;
rectangle(debugFace,leftRightCornerRegion,200);
rectangle(debugFace,leftLeftCornerRegion,200);
rectangle(debugFace,rightLeftCornerRegion,200);
rectangle(debugFace,rightRightCornerRegion,200);
// change eye centers to face coordinates
rightPupil.x += rightEyeRegion.x;
rightPupil.y += rightEyeRegion.y;
leftPupil.x += leftEyeRegion.x;
leftPupil.y += leftEyeRegion.y;
// draw eye centers
circle(debugFace, rightPupil, 3, 1234);
circle(debugFace, leftPupil, 3, 1234);
//-- Find Eye Corners
if (kEnableEyeCorner) {
cv::Point2f leftRightCorner = findEyeCorner(faceROI(leftRightCornerRegion), true, false);
leftRightCorner.x += leftRightCornerRegion.x;
leftRightCorner.y += leftRightCornerRegion.y;
cv::Point2f leftLeftCorner = findEyeCorner(faceROI(leftLeftCornerRegion), true, true);
leftLeftCorner.x += leftLeftCornerRegion.x;
leftLeftCorner.y += leftLeftCornerRegion.y;
cv::Point2f rightLeftCorner = findEyeCorner(faceROI(rightLeftCornerRegion), false, true);
rightLeftCorner.x += rightLeftCornerRegion.x;
rightLeftCorner.y += rightLeftCornerRegion.y;
cv::Point2f rightRightCorner = findEyeCorner(faceROI(rightRightCornerRegion), false, false);
rightRightCorner.x += rightRightCornerRegion.x;
rightRightCorner.y += rightRightCornerRegion.y;
circle(faceROI, leftRightCorner, 3, 200);
circle(faceROI, leftLeftCorner, 3, 200);
circle(faceROI, rightLeftCorner, 3, 200);
circle(faceROI, rightRightCorner, 3, 200);
}
Upvotes: 0