如何存储面部的多个特征并找到距离?

How to store multiple features for face and find distance?

我正在做一个基于面部识别和验证的项目。我正在使用 Siamese 网络来获取面部的 128 向量 ( Embeddings )。

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

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

匹配时

来自 face_recognition 库(获取距离):

face_recognition.compare_faces( stored_list_of_encodings, checking_image_encodings )

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

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

我正在使用 face_recognition 作为库和 Siamese Network 进行特征提取。

您是否考虑过使用 SVM classifier 来 class 化面部?所以 SVM classifier 的输入将是大小为 128 的向量。然后你可以编译一些属于一个人的脸的向量(在你的例子中是 3 个)并将它作为 SVM 拟合一个class。然后,您可以对不同的面孔执行相同的操作 (classes)。

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

svm.predict([..])

我的项目有一个类似的用例,但我使用的是 Facenet 作为特征提取器。完美运行。

您可以将所有人脸嵌入存储在支持最近邻查询的 database/datastructure 中,然后对于您应该找到匹配项的任何给定人脸,在数据库中获取它的最近邻嵌入。有了 k 个最近的邻居和他们到查询项的距离,你可以确定这张新面孔属于哪个人(如果它属于已知的人)。

您可以查看 Approximate Nearest Neighbor Benchmark 以了解可用选项。

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

有多种方法可以解决这个问题,我在人脸识别方面的工作相当广泛,并且尝试了一些方法。您可以执行以下一些操作。

创建一个 KNN class生成器

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

平均表示

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

集群表示

另一种方法是使用 DBScan 将表示聚类到聚类中,然后在运行时 class 将查询代表验证到聚类中,并将该聚类中的大多数 class 作为标签

根据我的经验,平均表现是最好的,但你最终需要多张图片,我认为至少需要 5 张。但就我而言,我至少需要 5 个,因为我要迎合多个角度,而不是什么。

注意 :: SVM 是一种糟糕的方法,你限制了你的数据库大小,每次你需要向数据库中添加一个新人时,你都需要训练一个新 SVM 用于刚刚弹出的额外 class

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