news 2026/2/17 2:33:03

Retinaface+CurricularFace详细步骤:修改源码支持返回人脸坐标与置信度

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Retinaface+CurricularFace详细步骤:修改源码支持返回人脸坐标与置信度

Retinaface+CurricularFace详细步骤:修改源码支持返回人脸坐标与置信度

如果你用过Retinaface+CurricularFace这个镜像,可能会发现一个问题:它默认只输出两张图片的相似度分数,告诉你是不是同一个人。但在很多实际项目里,我们不仅想知道是不是同一个人,还想知道人脸在图片里的具体位置,以及检测的把握有多大。

比如,在做考勤系统时,你不仅需要识别员工,还需要记录人脸在监控画面中的位置,方便后续分析。或者在做身份核验时,你需要知道系统检测到的人脸框有多准,用置信度来过滤掉那些模糊不清、检测不准的图片。

今天这篇文章,我就带你一步步修改这个镜像的推理源码,让它不仅能告诉你“是不是同一个人”,还能返回每张图片里检测到的人脸坐标(x, y, w, h)和对应的置信度。整个过程就像给一个现成的工具加装几个实用的小零件,让它的功能更强大、更贴合我们的工程需求。

1. 理解现有流程:从图片到相似度

在动手修改之前,我们得先搞清楚原来的代码是怎么工作的。这样改起来心里才有底,不会把东西搞坏。

1.1 默认推理脚本的核心逻辑

镜像里预置的inference_face.py脚本,其工作流程可以概括为以下几步:

  1. 加载模型:同时加载RetinaFace人脸检测模型和CurricularFace人脸特征提取模型。
  2. 读取图片:根据命令行参数或默认路径,读取两张待比对的图片。
  3. 人脸检测与对齐:对每张图片,使用RetinaFace模型找出其中最大的人脸,然后根据关键点(如眼睛、鼻子、嘴角)进行“对齐”,把人脸转成正脸姿态。注意:这一步其实已经得到了人脸的坐标和置信度,但原来的代码没有把它们返回给我们。
  4. 特征提取:将对齐后的人脸图片,送入CurricularFace模型,提取出一个固定长度的特征向量(可以理解为人脸的“数字指纹”)。
  5. 相似度计算:计算两个特征向量之间的余弦相似度。
  6. 输出结果:将相似度与预设的阈值(默认0.4)比较,输出“同一人”或“不同人”的结论。

问题的关键就在第3步。RetinaFace在检测时,会输出人脸框的坐标和属于人脸的置信度,但这些信息在后续流程中被“消化”掉了,只用于内部的对齐操作,最终没有暴露给用户。

1.2 我们需要修改什么

我们的目标很明确:在完成人脸对齐和特征提取的同时,把RetinaFace检测到的原始信息——人脸框的左上角坐标(x1, y1)、右下角坐标(x2, y2)以及检测置信度(score)——也保存下来,并最终和相似度结果一起输出。

这不会影响原本的识别功能,只是让程序“多说”一些信息。

2. 环境准备与代码定位

修改代码前,确保你已经站在了正确的起跑线上。

2.1 进入工作环境

首先,启动你的Retinaface+CurricularFace镜像。当容器运行起来后,打开终端,执行以下命令进入工作目录并激活Python环境:

cd /root/Retinaface_CurricularFace conda activate torch25

这两步确保了所有依赖库(如PyTorch, ModelScope)都已就位,并且我们位于正确的代码目录下。

2.2 找到关键源码文件

我们需要修改的核心文件就是inference_face.py。用你喜欢的文本编辑器(如vim,nano)打开它:

vim inference_face.py

或者

nano inference_face.py

接下来,我们将在这个文件中进行手术刀式的精准修改。

3. 分步修改推理脚本

我们将按照代码的执行顺序,一步步添加返回人脸框和置信度的功能。请跟随我的步骤,仔细操作。

3.1 第一步:修改特征提取函数,让它“记住”检测结果

首先,我们需要找到负责单张图片处理的函数。通常,这个函数会完成“检测->对齐->提取特征”这一系列动作。在inference_face.py中,我们寻找一个类似get_featureprocess_image的函数。

假设我们找到了一个函数,它的大致结构如下:

def get_face_feature(self, img): # 使用RetinaFace检测人脸 dets = self.retinaface_detector.detect(img) # 假设dets包含检测结果 # 这里进行人脸对齐和裁剪 aligned_face = self.align_face(img, dets) # 提取特征 feature = self.recognition_model(aligned_face) return feature

我们的修改目标是:让这个函数在返回特征(feature)的同时,也返回检测到的人脸框和置信度。

修改后的函数可能长这样:

def get_face_feature_and_box(self, img): """ 处理单张图片,返回人脸特征、人脸框坐标和置信度。 如果未检测到人脸,返回None。 """ # 使用RetinaFace检测人脸 dets = self.retinaface_detector.detect(img) # 检查是否检测到人脸 if dets is None or len(dets) == 0: return None, None, None # 通常,dets是一个数组,每一行代表一个检测框:[x1, y1, x2, y2, score] # 我们取置信度最高的那个人脸(原逻辑是取最大人脸,这里用最高置信度近似) best_det = max(dets, key=lambda x: x[4]) # 假设第5列是置信度 # 解析坐标和置信度 x1, y1, x2, y2, score = best_det bbox = [int(x1), int(y1), int(x2), int(y2)] # 转换为整数 # 使用这个检测框进行人脸对齐和裁剪 aligned_face = self.align_face(img, best_det) # 提取特征 feature = self.recognition_model(aligned_face) # 返回特征、人脸框和置信度 return feature, bbox, score

关键改动说明:

  1. 函数重命名:将函数名改为get_face_feature_and_box,明确其新增的功能。
  2. 解析检测结果:从dets中提取出置信度最高的检测框,并解析出x1, y1, x2, y2, score
  3. 多返回值:函数现在返回三个值:特征向量feature、人脸框列表bbox、置信度score

注意:以上代码是一个通用示例。实际代码中,dets的数据结构、align_face函数的调用方式可能略有不同。你需要根据inference_face.py中的实际代码进行适配。核心思想是拦截并保存dets中的原始信息。

3.2 第二步:修改主推理逻辑,收集并输出新信息

接下来,我们需要修改调用上述函数的主逻辑部分。通常是main函数或脚本直接执行的代码块。

原来的逻辑可能是:

# 处理第一张图片 feature1 = model.get_face_feature(img1) # 处理第二张图片 feature2 = model.get_face_feature(img2) # 计算相似度 sim_score = cosine_similarity(feature1, feature2) print(f”相似度: {sim_score:.4f}“)

修改后的逻辑应该是:

# 处理第一张图片,同时获取框和置信度 feature1, bbox1, score1 = model.get_face_feature_and_box(img1) if feature1 is None: print(“错误:在第一张图片中未检测到人脸。”) return # 处理第二张图片,同时获取框和置信度 feature2, bbox2, score2 = model.get_face_feature_and_box(img2) if feature2 is None: print(“错误:在第二张图片中未检测到人脸。”) return # 计算相似度 sim_score = cosine_similarity(feature1, feature2) # 打印详细结果 print(“\n” + “=”*50) print(“人脸识别与检测详细结果”) print(“=”*50) print(f”图片1 - 人脸位置: {bbox1}“) print(f”图片1 - 检测置信度: {score1:.4f}“) print(f”图片2 - 人脸位置: {bbox2}“) print(f”图片2 - 检测置信度: {score2:.4f}“) print(f”\n人脸特征相似度: {sim_score:.4f}“) print(f”判定阈值: {args.threshold}“) if sim_score > args.threshold: print(“结论: 同一人”) else: print(“结论: 不同人”) print(“=”*50)

关键改动说明:

  1. 接收多返回值:调用修改后的函数,接收特征、框、置信度三个值。
  2. 增加错误处理:检查是否成功检测到人脸,避免后续步骤出错。
  3. 丰富输出信息:将人脸框坐标、检测置信度、相似度、阈值和最终结论清晰、结构化地打印出来,一目了然。

3.3 第三步:考虑将结果以结构化格式返回(进阶)

对于需要集成到其他系统的场景,纯文本输出可能不方便。我们可以考虑将结果封装成字典或JSON格式。

在主逻辑的最后,我们可以添加:

# 将结果组织成字典 result = { “image1”: { “bbox”: bbox1, “detection_score”: float(score1), # 转换为Python float类型 }, “image2”: { “bbox”: bbox2, “detection_score”: float(score2), }, “similarity”: float(sim_score), “is_same_person”: sim_score > args.threshold, “threshold”: args.threshold } # 如果需要,可以打印JSON格式 import json print(json.dumps(result, indent=2))

这样,其他程序就可以很方便地解析这个JSON字符串来获取所有信息了。

4. 测试修改后的脚本

修改完成后,最重要的一步就是测试,确保我们的改动没有引入错误,并且新功能工作正常。

4.1 使用默认图片测试

首先,运行最简单的命令,使用镜像自带的示例图片:

python inference_face.py

如果一切正常,你应该能看到比原来更丰富的输出,除了相似度,还包括两张图片各自的人脸框坐标和检测置信度。

4.2 使用自定义图片测试

找两张包含人脸的图片,最好是正面、清晰的。使用绝对路径运行脚本:

python inference_face.py -i1 /path/to/your/photo1.jpg -i2 /path/to/your/photo2.jpg

观察输出:

  • 人脸框坐标是否合理?(是否准确地框住了人脸)
  • 检测置信度是否在0到1之间?(通常越清晰、越正面,置信度越高,接近1)
  • 相似度判断是否符合你的预期?

4.3 测试边界情况

尝试一些有挑战性的图片,检验程序的健壮性:

  • 无人脸图片:输入一张风景照,程序应该给出明确的错误提示,而不是崩溃。
  • 多人脸图片:输入一张合影。根据我们的修改,程序会选择置信度最高的那张脸。你需要确认这个逻辑是否符合你的应用场景。如果不符合,你可以回头修改get_face_feature_and_box函数,改为选择面积最大((x2-x1)*(y2-y1))的脸,这与原镜像“检测最大人脸”的逻辑更一致。

5. 修改总结与应用建议

回顾一下,我们通过三个主要步骤增强了Retinaface+CurricularFace镜像的功能:

  1. 解剖流程:理解了原脚本“检测->对齐->特征提取->比对”的流水线,并定位了信息丢失的环节(检测结果未被保存)。
  2. 手术修改:修改了特征提取函数,使其在内部流转检测结果的同时,也将关键信息(坐标、置信度)返回给调用者。
  3. 丰富输出:在主逻辑中收集这些新信息,并以清晰、结构化(甚至机器可读的JSON)格式输出。

5.1 应用场景拓展

修改后的脚本,其应用场景得到了显著扩展:

  • 考勤打卡+区域统计:不仅知道谁打卡了,还能知道他在监控画面的哪个区域出现最频繁,用于优化摄像头布局或分析热点区域。
  • 身份核验质量控制:通过检测置信度,可以过滤掉质量太差的图片(如置信度低于0.9),要求用户重拍,从而提高核验的整体通过率和安全性。
  • 人脸追踪初始化:在视频流中,第一帧检测到的人脸框和置信度可以作为人脸追踪算法的初始状态,实现检测与追踪的平滑衔接。
  • 数据标注辅助:可以批量处理图片,输出人脸框坐标,为人脸数据集标注提供初步的、可供人工校验的参考线。

5.2 后续优化方向

如果你还想更进一步,这里有几个方向:

  • 返回多张人脸信息:修改逻辑,返回图片中检测到的所有人脸(而不仅仅是置信度最高的那个)的特征、坐标和置信度,实现一张图片内的多人物识别。
  • 集成可视化:使用OpenCV在原始图片上绘制出检测到的人脸框,并标注上置信度,将结果保存为新图片,直观又实用。
  • 封装成API服务:使用Flask或FastAPI将修改后的推理代码包装成一个HTTP API服务,方便通过网络调用。

获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/16 22:17:34

Qwen3-ASR-1.7B模型蒸馏实战:打造轻量级语音识别

Qwen3-ASR-1.7B模型蒸馏实战:打造轻量级语音识别 1. 为什么需要模型蒸馏 语音识别模型越强大,参数量往往越大。Qwen3-ASR-1.7B在多个评测中达到开源SOTA水平,但1.7B的参数量对很多实际场景来说还是太重了。比如在边缘设备上部署、做高并发实…

作者头像 李华
网站建设 2026/2/14 9:40:17

DeepChat自动化测试脚本生成:从自然语言到可执行代码

DeepChat自动化测试脚本生成:从自然语言到可执行代码 1. 测试工程师的日常困境 你有没有过这样的经历:刚开完需求评审会,产品经理甩过来一份密密麻麻的测试场景文档,里面写着“用户登录后点击购物车图标,检查商品数量…

作者头像 李华
网站建设 2026/2/14 1:52:54

granite-4.0-h-350m实战案例:Ollama部署后对接Python API调用全流程

granite-4.0-h-350m实战案例:Ollama部署后对接Python API调用全流程 想快速上手一个轻量级、功能强大的AI模型,但又担心部署复杂、资源消耗大?今天,我们就来聊聊如何用Ollama轻松部署Granite-4.0-H-350M模型,并把它变…

作者头像 李华
网站建设 2026/2/14 9:28:56

IndexTTS-2-LLM部署教程:WebUI+API双模式快速上手指南

IndexTTS-2-LLM部署教程:WebUIAPI双模式快速上手指南 1. 为什么你需要这个语音合成工具 你有没有遇到过这些情况: 想把一篇长文章转成音频,方便通勤时听,但试了几个工具,声音生硬、断句奇怪,听着像机器人…

作者头像 李华
网站建设 2026/2/11 1:46:52

万物识别-中文镜像实战教程:3步部署通用物体识别Gradio服务

万物识别-中文镜像实战教程:3步部署通用物体识别Gradio服务 你是不是也遇到过这样的问题:手头有一堆商品图、产品样机照、现场实拍图,想快速知道图里有什么?不是要精确到品种的农业识别,也不是要区分几十种工业零件&a…

作者头像 李华