无法使用 OpenCV2 检测面部标志

Posted

技术标签:

【中文标题】无法使用 OpenCV2 检测面部标志【英文标题】:Unable to detect facial landmarks using OpenCV2 【发布时间】:2021-04-26 13:03:47 【问题描述】:

我开发了一个脚本,使用dlibcv2 在该图像中有一张脸的图像上绘制面部标志。这是脚本;

import cv2
import dlib

img_path = 'landmarks.png'
detector = dlib.get_frontal_face_detector()

shape_predictor = 'shape_predictor_68_face_landmarks.dat'
predictor = dlib.shape_predictor(shape_predictor)


count = 1
ready = True
while ready:
    frame = cv2.imread("demo.jpg")
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = detector(gray)
    for face in faces:
        x1 = face.left()
        y1 = face.top()
        x2 = face.right()
        y2 = face.bottom()
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 3)

        landmarks = predictor(gray, face)

        for n in range(0, 68):
            x = landmarks.part(n).x
            y = landmarks.part(n).y
            cv2.circle(frame, (x, y), 4, (255, 0, 0), -1)

    cv2.imshow("Frame", frame)
    cv2.waitKey(0)
    ready = False

现在,这让我发疯了。当我尝试从谷歌下载任何图像(带或不带掩码)来测试它时,这个脚本工作正常。同样,您可以看到这些结果,例如,

但是当我尝试以下这些图像时,它什么也没做。

我在互联网上进行了几次搜索,但没有找到任何符合当前目的的东西。

甚至,我已经尝试过组合

cv2.CascadeClassifier("haarcascade_frontalface_default.xml") eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml') m_cascade = cv2.CascadeClassifier('haarcascade_mcs_mouth.xml')

我还查看了以下有用的链接;

Face Bounding Box

Detect Face Landmarks in android (Even not same domain)

Landmarks detection

OpenCV2 Detect Facial Landmarks

但它也不适用于这些图像。 CV2 detector 通过脚本调试时显示一个空列表,例如:

我只想使用上面的图像绘制基准地标。我可以通过什么最好的解决方案?也许,我在cv2Dlib 中遗漏了一些东西,但无法获得所需的结果。

我还使用 Stack Overflow 极客 推荐的实现找到了 dlib置信度得分,例如;

import dlib

detector = dlib.get_frontal_face_detector()

img = dlib.load_rgb_image('demo.jpg')
dets, scores, idx = detector.run(img, 1, -1)
for i, d in enumerate(dets):
    print("Detection , score: , face_type:".format(
        d, scores[i], idx[i]))

这是上述第二行图像中第一张图像的置信度得分结果;

期待从任何优秀的人那里获得更好的研究。谢谢

【问题讨论】:

尝试使用 dlib 正面人脸检测器。它更健壮。pyimagesearch.com/2017/04/03/… @AmitayNachmani 感谢您的友好回复。先生,这是我为此目的而遵循的第一个教程,但这也不起作用。如果你能看到detector = dlib.get_frontal_face_detector() ,我现在也在我当前的脚本中使用它。 【参考方案1】:

首先,我可能会尝试看看您是否可以从 dlib 中获得置信度分数。我不确定置信度阈值是多少,但可能检测到低于限制的面部。来自dlib Git Repo,这是一个如何从检测中获得置信度的示例:

if (len(sys.argv[1:]) > 0):
    img = dlib.load_rgb_image(sys.argv[1])
    dets, scores, idx = detector.run(img, 1, -1)
    for i, d in enumerate(dets):
        print("Detection , score: , face_type:".format(
            d, scores[i], idx[i]))

或者,考虑另一个人脸检测器,例如像MobileNet SSD 人脸检测器这样的基于 CNN 的检测器。我没有使用过这个特定的模型,但我使用过类似的模型,比如Google TPU-based face detector model here,效果非常好。

【讨论】:

先生,我已根据您的要求更新了我的问题。请在这件事上帮助我。我也尝试过基于 CNN 的检测器,但它在当前用例中不起作用。当我尝试上面给定的图像时。它不会起作用。【参考方案2】:

下载“shape_predictor_68_face_landmarks.dat”链接: enter link description here

100% 工作代码试试这个:

import cv2
import dlib
import numpy as np

img= cv2.imread('Capture 8.PNG')
gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

p = "shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(p)
faces = detector(gray)

for face in faces:
  x1=face.left()
  y1=face.top()
  x2=face.right()
  y2=face.bottom()
  cv2.rectangle(img, (x1,y1), (x2,y2),(0,255,0),3)
  landmarks=predictor(gray, face)
  for n in range(0,68):
    x=landmarks.part(n).x
    y=landmarks.part(n).y
    cv2.circle(img, (x, y), 4, (0, 0, 255), -1)

cv2.imshow(img)

【讨论】:

阿里,我已经用模型图片测试过了,但是这段代码也不起作用。即使我已经从您提供的链接中下载了shape_predictor_68_face_landmarks.dat 文件。无论如何感谢您的回复。

以上是关于无法使用 OpenCV2 检测面部标志的主要内容,如果未能解决你的问题,请参考以下文章

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

在基于 JavaScript 的面部标志检测中查找所有点的坐标

人脸检测进阶:使用 dlibOpenCV 和 Python 检测眼睛鼻子嘴唇和下巴等面部五官

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

给定 dlib 的 68 点面部标志,确定它们有多好

图像处理中面部标志点的归一化