OpenCV & Python :使用 haarcascades 的人脸检测将许多框检测为眼睛。
OpenCV & Python : Face Detection using haarcascades is detecting many boxes as eyes.
我正在使用 Haarcascades 检测面部和眼睛。我的问题是,它像眼睛一样包围了许多盒子。我的语法是
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)
我目前使用的是 1.2 和 6。faces(5 行) 中的参数值应该是多少,如 scaleFactor、minNeighbors ??
为了找到参数,已经实现了一个非常好的实时实现here用于面部和眼睛检测。
在这个项目中,他首先检测面部区域,然后检测眼睛。
如果你浏览代码,你会发现你也可以为面部绘制边界框的部分:
main.cpp:检测面部和眼睛
//-- 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]);
}
它使用面部 ROI 来检测眼睛:
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);
}
您确实需要使用这些参数并找到适合您的参数。总是有更好的方法来做到这一点,但请记住,您永远不会达到 100% 的准确性。
您可以了解参数here。
python 中适合我的面部和眼睛检测示例:
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()
希望对您有所帮助。如果您需要有关代码的帮助,请告诉我。
我正在使用 Haarcascades 检测面部和眼睛。我的问题是,它像眼睛一样包围了许多盒子。我的语法是
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)
我目前使用的是 1.2 和 6。faces(5 行) 中的参数值应该是多少,如 scaleFactor、minNeighbors ??
为了找到参数,已经实现了一个非常好的实时实现here用于面部和眼睛检测。 在这个项目中,他首先检测面部区域,然后检测眼睛。 如果你浏览代码,你会发现你也可以为面部绘制边界框的部分:
main.cpp:检测面部和眼睛
//-- 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]);
}
它使用面部 ROI 来检测眼睛:
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);
}
您确实需要使用这些参数并找到适合您的参数。总是有更好的方法来做到这一点,但请记住,您永远不会达到 100% 的准确性。 您可以了解参数here。
python 中适合我的面部和眼睛检测示例:
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()
希望对您有所帮助。如果您需要有关代码的帮助,请告诉我。