Выравнивание лиц в Python с помощью детектора лиц DNN

Я пытаюсь сделать код выравнивания лица на Python. Я слежу за этой статьей, но в этой статье для распознавания лиц используется dlib. Ниже приведен исходный код:

from imutils.face_utils import FaceAligner
from imutils.face_utils import rect_to_bb
import argparse
import imutils
import dlib
import cv2

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
fa = FaceAligner(predictor, desiredFaceWidth=256)

image = cv2.imread('images\\1.jpg')

image = imutils.resize(image, width=300)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

rects = detector(gray, 2)

for rect in rects:
    (x, y, w, h) = rect_to_bb(rect)
    faceOrig = imutils.resize(image[y:y + h, x:x + w], width=256)

    faceAligned = fa.align(image, gray, rect)  # Here we get the aligned face

У меня есть изображения лиц, которые не распознаются детектором лиц dlib. Поэтому я модифицирую приведенный выше код и использую распознавание лиц DNN. Ниже мой код:

from imutils.face_utils import FaceAligner
from imutils.face_utils import rect_to_bb
import argparse
import imutils
import dlib
import cv2

protoPath = "deploy.prototxt"
modelPath = "res10_300x300_ssd_iter_140000.caffemodel"
detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)

fa = FaceAligner(predictor, desiredFaceWidth=256)

image = cv2.imread('images\\1.jpg')
image = imutils.resize(image, width=300)

(h, w) = image.shape[:2]
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
imageBlob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0), swapRB=False, crop=False)

detector.setInput(imageBlob)
detections = detector.forward()

for i in range(0, detections.shape[2]):
    confidence = detections[0, 0, i, 2]

    if confidence > 0.5:
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")
    
        face = image[startY:endY, startX:endX]
        gray = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)
        r = dlib.rectangle(int(startX), int(startY), int(endX), int(endY))
        
        faceAligned = fa.align(face, gray, r)

Но в приведенном выше коде faceAlignedвсе нули и, следовательно, пустое изображение. Я не уверен, что делаю не так. Кто-нибудь может указать на ошибку и помочь мне решить проблему. Пожалуйста помоги. Благодарность

3 ответа

Я рекомендую вам делать это в deepface. Он обертывает opencv, ssd, dlib и mtcnn для обнаружения и выравнивания лиц.

Функция detectFace применяет обнаружение и выравнивание в фоновом режиме соответственно.

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

Кроме того, вы можете применить обнаружение и выравнивание вручную.

from deepface.commons import functions
img = functions.load_image("img.jpg")
backends = ['opencv', 'ssd', 'dlib', 'mtcnn']

detected_face = functions.detect_face(img = img, detector_backend = backends[2])
plt.imshow(detected_face)

aligned_face = functions.align_face(img = img, detector_backend = backends[2])
plt.imshow(aligned_face)

processed_img = functions.detect_face(img = aligned_face, detector_backend = backends[2])
plt.imshow(processed_img)

Если вы собираетесь применить распознавание лиц, он также обрабатывает эти шаги предварительной обработки в фоновом режиме.

from deepface import DeepFace
DeepFace.verify("img1.jpg", "img2.jpg", detector_backend = 'dlib')

В репозитории dlib есть лучший предсказатель формы лица: «shape_predictor_68_face_landmarks_GTX.dat.bz2». Вы должны использовать его для повышения производительности.

Вы передаете обрезанные изображения лица и серого в fa.align(face, grey, r), как показано в первом коде, эти параметры должны быть полными изображениями и прямоугольниками. Вот полный пример:

      import numpy as np
import imutils
import dlib
import cv2

from imutils.face_utils import FaceAligner

protoPath = "path/to/deploy.prototxt.txt"
modelPath = "path/to/res10_300x300_ssd_iter_140000.caffemodel"
detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
predictor = dlib.shape_predictor("path/to/shape_predictor_68_face_landmarks.dat")

fa = FaceAligner(predictor, desiredFaceWidth=256)

image = cv2.imread('path/to/image.jpg')
image = imutils.resize(image, width=300)
cv2.imshow("image", image)
(h, w) = image.shape[:2]

rgb = image.copy()
grey = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY)
imageBlob = cv2.dnn.blobFromImage(rgb, 1.0, (300, 300), (104.0, 177.0, 123.0), swapRB=False, crop=False)

detector.setInput(imageBlob)
detections = detector.forward()

for i in range(0, detections.shape[2]):
    confidence = detections[0, 0, i, 2]

    if confidence > 0.5:
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")

        face = image[startY:endY, startX:endX]

        r = dlib.rectangle(int(startX), int(startY), int(endX), int(endY))
        faceAligned = fa.align(rgb, grey, r)
        cv2.imshow("FACE ALIGNED {:d}".format(i), faceAligned)

k = cv2.waitKey(0)
if k == 27:
    cv2.destroyAllWindows()

Удачи.

Другие вопросы по тегам