使用 dlib 的 Python 裁剪人脸图像

标签 python opencv crop face-recognition dlib

我想调整裁剪后的人脸图像的边距。我当前的代码可以检测和裁剪人脸。但是,裁剪后的图像太紧,如下面的输出图像所示。

输入图片:

enter image description here

下面是我的代码:

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)

最佳答案

更新:在缩放后,它不会对超出边界的边界框正常工作。

代码:

使用scale_factor 来控制新矩形的大小。 M 也可以使用不同的公式。可能没有必要使用 abs

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()

图片:

enter image description here

方法:

获取给定区域的中心点 (cX, cY) 并通过从 (cX - M,cY - M)。所以右角将是(cX + M, cY + M)。您可以使用比例因子,例如 M * p 而不是 M,其中 p 将控制新区域的大小.

中心点:

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

此外,新裁剪可能超出图像范围。要解决类似 newTop = max(0, newTop)newRight = min(imageWidth, newRight) 之类的问题,其他人也可以这样做。你可以在这里找到一个演示,

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

enter image description here

关于使用 dlib 的 Python 裁剪人脸图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62266719/

相关文章:

android - Android 上矢量 <DMatch> OpenCV 的问题

android - 向图像添加空格并保存文件

python - 裁剪功能 Jython JES

python - 索引计数字典的嵌套列表

python - Apache Airflow - 使用 pymssql + SQLAlchemy 与 MS SQL Server 的连接问题

python - web.py - WalkerError : ('unexpected node type' , 339)

javascript - jcrop 全宽/高,带比例裁剪

python - 无法使用 Python 读取服务器上的 UDP 数据包

python - 出现错误 “FindContours support only 8uC1 and 32sC1 images in function cvStartFindContours”

opencv - OpenCv-深度图