【问题标题】:OpenCV/JavaCV face recognition - Very similar confidence valuesOpenCV/JavaCV 人脸识别 - 非常相似的置信度值
【发布时间】:2012-07-04 03:15:09
【问题描述】:

我将解释我正在尝试做什么,因为它似乎与理解我的问题有关。

我目前正在尝试根据数据库中的已知图片对走到摄像机前的人进行面部识别。

这些已知照片是从识别智能卡(仅包含一张正面照片)或来自社交网络的正面个人资料照片中收集的。从我目前阅读的内容来看,似乎要获得良好的人脸识别,需要大量的训练图像(50+)。因此,由于我收集的图像很少,无法创建可靠的训练集,因此我尝试使用我的实时相机帧捕获(目前使用 150 个)作为训练集,并将之前收集的识别图片作为测试集。我不确定我的尝试是否正确,所以如果我搞砸了,请告诉我。

所以,问题在于,假设我从智能卡中获得了 5 张已识别的图片,我尝试使用相机捕获的 150 帧作为训练集来进行人脸识别。在尝试识别时,5 个测试面中的每一个的置信度值都非常相似,这使得整个程序毫无用处,因为我无法准确识别任何人。通常,使用不同的相机捕捉作为训练,我从随机人的照片中获得的置信度值高于我自己的照片。

如果你能给我任何帮助,我将不胜感激,因为我在这里不知所措。

谢谢。

注意:我使用 OpenCV 的 JavaCV 包装器来制作我的程序,以及包中包含的 haarcascades。特征脸是使用的算法。

【问题讨论】:

  • 不清楚您正在针对哪些数据训练哪些模型...?
  • 怎么回事?如果我正确理解了您的问题,我将在训练集中使用灰度、均衡、裁剪的人脸图像。也使用与测试集相同类型的图像

标签: java opencv javacv eigenvector


【解决方案1】:

人脸识别

简介

我想添加这个。 libfacerec已被收录到官方OpenCV 2.4.2,详见:

这意味着如果您使用的是 OpenCV 2.4.2,那么您在 contrib 模块中有新的cv::FaceRecognizer。我知道最近添加了一个 Python 包装器(谢谢!),可能 Java 在写这篇文章时也被包装了。

cv::FaceRecognizer 附带大量文档,它将向您展示如何使用 大量 完整的源代码示例进行人脸识别:

如果您想了解可用的人脸识别算法(特征脸、Fisherfaces、局部二进制模式直方图)如何工作,请特别阅读Guide To Face Recognition with OpenCV。在那里,我解释了算法的工作原理并提到了它们的缺点:

少量图像的人脸识别

现在,当您的训练数据集较小时,您会遇到最初的人脸识别问题。我会给你写一个详尽的答案,所以它可能会帮助从谷歌来到这里的人。

实际上,当您的数据集中每个人的样本很少时,不应使用 Eigenfaces 和 Fisherfaces。 这些模型需要数据才能发挥作用,我怎么强调都不过分。越多越好。这些方法是基于估计数据的方差,所以给他们一些数据来估计你的模型!不久前,我在 AT&T 人脸数据库(使用 facerec framework)上进行了一个小测试,它显示了这些方法在每个人的图像数量不同时的性能:

我不会在这里写文章,也不会用详细的数学分析来支持这些数字。以前也做过,所以建议大家对这些图有疑问的看下(2),可以看到小训练数据集的PCA(Eigenfaces)和LDA(Fisherfaces)非常详细的分析。

所以我建议在小样本场景中使用局部二进制模式直方图 (3) 进行人脸识别。这些也包含在 OpenCV FaceRecognizer 中,并且已被证明在小型训练数据集上表现良好。如果将此与 TanTriggs 预处理 (4) 结合使用,您应该拥有一个非常强大的人脸识别模型。 TanTriggs 预处理是 Python 中的 8 行(左右),有关实现,请参见 https://github.com/bytefish/facerec/blob/master/py/facerec/preprocessing.py#L41。这应该很容易适应 Java(或者我可以使用 OpenCV 来实现它,如果人们要求的话)。

文学

  • (1) Belhumeur, PN, Hespanha, J. 和 Kriegman, D. Eigenfaces vs. Fisherfaces: Recognition Using Class Specific Linear Projection. IEEE Transactions on Pattern Analysis and Machine Intelligence 19, 7 (1997), 711–720。
  • (2) Martinez, A 和 Kak, A. PCA 与 LDA IEEE Transactions on Pattern Analysis and Machine Intelligence,Vol。 23,第 2 期,第 228-233 页,2001 年。
  • (3) Ahonen, T.、Hadid, A. 和 Pietikainen, M. 使用局部二进制模式进行人脸识别。 计算机视觉 - ECCV 2004 (2004), 469–481。李>
  • (4) Tan, X. 和 Triggs, B. 增强的局部纹理特征集用于在困难的光照条件下进行人脸识别。 IEEE Transactions on Image Processing 19 (2010), 1635–650。

