简体   繁体   中英

Python cropped face image using dlib

I want to adjust the margin of cropped face image. My current code can detect and crop face. However, the cropped image is too tight as shown in the below output image.

Input image:

在此处输入图像描述

Below is my code:

import face_recognition
import cv2

img = face_recognition.load_image_file("test.png")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

face_locations = face_recognition.face_locations(img_rgb)

for top, right, bottom, left in face_locations:
    # Draw a box around the face
    cv2.rectangle(img, (left, top), (right, bottom), (0, 0, 255), 2)

    crop_img = img_rgb[top:bottom, left:right]
    cv2.imwrite('test_crop.png', crop_img)

UPDATE: It will not work correctly for out of bound bounding boxes after scaling.

Code:

Use the scale_factor to control the new rectangle size. Also a different formula can be used for M . Using abs may not be necessary.

import face_recognition
import cv2


img = face_recognition.load_image_file("test.png")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_rgb_copy = img_rgb.copy()


## Define scale factor and window size
scale_factor = 1.1
sz1 = img_rgb.shape[1] * 2
sz2 = img_rgb.shape[0] * 2


face_locations = face_recognition.face_locations(img_rgb)

for top, right, bottom, left in face_locations:
    # Draw a box around the face
    #cv2.rectangle(img, (left, top), (right, bottom), (0, 0, 255), 2)

    crop_img = img_rgb[top:bottom, left:right]
    #cv2.imwrite('test_crop.png', crop_img)



    ## Calculate center points and rectangle side length
    width = right - left
    height = bottom - top
    cX = left + width // 2
    cY = top + height // 2
    M = (abs(width) + abs(height)) / 2


    ## Get the resized rectangle points
    newLeft = max(0, int(cX - scale_factor * M))
    newTop = max(0, int(cY - scale_factor * M))
    newRight = min(img_rgb.shape[1], int(cX + scale_factor * M))
    newBottom = min(img_rgb.shape[0], int(cY + scale_factor * M))


    ## Draw the circle and bounding boxes
    cv2.circle(img_rgb_copy, (cX, cY), radius=0, color=(0, 0, 255), thickness=2)
    cv2.rectangle(img_rgb_copy, (left, top), (right, bottom), (0, 0, 255), 2)
    cv2.rectangle(img_rgb_copy, (newLeft, newTop), (newRight, newBottom), (255, 0, 0), 2)


    ## Show the original image in window resized to double
    cv2.namedWindow('image', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('image', sz1, sz2)
    cv2.imshow("image", img_rgb_copy)
    cv2.waitKey(0)


cv2.destroyAllWindows()

Image:

在此处输入图像描述

Method:

Get the center point (cX, cY) of given region and from that get new left corner of image by subtracting same value from both (cX - M,cY - M) . So the right corner will be (cX + M, cY + M) . You can use a scale factor such as, M * p instead of M , where p will control how large or small the new region will be.

Center Point:

width = right - left
height = bottom - top

centerX = left + (width / 2)
centerY = top + (height / 2)

M = (abs(width) + abs(height)) / 2

0 <= p < 1, for smaller crop than given in a side
p > 1, for larger crop margin

Also the new crop may be out of bounds in image. To solve it something like, newTop = max(0, newTop) , newRight = min(imageWidth, newRight) can be done and similar for others. You can find a demo here,

https://www.desmos.com/calculator/bgn9dobkjt

在此处输入图像描述

DeepFace wraps many face detection libraries. Besides, it applies face alignment in the background. You can detect faces in a line of code.

#!pip install deepface
from deepface import DeepFace
backends = ['opencv', 'ssd', 'dlib', 'mtcnn']
for backend in backends:
   detected_face = DeepFace.detectFace("img.jpg", detector_backend = backend)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM