ONNX 模型库
返回模型

说明文档

模型卡片

这是一个面部识别模型,可从对齐的人脸图像中提取面部特征向量。

此模型卡片旨在作为新模型的基础模板。它是使用此原始模板生成的。

模型详情

模型描述

  • 开发者: Martin Knoche
  • 资助方 [可选]: 慕尼黑工业大学
  • 分享者 [可选]: Martin Knoche
  • 模型类型: 卷积神经网络
  • 许可证: 原始作品:

MIT 许可证

版权所有 (c) 2022 Zhong Yaoyao

特此免费授予任何获得本软件及相关文档文件("软件")副本的人不受限制地处置本软件的权利,包括不受限制地使用、复制、修改、合并、发布、分发、再许可和/或出售本软件副本的权利,以及再授权被配发了本软件的人如上的权利,须在下列条件下:

上述版权声明和本许可声明应包含在本软件的所有副本或实质性成分中。

本软件按"原样"提供,不提供任何形式的担保,明示或暗示,包括但不限于适销性、特定用途适用性和非侵权性的担保。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权行为还是其他方面,由软件或软件的使用或其他交易引起、由此产生或与之相关。

代码修改、微调等也采用 MIT 许可证:

MIT 许可证

版权所有 (c) 2023 Martin Knoche

特此免费授予任何获得本软件及相关文档文件("软件")副本的人不受限制地处置本软件的权利,包括不受限制地使用、复制、修改、合并、发布、分发、再许可和/或出售本软件副本的权利,以及再授权被配发了本软件的人如上的权利,须在下列条件下:

上述版权声明和本许可声明应包含在本软件的所有副本或实质性成分中。

本软件按"原样"提供,不提供任何形式的担保,明示或暗示,包括但不限于适销性、特定用途适用性和非侵权性的担保。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权行为还是其他方面,由软件或软件的使用或其他交易引起、由此产生或与之相关。

模型来源

用途

使用该模型从任意对齐的人脸图像中提取面部特征向量。然后,您可以将该向量与其他面部特征向量进行比较,以判断是否为同一人。

直接使用

该模型可在 ONNX-Runtime 环境中使用。

model = rt.InferenceSession("FaceTransformerOctupletLoss.onnx", providers=rt.get_available_providers())
embedding = model.run(None, {"input_image": input_image})[0][0]

input_image 变量

  • 尺寸:112x112x3
  • 通道:应为 RGB 格式
  • 类型:float
  • 数值:介于 0 到 255 之间

embedding 变量

  • 维度:512
  • 类型:float

偏差、风险和局限性

该模型最初是在 MS1M 数据集上训练并微调的。因此,请查看 MS1M 数据集以了解偏差和风险。

如何开始使用该模型

使用以下代码开始使用该模型:

import numpy as np
import onnxruntime as rt
import mediapipe as mp
import cv2
import os
import time
from skimage.transform import SimilarityTransform


# ---------------------------------------------------------------------------------------------------------------------
# 初始化

# 对齐用的目标关键点坐标(训练中使用)
LANDMARKS_TARGET = np.array(
    [
        [38.2946, 51.6963],
        [73.5318, 51.5014],
        [56.0252, 71.7366],
        [41.5493, 92.3655],
        [70.7299, 92.2041],
    ],
    dtype=np.float32,
)

# 初始化人脸检测器(例如 Mediapipe)
FACE_DETECTOR = mp.solutions.face_mesh.FaceMesh(
    refine_landmarks=True, min_detection_confidence=0.5, min_tracking_confidence=0.5, max_num_faces=1
)

# 初始化人脸识别模型(FaceTransformerOctupletLoss)
FACE_RECOGNIZER = rt.InferenceSession("FaceTransformerOctupletLoss.onnx", providers=rt.get_available_providers())


# ---------------------------------------------------------------------------------------------------------------------
# 人脸采集

# 使用网络摄像头捕获一帧并保存到磁盘
if not os.path.exists("img.jpg"):
    cap = cv2.VideoCapture(1) # 打开网络摄像头
    time.sleep(2) # 等待摄像头预热
    
    if not cap.isOpened():
        raise IOError("无法打开网络摄像头")
    
    ret, img = cap.read() # 捕获一帧
    if ret:
        cv2.imwrite("img.jpg", img) # 保存该帧
else:
    img = cv2.imread("img.jpg") # 从磁盘读取该帧


# ---------------------------------------------------------------------------------------------------------------------
# 人脸检测

# 使用人脸检测器处理图像
result = FACE_DETECTOR.process(img)

if result.multi_face_landmarks:
    # 选择 5 个关键点(眼睛中心、鼻尖、左嘴角、右嘴角)
    five_landmarks = np.asarray(result.multi_face_landmarks[0].landmark)[[470, 475, 1, 57, 287]]

    # 提取感兴趣的关键点的 x 和 y 坐标
    landmarks = np.asarray(
        [[landmark.x * img.shape[1], landmark.y * img.shape[0]] for landmark in five_landmarks]
    )

    # 提取所有关键点的 x 和 y 坐标
    all_x_coords = [landmark.x * img.shape[1] for landmark in result.multi_face_landmarks[0].landmark]
    all_y_coords = [landmark.y * img.shape[0] for landmark in result.multi_face_landmarks[0].landmark]

    # 计算人脸的边界框
    x_min, x_max = int(min(all_x_coords)), int(max(all_x_coords))
    y_min, y_max = int(min(all_y_coords)), int(max(all_y_coords))
    bbox = [[x_min, y_min], [x_max, y_max]]

else:
    print("未检测到人脸")
    exit()


# ---------------------------------------------------------------------------------------------------------------------
# 人脸对齐

# 使用 5 个关键点对齐图像
tform = SimilarityTransform()
tform.estimate(landmarks, LANDMARKS_TARGET)
tmatrix = tform.params[0:2, :]
img_aligned = cv2.warpAffine(img, tmatrix, (112, 112), borderValue=0.0)

# 保存到磁盘
cv2.imwrite("img2_aligned.jpg", img_aligned)


# ---------------------------------------------------------------------------------------------------------------------
# 人脸识别

# 使用 onnxruntime 推理人脸嵌入
input_image = (np.asarray([img_aligned]).astype(np.float32)).clip(0.0, 255.0).transpose(0, 3, 1, 2)
embedding = FACE_RECOGNIZER.run(None, {"input_image": input_image})[0][0]

print("嵌入向量:", embedding)

# 如果您有多张人脸图像的嵌入向量 - 您可以计算它们之间的余弦距离,并根据阈值区
# 分不同或相同的人。例如,如果余弦距离小于 0.5,则两张图像是同一个人,
# 否则是不同的人。余弦距离越低,两张图像越相似。余弦距离是 0 到 2 之间的值,
# 其中 0 表示两张图像完全相同,2 表示两张图像完全不同。

# ---------------------------------------------------------------------------------------------------------------------
# 可视化

# 在图像副本上绘制边界框
img_draw = img.copy()
cv2.rectangle(img_draw, (bbox[0][0], bbox[0][1]), (bbox[1][0], bbox[1][1]), (255, 0, 0), 2)

# 在图像上显示检测到的人脸
cv2.imshow("img", img_draw)
cv2.waitKey(0)

# 显示对齐后的图像
cv2.imshow("img", img_aligned)
cv2.waitKey(0)

另请参阅 main.py 以开始使用该模型。

评估

测试数据、因素和指标

测试数据

指标

准确率 [%]

结果

LFW CALFW CPLFW MLFW XQLFW
99.73 94.93 91.58 85.63 95.12

引用

BibTeX:

@inproceedings{knoche2023octuplet,
  title={Octuplet loss: Make face recognition robust to image resolution},
  author={Knoche, Martin and Elkadeem, Mohamed and H{\\"o}rmann, Stefan and Rigoll, Gerhard},
  booktitle={2023 IEEE 17th International Conference on Automatic Face and Gesture Recognition (FG)},
  pages={1--8},
  year={2023},
  organization={IEEE}
}

模型卡片作者

Martin Knoche

模型卡片联系方式

Martin.Knoche@tum.de

Martlgap/FaceTransformerOctupletLoss

作者 Martlgap

↓ 0 ♥ 1

创建时间: 2023-11-24 22:49:45+00:00

更新时间: 2023-11-27 17:09:46+00:00

在 Hugging Face 上查看

文件 (5)

.gitattributes
FaceTransformerOctupletLoss.onnx ONNX
LICENSE
README.md
main.py