我只有一个 test1.jpg -它是原始图像,其中包含我们需要查找的面孔。
我的 test2.jpg 是要检查的图像。我们将需要在 test2.jpg 中检查 test1.jpg 的面孔,如果 test2.jpg 输出输出 true 中是否存在 test1.jpg 的面孔。
我还没有OpenCV及其新技术方面的经验。
我非常简单的代码:
# faces which we need find
known_image = cv2.imread('test1.jpg')
# some random image
unknown_image = cv2.imread('test2.jpg')
gray_known = cv2.cvtColor(known_image, cv2.COLOR_BGR2GRAY)
gray_unknown = cv2.cvtColor(unknown_image, cv2.COLOR_BGR2GRAY)
faceCascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
known_faces = faceCascade.detectMultiScale(
gray_known,
scaleFactor=1.27,
minNeighbors=5,
minSize=(10, 10),
flags = cv2.CASCADE_SCALE_IMAGE
)
print("Found known {0} faces!".format(len(known_faces)))
unknown_faces = faceCascade.detectMultiScale(
gray_unknown,
scaleFactor=1.27,
minNeighbors=5,
minSize=(10, 10),
flags = cv2.CASCADE_SCALE_IMAGE
)
print("Found unknown {0} faces!".format(len(unknown_faces)))
# BELLOW NOT CORRECT CODE. I DONT KNOW HOW I CAN DO LIKE THIS:
for face in known_faces:
if face in unknown_faces:
print(TRUE)
break
最佳答案
就目前而言,代码的主要问题在于,它期望面部补丁在两个不同的图像中是相同的。几乎可以肯定不是这种情况-即使一个仅仅是另一个的裁剪图像,如果级联分类器在一个图像中比另一个图像的左侧更靠近像素1个像素,结果也不相同。
级联分类器的结果是一组边界框,这些边界框应代表面部(有时会出现错误的检测结果)。然后,您需要在这些边界框中提取子图像,并使用某种比较技术来确定两个人脸图像是否相同。我将在下面讨论这些。
您的问题实际上有两个阶段,将它们区分开很重要,因为有两种方法可以解决这两个问题。
阶段1:人脸检测
这是实际上在图像中找到面部的问题。您的代码应该可以很好地处理-OpenCV的级联分类器是执行此操作的最常用方法之一(aligned face detector in DLib替代方法)。
阶段2:人脸识别
这是比较困难的部分。人脸识别技术可能相差很大,并且很多取决于情况。其中最准确的方法是使用deep learning module,因此,如果您的硬件可以完成任务,我建议您这样做。似乎代码实际上是implementation of OpenFace-我以前使用过它,并且有可能在很少的训练图像上获得准确的识别。我建议阅读链接的文章,以及DNN示例,因为代码可能太深而无法在此处介绍。
主要步骤如下:
DNN嵌入步骤是此处的较慢部分,但是如果您有GPU可用,它仍然应该非常高效。
如果您不是在进行直接的图像-图像比较,而是在寻找一组已知的面孔,而是可以训练一个现成的线性分类器(例如在您要寻找的实际人员上使用SVM),则可以使用此分类器您可以在图像中找到的特征 vector 上查看它们是否属于任何类别。
阶段2(a):无需深度学习的人脸识别
OpenCV还带有面部识别模块,该模块使用了更为经典的技术,这些技术往往更快,更便携,但会降低准确性。
有一个really good tutorial on it in the OpenCV documentation。同样,该代码太长了,无法直接发布到帖子中,但是该链接描述了3种面部检测方法。 Fisherfaces和Eigenfaces都依赖于查看同一张面孔的多个示例,并在较低维度的空间中对其进行建模,可以在其中比较它们的基本属性,而不是原始像素数据。
我不确定这两种方法中的哪一种都适合您的用例,因为每张脸只有一个示例。
使用本地二进制模式(LBP)直方图可能会为您提供更好的起点。 LBP是描述图像纹理细节的一种方法-在上面链接的教程中有更多信息。我将在这里再次给出一些基本步骤来帮助您入门:
注意:
使用单个图像的任何识别技术都容易出错。我还没有测试上述算法,但是在遵循这些教程之后,过去曾使用OpenFace,Fisherfaces和LBPH进行人脸识别,并发现它们可以很好地识别一些人脸示例。
关于python - Python + OpenCV人脸识别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55242252/