当前位置: 首页 > 知识库问答 >
问题:

如何存储人脸的多个特征并找到距离?

仇建茗
2023-03-14

我正在做一个基于面部识别和验证的项目。我正在使用暹罗网络来获得人脸的128个向量(嵌入)。

我将人脸的编码/嵌入存储在数据库中,然后检查或说将传入人脸的编码与之前存储的编码匹配,以识别此人。

为了建立一个健壮的系统,我必须存储同一个人的多个编码。当我只使用了一个编码向量,并且匹配了:

人脸识别库(获取距离):

face_recognition.compare_faces( stored_list_of_encodings, checking_image_encodings )

这并不是一直有效,因为我只与单个编码进行了比较。为了使系统足以满足大多数情况,我想存储同一个人的至少3个编码,然后与新数据进行比较。

现在的问题是:如何存储同一个人的多个嵌入,然后比较距离?

我使用face_recognition作为特征提取的库和暹罗网络。

共有3个答案

习旻
2023-03-14

您可以将所有人脸嵌入存储在支持最近邻查询的数据库/数据结构中,然后对于任何给定的人脸,您应该找到匹配项,在数据库中获取其最近邻嵌入。通过k个最近邻及其到查询项的距离,您可以决定这张新面孔属于哪个人(如果它属于已知的人)。

您可以查看近似最近邻基准以获得可用选项。

记住,它们被称为近似值,所以你不会得到精确的结果,但如果你处理大量实体,这是你最好的选择。如果你不是这样,你可以使用sklearn中已经提供的暴力近邻解决方案来获得精确匹配。

阙佐
2023-03-14

您是否考虑过使用SVM分类器对人脸进行分类?因此,SVM分类器的输入将是大小为128的向量。然后,您可以编译一些属于单个人脸(在您的情况下为3个)的向量,并将其作为一个类来适应SVM。然后,您可以对不同的人脸(类)进行相同的操作。

然后,在预测人脸时,只需输入新的向量并运行

svm.predict([..])

我的项目有一个类似的用例,但我使用Facenet作为特性提取器。效果很好。

曹普松
2023-03-14

有多种方法可以做到这一点,我在人脸识别方面做了相当广泛的工作,我尝试了一些方法。您可以执行以下操作。

创建KNN分类器

这样做的方法是创建一个分贝排序,其中每个特征都有一个与之相关联的人名(在这种情况下,一个特征代表一个人的一张脸图像)。然后在比较时,您计算每个表示的查询特征的距离。您使用N个最小距离进行比较。然后您可以遍历N个距离,看看每个距离属于什么类,然后您可以使用最大出现的标签,这将是您的目标类。根据我的经验,虽然这不是非常健壮(虽然这完全取决于您的测试数据的类型,但我的测试数据与大量的野生图像有关,因此这不够健壮)

平均表示法

我使用的另一种方法是对每个人的表示取平均值。如果我有5张图像,我会取从这些表示中提取的5个表示的平均值或中位数。根据我的经验,中位数比平均值更有效。现在你将有一个与每个人相关的平均表示,你可以用每个平均表示取距离,距离最小的将是你的目标类。

簇表示

另一种方法是使用DBScan将表示形式集群到集群中,然后在运行时将查询代表分类到集群中,并将该集群中的多数类作为标签

根据我的经验,平均表现是最好的,但你最终需要多张图片,至少5张。但在我的情况下,我需要至少5个,因为我是迎合多个角度和什么没有。

不E:: SVM是一个坏方法,你限制你的数据库大小,每次你需要添加一个新的人到数据库,你需要为刚刚弹出的额外类训练一个新的SVM

此外,出于存储目的,您可以始终将其存储在JSON中

 类似资料:
  • 本文向大家介绍python3利用Dlib19.7实现人脸68个特征点标定,包括了python3利用Dlib19.7实现人脸68个特征点标定的使用技巧和注意事项,需要的朋友参考一下 0.引言 利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68点标定,利用OpenCv进行图像化处理,在人脸上画出68个点,并标明序号; 实现的68个特征点标

  • 当我尝试将我的maven项目部署到Glassfish 5时,我得到以下错误: [[FATAL]在索引0处找不到类型为public javax.ws.rs.core.response com.test.resources.AccountResource.AddProfilePicture(java.io.inputStream,org.glassfish.jersey.media.multipart

  • 问题内容: 在执行流操作时,将在中间/流水线操作期间创建具有不同特征的流(例如:SORTED / SIZED / DISTINCT / ORDERED)-掌握Lambda(第6章) 我们如何找出上述片段中提到的流的不同特征? 问题答案: 我想稍微延长一下亚述(绝对正确)。 首先 ,这些特征被实现为plain ,它是二进制表示形式。首先是全零,但是当您添加某个特性时,通过操作将该位设置为,通过该操作

  • 在执行流操作时,在中间/流水线操作期间,将创建具有不同特性的流(例如:排序/大小/不同/排序)--掌握lambda(第6章) 我们如何找出上面片段中提到的流的不同特征?

  • 我有一个设计问题,当使用类似的东西时: 我认为应该有一些更好的方法来实现这种参数化的特性。 我在std中没有找到好的示例(例如,在具有类似的关联类型的traits中没有实现)?

  • 我当前的Cucumber文件如下所示: 所以现在我想再添加几个场景,可能是在同一个文件中进行API测试。所以我想为此创建一个新特性,而不是使用Feature:Test Online application页面。这样我就不需要为API测试创建单独的特性文件。