【讨论】:

  • 非常感谢您的回答好先生,我对此感到有些绝望,因为即使在 lukaskrieger 的帮助下,使用我以前的方法也无法获得任何体面的结果它写了第一个答案(尽管我仍然感谢您的帮助!)。我将不得不尝试一下,我将在这里发布我能够达到的结果。再次感谢您的洞察力,非常感谢:)
  • 你好,我一直在尝试在 java 中找到一些示例代码/教程,因为它似乎已经被包装了 - code.google.com/p/javacv/source/browse/src/main/java/com/…。但是,我没有成功找到教程,或者自己做......后来有些沮丧,我尝试尝试使用c ++代码,因为它已经创建了示例,但我似乎无法得到它要运行,总是返回:编译 facerec_lbph.cpp 时函数 read_csv 中的“'imread' 未在此范围内声明”。
  • 显然包装在那里的界面不是OpenCV 2.4.2。 javacv 可能需要一些时间来适应。本地二进制模式直方图在 OpenCV 中可用,我昨天刚刚为这个问题编译了演示,它可以正常工作:stackoverflow.com/a/11399099/513875。请务必阅读此答案,如果您的问题仍然存在,您可能想在answers.opencv.org/questions 上提问或提交错误。错误不在stackoverflow.com 上提交,而是在code.opencv.org 上的错误跟踪器中提交。
  • 您好,我之前的问题已通过将我的 openCV 从 2.4.1 升级到 2.4.2 得到解决。我曾假设 2.4 之后的任何版本都可以工作。好的,现在我可以使用我的测试 csv 文件编译和测试您的示例代码 facerec_lbph.cpp,但结果仍然很糟糕。我相信这是因为我用于训练的图像是灰度、直方图均衡图像,而不是使用 TanTriggs。即使在阅读并尝试了 python 示例之后,我也无法将此预处理方法应用于我的图像。你能给我一些提示吗?请给我指明正确的方向吗?
【解决方案2】:

您想知道的是如何仅使用一张训练图像执行人脸识别。这是可能的,但也取决于您要分类的不同人员的数量。

当然不需要 50 多张训练图像。对于基本的人脸识别,您需要大约 50 张人脸来计算您的人脸空间(特征脸)。也许你把它和那个混在一起了。看到你的这张脸有很多变化(肤色、眼镜、形状......) 您可以从任何您喜欢的人脸数据库中获取这些人脸。 http://www.face-rec.org/ 列出了几个数据库并解释了不同的算法。

计算出人脸空间后,您可以使用尽可能多的人脸进行训练。在你的情况下,你只有一个。根据您想要分类的不同主题的数量,这可能已经奏效了。

如果你得到太多错误的分类,我会看看混合方法。混合方法将模板匹配算法(特征脸、渔人脸)与基于特征的算法相结合。在这种情况下,您获取第一个算法的输出并将眼睛、鼻子、眉毛、下巴形状等与您的测试脸相匹配。

简而言之:

  1. 使用 haarcascades 从每张图像中提取人脸
  2. 计算你的面部空间
  3. 为每张脸训练
  4. 要求人脸分类
  5. 进行最可能的分类并检查面部特征

如果你还没有找到,OpenCV 还有一个人脸识别库: https://github.com/bytefish/libfacerec

编辑: 我不会使用超过 10-15 个组件(特征脸)。

【讨论】:

  • 您好,感谢您的回复 :) 我也尝试过这种方式,使用的是 Cambridge_FaceDB,其中我的训练图像是这个人脸数据库中的所有图像加上我自己从智能卡收集的识别图片。我目前正在测试将 3 张收集到的图片插入到训练集中,测试集包含 3 张不同的图片,属于这些人。我对完全不同的人的信心水平仍然在 95 左右。 ps:我目前没有使用混合方法,但即使没有这种方法,我也期待得到不同的结果。还有什么可能导致这种情况?
  • 在我看来,您仍然将面部空间生成与您自己的面部训练混合在一起。您不需要将 3 个收集到的人脸添加到训练集中。仅使用数据库图像生成人脸空间。这使您可以将面投影到坐标系中。基本上,您将此转换应用于稍后要识别的对象的面孔(培训)。如果将变换应用于要识别的面,则将其投影到相同的坐标系中并与最近的邻居匹配(匹配)。暂时不考虑置信区间。
  • 好吧,我显然在这里搞砸了。所以,我将只使用下载的人脸数据库之一作为训练,它将生成平均图像和特征脸正确吗?下一部分是我不太明白的地方。我正在从相机中收集图像,我想看看相机前的这个人是否是一个已知的人(他的面部照片已从他的智能卡中检索到)。我之前所做的只是加载保存的训练数据,然后将测试图像投影到 PCA 子空间中,以找到最近的邻居,结果总是出错。
  • 现在你明白了。在子空间中,您需要预先分类的面孔。这些是你的训练面孔。当您将未知面孔投射到空间中并找到最近的邻居时,您将获得您的分类。
  • 这对我来说没有意义,许多使用 opencv 和 javacv 的人脸识别指南说要创建一个文本文件,指定训练图像的位置(他们想要识别的人的训练图像)。如果我只使用剑桥图像作为训练,我怎么能期望在它们中认出自己?它目前正在做的是尝试匹配并确定与测试面不对应的最近邻居...如果您熟悉它,我一直在关注 javaCV 包中的示例代码, “人脸识别.java”。
猜你喜欢
  • 2017-05-03
  • 2014-05-01
  • 1970-01-01
  • 2015-07-05
  • 1970-01-01
  • 2016-09-18
  • 2017-09-06
  • 2018-09-15
相关资源
最近更新 更多