【问题标题】:OpenCV & Python : Face Detection using haarcascades is detecting many boxes as eyes.OpenCV 和 Python:使用 haar 级联的人脸检测将许多框检测为眼睛。
【发布时间】:2023-03-25 04:55:01
【问题描述】:

我正在使用 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 line) 中的参数值应该是多少,例如 scaleFactor、minNeighbors ??

【问题讨论】:

  • 您应该将眼睛检测减少到之前检测到人脸的区域。

标签: python opencv face-detection haar-classifier eye-detection


【解决方案1】:

您确实需要使用参数并找到适合您的参数。总是有更好的方法来做到这一点,但请记住,您永远不会达到 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()   

我希望这对你有帮助。如果您需要有关代码的帮助,请告诉我。

【讨论】:

    【解决方案2】:

    为了查找参数,已经实现了一个非常好的实时实现here 用于面部和眼睛检测。 在这个项目中,他首先检测面部区域,然后检测眼睛。 如果你浏览代码,你会发现你还可以绘制人脸边界框的部分:

    ma​​in.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);
      }
    

    【讨论】:

      猜你喜欢
      • 2016-10-26
      • 1970-01-01
      • 2015-04-23
      • 2013-12-26
      • 2015-05-24
      • 1970-01-01
      • 2014-06-27
      • 2013-12-30
      • 1970-01-01
      相关资源
      最近更新 更多