pythonopencvface-detection

Face Detection: show only one face at a time


I've been developing a face detection app integrated with ROS to be used with DRONES (bebop parrot to be exact). The code itself can be found on google and what it does is, basically, shows every face that appear on screen. My problem is: I want the drone to follow my face (and only mine) but as i said before, the code can detect multiples faces at time. Here's the code:

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# some people can just use the haarcascade_frontalface_default.xml without specifying the path
test = face_cascade.load('../../../../opencv/data/haarcascades/haarcascade_frontalface_default.xml')

# start the video capture
video_capture = cv2.VideoCapture(0)

# while-loop to detect face on webcam until you press 'q'.
while not rospy.is_shutdown():
    # Capture frame-by-frame
    ret, frame = video_capture.read()
    frame = imutils.resize(frame, width=600)

    #convert the frame (of the webcam) to gray)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    mask = cv2.erode(gray, None, iterations=2)
    mask = cv2.dilate(mask, None, iterations=2)

    # detecting the faces
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)

    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
        x_imagem = x + (w/2)
        y_imagem = y + (h/2)
        cv2.circle(frame, (x+(w/2), y+(h/2)), 5, (0,0,255), -1)
        #600 x 450;
        if(x_imagem > 200 and x_imagem < 400):
            rospy.loginfo("CENTRO")
        elif(x_imagem < 200): #ROSTO PRA ESQUERDA, ENTAO VAI PARA DIREITA
            rospy.loginfo("ROSTO NA ESQUERDA")
            pub_face.publish("esq")
        elif(x_imagem > 400): #ROSTO PRA DIREITA, ENTAO VAI PARA ESQUERDA
            rospy.loginfo("ROSTO NA DIREITA")
            pub_face.publish("dir")

    # Display the resulting frame
    cv2.imshow('Video', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        rospy.loginfo("FIM DO PROGRAMA DE DETECCAO DE ROSTOS")
        break

# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()

As you can see, we have an array of FACES at:

faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)

The code will draw a rectangle where the face is, is there a way that I can make it show only the biggest rectangle (in that case, my face)? Hope I could make it clear!


Solution

  • Is there a way that I can make it show only the biggest rectangle (in that case, my face)?

    Iterate thought the list of 'faces' and calculate the area of each Region of Interest (ROI), and grab the largest area.