静态图片中的人脸是二维平面的,比较其中的人脸相似度应该怎么做呢?通常涉及以下几个核心步骤。

  • 1.人脸检测

  • 2.人脸关键点检测与对齐

  • 3.人脸特征提取

  • 4.计算特征向量相似度

    图片

    仅供交流,两人为小红书用户,相似度 0.703

第一步:人脸检测

目标:在图片中找出所有人脸的位置。

  • 操作

    使用人脸检测模型(如 MTCNN, Haar Cascades, 基于CNN的检测器等)对输入的每张图片进行分析。

  • 输出

    一个或多个包含人脸的边界框坐标 (x, y, width, height)

  • 重要性

    这是所有后续步骤的基础。如果检测失败,整个流程就无法进行。

  • 注意

    如果一张图片中检测到多张人脸,需要判断比较的是哪一张(一般检测最大人脸)。

第二步:人脸对齐

目标:将检测到的人脸进行几何变换,使其“摆正”,消除姿态(如侧脸、抬头、低头)和旋转带来的影响。

  • 操作
    1. 人脸关键点检测

      首先检测出人脸上的关键特征点,如眼睛、鼻子、嘴角等(通常是5点、68点或106点)。

    2. 仿射变换

      以关键点(通常是双眼的位置)为基准,计算一个变换矩阵,将人脸旋转并缩放到一个标准化的坐标系中。

  • 输出

    对齐后的、大小统一(例如 224x224 像素)的人脸图像。

  • 重要性

    对齐能显著提升后续特征提取的准确性和鲁棒性,是工业级系统中至关重要的一步。

第三步:人脸特征提取

目标:将对齐后的人脸图像转换成一个具有代表性和区分度的数学向量(即“特征向量”或“人脸Embedding”)。

  • 操作

    使用一个在大型人脸数据集上训练好的深度学习模型(如 ArcFace, FaceNet, VGGFace 等)。这个模型就像一个函数,输入一张人脸图片,输出一个高维向量(例如512维的浮点数向量)。

  • 输出

    两个特征向量,分别代表两张图片中的人脸。

  • 核心思想

    这个特征向量空间被设计为,同一个人不同图片的向量在空间中的“距离”很近,而不同人的向量“距离”很远。

    图片

    计算机能识别的人脸特征和人眼睛可能不太一样,上面的赛博面孔其实是作者通过Adobe firefly 生成的数字人脸,同样能被人脸识别程序识别 (仅供交流)

第四步:计算相似度

目标:计算两个特征向量之间的相似程度。

  • 操作

    使用特定的距离或相似度度量方法来比较两个向量。

    • 余弦相似度

      最常用的方法之一。它衡量的是两个向量在方向上的差异,忽略其长度。结果范围通常在 [-1, 1] 或 [0, 1],值越大越相似。

    • 欧氏距离

      计算空间中两点之间的直线距离。距离越接近0,表示两张脸越相似。

    • L2归一化 + 点积/欧氏距离

      在实际应用中,通常会先将特征向量进行L2归一化(使其模长为1),然后再计算点积(此时点积等于余弦相似度)或欧氏距离,这样能消除光照等因素的影响,使比较更稳定。

  • 输出

    一个具体的数值分数,代表两张人脸的相似度。

第五步:设定阈值与判断

目标:根据相似度分数得出最终结论——是否是同一个人。

  • 操作

    根据具体应用场景设定一个阈值。

    • 如果 相似度分数 >= 阈值,则判断为 同一个人

    • 如果 相似度分数 < 阈值,则判断为 不同的人

  • 阈值选择

    这个阈值不是固定的,需要通过大量实验来确定。在安全要求高的场景(如手机解锁),阈值会设得较高;在便利性为主的场景(如相册聚类),阈值可以稍低。


简单代码示例

import face_recognition

# 加载图片
image_a = face_recognition.load_image_file("person1.jpg")
image_b = face_recognition.load_image_file("person2.jpg")

# 第一步&第二步:检测人脸并提取特征向量(库内部自动完成了对齐)
encoding_a = face_recognition.face_encodings(image_a)
encoding_b = face_recognition.face_encodings(image_b)

iflen(encoding_a) == 0:
print("在 image_a 中未找到人脸!")
eliflen(encoding_b) == 0:
print("在 image_b 中未找到人脸!")
else:
# 取第一张检测到的人脸
    encoding_a = encoding_a[0]
    encoding_b = encoding_b[0]

# 第三步&第四步:计算相似度(使用欧氏距离)
# face_distance 实际上是计算归一化后向量的欧氏距离,距离越小越相似
    distance = face_recognition.face_distance([encoding_a], encoding_b)[0]
# 也可以将其转换为一个更直观的相似度分数(例如: 1 - distance)
    similarity_score = 1 - distance

print(f"人脸特征向量间的欧氏距离: {distance:.4f}")
print(f"转换后的相似度分数: {similarity_score:.4f}")

# 第五步:判断(这里以0.85为阈值示例,实际需要调整)
    threshold = 0.85
if similarity_score >= threshold:
print("判断为:同一个人")
else:
print("判断为:不同的人")

总结

比较两张人脸相似度的核心在于 将人脸图像转化为一个鲁棒的、可度量的数学特征向量。整个流程环环相扣,任何一步的失误都会影响最终结果。选择合适的人脸检测、对齐模型以及高质量的特征提取模型,是保证高精度的关键

FaceAISDK API iOS与Android平台详细接入(静态人脸对比API开放使用无限制 )

iOS SDK: https://github.com/FaceAISDK/FaceAISDK_iOS
Android:     https://github.com/FaceAISDK/FaceAISDK_Android

体验Android APK 下载 : https://www.pgyer.com/faceVerify

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