【问题标题】:Python cropped face image using dlibPython使用dlib裁剪人脸图像
【发布时间】:2020-09-27 16:37:55
【问题描述】:

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

输入图片:

下面是我的代码:

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)

【问题讨论】:

  • 对不起,我没有机会早点回复您,但我看到了您的额外细节,但它失败了。这对找出我的答案的问题很有帮助。

标签: python opencv crop face-recognition dlib


【解决方案1】:

DeepFace 封装了许多人脸检测库。此外,它在背景中应用人脸对齐。你可以在一行代码中检测到人脸。

#!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)

【讨论】:

    【解决方案2】:

    更新:缩放后超出边界框将无法正常工作。

    代码:

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

    图片:

    方法:

    获取给定区域的中心点(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

    【讨论】:

      猜你喜欢
      • 2018-03-07
      • 2015-06-17
      • 2018-07-08
      • 1970-01-01
      • 2011-11-14
      • 2017-02-21
      • 1970-01-01
      • 2014-04-28
      • 2020-12-26
      相关资源
      最近更新 更多