有没有办法在使用 dlib 检测面部标志后选择面部的特定点?

Posted

技术标签:

【中文标题】有没有办法在使用 dlib 检测面部标志后选择面部的特定点?【英文标题】:Is there a way to select a specific point at the face after detecting facial landmarks using dlib? 【发布时间】:2021-07-25 11:01:18 【问题描述】:

我正在使用 Dlib 的 68 点人脸界标预测器,它有 68 个点标记在人脸的各个区域,如下图所示:

我已经设法从预测的地标中访问特定点,例如,我可以通过以下方式选择唇角处的点,该点是面部地标预测器中的第 48 个点 ' 导入简历2 导入 dlib 从 google.colab.patches 导入 cv2_imshow

p = "path_to_shape_predictor_68_face_landmarks.dat"
img= cv2.imread('Obama.jpg')
gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(p)
face = detector(gray)
# Get the shape using the predictor
landmarks=predictor(gray, face)

# Defining x and y coordinates of a specific point
x=landmarks.part(48).x
y=landmarks.part(48).y
# Drawing a circle
cv2.circle(img, (x, y), 6, (0, 0, 255), -1)
cv2_imshow(img)'

它会生成一个在指定区域上绘制一个红色小圆圈的图像。然而;如果我想选择一个不属于地标模型的 68 个点的点,我该如何获得它?

这张图会详细说明:

红色圆圈表示我使用代码访问的点,蓝色圆圈表示所需的点。

【问题讨论】:

定义要检测的点。你的意思是像你用鼠标点击一个点,你需要得到那个点的坐标吗? 我需要从给定的面部图像中提取面部的一部分,因此我需要指定用于提取特定区域的掩蔽函数的坐标。 试试 google face-mesh google.github.io/mediapipe/solutions/face_mesh.html,它提供了 468 个面部关键点。 【参考方案1】:

我可能会向您建议几种解决方案:

1- 简单的方法是使用三角学和几何学,例如计算左眼的瞳孔:

pupil_x = int((abs(landmarks.part(39).x + landmarks.part(36).x)) / 2) # The midpoint of a line Segment between eye's corners in x axis
pupil_y = int((abs(landmarks.part(39).y + landmarks.part(36).y)) / 2) # The midpoint of a line Segment between eye's corners in y axis
pupil_coordination = (pupil_x, pupil_y)

完整代码:

import cv2
import dlib

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_81_face_landmarks.dat")

img = cv2.imread("test.jpg")
(h, w, _) = img.shape
h2 = 600
w2 = int(h2 * h / w)
img = cv2.resize(img , (h2, w2))
img = cv2.flip(img , 1)
gray = cv2.cvtColor(img , cv2.COLOR_BGR2GRAY)
faces = detector(gray)
face = faces[0]
landmarks = predictor(gray, face)

pupil_x = int((abs(landmarks.part(39).x + landmarks.part(36).x)) / 2)
pupil_y = int((abs(landmarks.part(39).y + landmarks.part(36).y)) / 2)
pupil_coordination = (pupil_x, pupil_y)

cv2.circle(img, pupil_coordination, 6, (0, 0, 255), -1)
cv2.imshow('Show', img )
cv2.waitKey(0)
cv2.destroyAllWindows()

2- 其他解决方案是使用更大的面部标志模型,请查看: 81 Facial Landmarks Shape Predictor

3- 困难的方法是重新训练和自定义您自己的形状检测器:Train a face landmarking model

对于地标索引,我使用了以下参考: Face reference points

【讨论】:

以上是关于有没有办法在使用 dlib 检测面部标志后选择面部的特定点?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 OpenCV2 检测面部标志

当头部的滚动角度不在 -30 到 30 度之间时,dlib 68 面部标志点不准确

人脸检测进阶:更快的5点面部标志检测器

使用 dlib 面部标志裁剪面部

为啥 dlib 面部地标检测器会抛出 RuntimeError?

使用 dlib 检测眼睛地标