Face_recognition: Cannot crop frame based on face_location

Created on 6 Aug 2018  路  2Comments  路  Source: ageitgey/face_recognition

  • face_recognition version: 1.2.2 (most current)
  • Python version: 3.6.5
  • Operating System: MacOS

Description

When getting the location of faces in a live webcam feed I have been trying to crop the image to just display the detected face. However, when I used the rectangle coordinates to perform a crop on the image and save it to the disk, the jpg cannot be opened because it is empty.
screen shot 2018-08-05 at 10 06 58 pm
Here is a screenshot to show you that drawing a rectangle is working.

What I Did

import cv2
import face_recognition
import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-d", "--detection-method", type=str, default="hog", help="face detection model to use: either `hog` (light) or `cnn` (heavy)")
args = vars(ap.parse_args())

cap = cv2.VideoCapture(0)

print("[WELCOME] Welcome to the face dataset creator!")
print("[INFO] Attempting to recognize face...")
faces_recognized = 0
while(True):
    ret, frame = cap.read()
    if not ret:
        print("[WARNING] Error retrieving frame from web-cam")
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    face_location_array = face_recognition.face_locations(rgb_frame, model=args['detection_method'])
    if face_location_array:     #  prevent manipulation of null variable
        y1 = face_location_array[0][0]
        x1 = face_location_array[0][1]
        end_coordinate_y = face_location_array[0][2]
        end_coordinate_x = face_location_array[0][3]
        faces_recognized += 1
        print("[%i] Face recognized..." % faces_recognized)
        cv2.rectangle(frame, (x1, y1), (end_coordinate_x, end_coordinate_y), (0, 0, 255), 2)
        cropped_face = frame[x1:end_coordinate_y, y1:end_coordinate_x]
        cv2.imwrite("faceimage.jpg", cropped_face)

    cv2.imshow('face detector', frame)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Most helpful comment

I think you've mixed up the order of variables when extracting data from the array. Instead of this:

    face_location_array = face_recognition.face_locations(rgb_frame, model=args['detection_method'])
    if face_location_array:     #  prevent manipulation of null variable
        y1 = face_location_array[0][0]
        x1 = face_location_array[0][1]
        end_coordinate_y = face_location_array[0][2]
        end_coordinate_x = face_location_array[0][3]
        faces_recognized += 1
        print("[%i] Face recognized..." % faces_recognized)
        cv2.rectangle(frame, (x1, y1), (end_coordinate_x, end_coordinate_y), (0, 0, 255), 2)
        cropped_face = frame[x1:end_coordinate_y, y1:end_coordinate_x]

Try this:

    face_location_array = face_recognition.face_locations(rgb_frame, model=args['detection_method'])
    if face_location_array:     #  prevent manipulation of null variable

        top, right, bottom, left = face_location_array[0]

        faces_recognized += 1
        print("[%i] Face recognized..." % faces_recognized)

        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
        cropped_face = frame[top:bottom, left:right]

All 2 comments

I think you've mixed up the order of variables when extracting data from the array. Instead of this:

    face_location_array = face_recognition.face_locations(rgb_frame, model=args['detection_method'])
    if face_location_array:     #  prevent manipulation of null variable
        y1 = face_location_array[0][0]
        x1 = face_location_array[0][1]
        end_coordinate_y = face_location_array[0][2]
        end_coordinate_x = face_location_array[0][3]
        faces_recognized += 1
        print("[%i] Face recognized..." % faces_recognized)
        cv2.rectangle(frame, (x1, y1), (end_coordinate_x, end_coordinate_y), (0, 0, 255), 2)
        cropped_face = frame[x1:end_coordinate_y, y1:end_coordinate_x]

Try this:

    face_location_array = face_recognition.face_locations(rgb_frame, model=args['detection_method'])
    if face_location_array:     #  prevent manipulation of null variable

        top, right, bottom, left = face_location_array[0]

        faces_recognized += 1
        print("[%i] Face recognized..." % faces_recognized)

        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
        cropped_face = frame[top:bottom, left:right]

@ageitgey Thank you very much, it works perfectly! Saved me from more frustrating, inconclusive Google searches.

Was this page helpful?
0 / 5 - 0 ratings