news 2026/2/11 6:07:09

DamoFD人脸关键点检测实战:导出CSV坐标文件用于后续3D建模输入

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DamoFD人脸关键点检测实战:导出CSV坐标文件用于后续3D建模输入

DamoFD人脸关键点检测实战:导出CSV坐标文件用于后续3D建模输入

你是不是正在为3D建模准备人脸数据?有没有试过手动标注几十张人脸的五点坐标?那种反复点击、校准、保存的流程,既耗时又容易出错。其实,用DamoFD这个轻量级模型,几行代码就能自动完成人脸检测+关键点定位,并把结果导出成标准CSV格式——直接拖进Blender、Maya或者Unity里做面部绑定或表情驱动。

这篇文章不讲论文、不聊参数,只聚焦一件事:怎么把一张普通照片,变成3D建模可用的结构化坐标数据。整个过程不需要编译、不调CUDA版本、不改模型结构,镜像开箱即用,10分钟内跑通全流程。哪怕你刚接触Python,也能照着步骤拿到第一份带坐标的CSV文件。


1. 为什么选DamoFD做3D建模前期准备

很多人一听到“人脸关键点”,第一反应是MediaPipe或dlib——但它们要么依赖OpenCV版本兼容性,要么在低光照下漏检严重。而DamoFD(Face Detection & Landmark)是达摩院专为边缘部署优化的模型,0.5G大小,却能稳定输出五点关键点:左眼中心、右眼中心、鼻尖、左嘴角、右嘴角。这五个点,恰恰是3D建模中最基础、最通用的面部锚点。

它不是追求68点或106点的精细度,而是用极简结构换高鲁棒性:

  • 在侧脸、低头、戴口罩等常见干扰场景下,依然能准确定位;
  • 输出坐标是归一化后的浮点值(0~1范围),方便适配任意分辨率输入;
  • 推理速度快,单图平均耗时不到120ms(RTX 3060),适合批量处理上百张训练素材。

更重要的是,它的输出结构干净——没有多余字段、不嵌套JSON、不打包二进制,就是纯坐标数组。这意味着你不用写解析器,只要加三行代码,就能把它转成Excel打开就用的CSV。


2. 镜像环境快速上手:复制→激活→运行

镜像已预装全部依赖,但默认代码在系统盘/root/DamoFD,直接修改有风险。我们先把它安全迁移到工作区:

2.1 复制代码到可写目录

打开终端,执行:

cp -r /root/DamoFD /root/workspace/ cd /root/workspace/DamoFD

2.2 激活专用环境

conda activate damofd

此时终端提示符前会显示(damofd),说明环境已就绪。这个环境里已经装好了:

  • PyTorch 1.11.0 + CUDA 11.3(无需额外配置GPU)
  • ModelScope 1.6.1(自动加载模型权重)
  • OpenCV-Python、NumPy、Pandas(CSV导出必备)

注意:不要用pip installconda install额外安装包,所有依赖都已固化。强行升级可能破坏兼容性。


3. 修改代码:从显示图片到导出CSV

原镜像提供的DamoFD.pyDamoFD-0.5G.ipynb默认只做可视化——画框、标点、弹窗显示。我们要让它“干活”,也就是把关键点坐标存成CSV。

3.1 定位关键输出位置

打开DamoFD.py,找到类似这样的代码段(通常在推理循环末尾):

# 原始代码:仅打印坐标 print("Landmarks:", landmarks)

这里landmarks是一个形状为(5, 2)的NumPy数组,每行是[x, y],单位为像素(相对于输入图像宽高)。

3.2 插入CSV导出逻辑

print语句下方,添加以下四行(注意缩进对齐):

import pandas as pd df = pd.DataFrame(landmarks, columns=['x', 'y'], index=['left_eye', 'right_eye', 'nose', 'left_mouth', 'right_mouth']) csv_path = img_path.replace('.jpg', '_landmarks.csv').replace('.png', '_landmarks.csv') df.to_csv(csv_path, index=True) print(f" CSV已保存至:{csv_path}")

这段代码做了三件事:

  • 把5个点组织成带行列名的表格(index确保顺序固定,columns明确坐标含义);
  • 自动根据输入图片名生成同名CSV(如face.jpgface_landmarks.csv);
  • 支持.jpg.png后缀,其他格式可按需扩展。

3.3 验证路径与格式

确保你的图片放在/root/workspace/下,比如:

cp /root/examples/test_face.jpg /root/workspace/

然后修改DamoFD.py中的img_path

img_path = '/root/workspace/test_face.jpg'

4. 运行并检查CSV内容

执行命令:

python DamoFD.py

你会看到类似输出:

CSV已保存至:/root/workspace/test_face_landmarks.csv

用命令行快速查看内容:

cat /root/workspace/test_face_landmarks.csv

预期输出应为:

, x, y left_eye, 0.324, 0.418 right_eye, 0.672, 0.421 nose, 0.498, 0.583 left_mouth, 0.385, 0.726 right_mouth, 0.612, 0.729

第一列是点名称(保证3D软件能按名读取)
前两列是归一化坐标(0~1),可直接映射到UV空间
无空行、无BOM、无特殊字符——Excel双击即开

小技巧:如果需要像素坐标(比如导入Blender的Geometry Nodes),把landmarks替换成landmarks * [img_width, img_height]即可,代码里已有img.shape[1], img.shape[0]可直接调用。


5. Jupyter Notebook方式:交互式调试更直观

如果你习惯边看效果边调参,推荐用Notebook方式:

5.1 正确选择内核

  • 打开/root/workspace/DamoFD/DamoFD-0.5G.ipynb
  • 点击右上角内核选择器 → 选damofd(不是Python 3
  • 如果没看到damofd,重启Jupyter服务再试一次

5.2 在指定单元格插入导出代码

找到包含# 可视化结果的代码块,在plt.show()上方插入:

# 新增:导出CSV import pandas as pd df = pd.DataFrame(landmarks, columns=['x', 'y'], index=['left_eye', 'right_eye', 'nose', 'left_mouth', 'right_mouth']) csv_name = img_path.split('/')[-1].rsplit('.', 1)[0] + '_landmarks.csv' df.to_csv('/root/workspace/' + csv_name, index=True) print(f" 已生成:{csv_name}")

点击「Run All」后,不仅能看到画点效果图,还能立刻在左侧文件列表里找到新生成的CSV文件,双击即可在线预览。


6. 批量处理:一次导出百张图的坐标

单张图只是热身,实际建模需要多角度人脸数据。把上面的逻辑封装成批量脚本:

6.1 创建batch_export.py

/root/workspace/DamoFD/下新建文件:

touch batch_export.py

粘贴以下内容:

import os import cv2 import numpy as np import pandas as pd from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks # 初始化模型(只需一次) detector = pipeline(task=Tasks.face_detection, model='iic/cv_ddsar_face-detection_iclr23-damofd') # 设置图片目录 input_dir = '/root/workspace/faces/' output_dir = '/root/workspace/landmarks_csv/' os.makedirs(output_dir, exist_ok=True) for img_name in os.listdir(input_dir): if not img_name.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp')): continue img_path = os.path.join(input_dir, img_name) img = cv2.imread(img_path) if img is None: print(f" 跳过损坏图片:{img_name}") continue # 推理 result = detector(img) bboxes = result['boxes'] landmarks = result['keypoints'] # 只取置信度最高的一张脸(3D建模通常只需主视角) if len(bboxes) == 0: print(f"❌ 未检测到人脸:{img_name}") continue best_idx = np.argmax([box[-1] for box in bboxes]) best_landmarks = landmarks[best_idx] # shape: (5, 2) # 归一化到0~1(除以图像宽高) h, w = img.shape[:2] norm_landmarks = best_landmarks / [w, h] # 保存CSV df = pd.DataFrame(norm_landmarks, columns=['x', 'y'], index=['left_eye', 'right_eye', 'nose', 'left_mouth', 'right_mouth']) csv_path = os.path.join(output_dir, img_name.rsplit('.', 1)[0] + '_landmarks.csv') df.to_csv(csv_path, index=True) print(f" {img_name} → {os.path.basename(csv_path)}")

6.2 准备图片并运行

mkdir -p /root/workspace/faces/ # 把你的100张正脸/侧脸图放进去 cp /your/photos/*.jpg /root/workspace/faces/ python batch_export.py

运行结束后,/root/workspace/landmarks_csv/下将生成100个CSV文件,每个都严格遵循命名+结构规范。


7. CSV如何对接3D建模软件

导出的CSV不是终点,而是3D流程的起点。以下是三个主流软件的接入方式:

7.1 Blender:用Geometry Nodes读取

  • 添加一个「Object Info」节点 → 「Transform」→ 「Set Position」
  • 用「CSV Reader」插件(如 CSV Importer)导入CSV
  • x,y列映射到顶点位置(Z轴设为0)
  • 5个点自动生成空物体,后续可绑定骨骼或驱动Shape Keys

7.2 Maya:用Python脚本批量创建locator

import maya.cmds as cmds import pandas as pd df = pd.read_csv('/path/to/face_landmarks.csv', index_col=0) for idx, row in df.iterrows(): loc = cmds.spaceLocator(name=f'{idx}_loc')[0] cmds.setAttr(f'{loc}.tx', row['x'] * 10) # X放大10倍适配场景 cmds.setAttr(f'{loc}.ty', row['y'] * 10) cmds.setAttr(f'{loc}.tz', 0)

7.3 Unity:C#脚本动态加载

// 读取CSV后,用Vector3[]存储5个点 Vector3[] landmarks = new Vector3[5]; landmarks[0] = new Vector3(csvData["left_eye"]["x"], csvData["left_eye"]["y"], 0); // ... 其余点同理 // 传给SkinnedMeshRenderer或自定义Shader

关键提醒:所有软件都要求坐标系一致。DamoFD输出是OpenCV风格(原点在左上角),而Blender/Maya默认原点在左下角。若发现Y轴反向,把y列替换为1 - y即可。


8. 效果调优:让关键点更贴合3D需求

默认参数适合通用场景,但3D建模对精度更敏感。以下三个调整能显著提升可用性:

8.1 提升检测稳定性

原代码中if score < 0.5: continue是过滤低置信度框。建模素材常有模糊或小脸,建议改为:

if score < 0.35: # 放宽阈值,避免漏检 continue

8.2 强制单脸输出(避免多脸干扰)

在批量脚本中,我们已取置信度最高的脸。若想强制只处理主脸,可加裁剪逻辑:

# 获取最高分bbox,裁剪出人脸区域再测关键点 x1, y1, x2, y2, _ = bboxes[best_idx] face_img = img[int(y1):int(y2), int(x1):int(x2)] result = detector(face_img) # 在裁剪图上重跑,关键点更精准

8.3 坐标平滑处理(对抗抖动)

对视频帧序列建模时,单帧关键点可能跳变。加一个简单均值滤波:

# 假设landmarks_list是连续10帧的list smoothed = np.mean(landmarks_list[-5:], axis=0) # 最近5帧平均

9. 总结:一条从照片到3D的高效链路

回顾整个流程,你其实只做了三件事:
1⃣复制代码到工作区——避开系统盘风险;
2⃣加四行CSV导出代码——把内存数组变成结构化文件;
3⃣批量跑通100张图——用现成脚本替代手动操作。

没有模型训练、没有环境踩坑、没有格式转换工具链。DamoFD的价值,不在于它有多“智能”,而在于它足够“可靠”——在你需要它的时候,稳稳输出那5个坐标点,不多不少,不偏不倚。

下一步,你可以:

  • 把CSV喂给Blender的驱动器,自动生成眨眼动画;
  • 用5点反推头部姿态角,做AR实时跟踪;
  • 结合深度图,把2D关键点升维成3D点云……

技术本身没有边界,限制你的,往往只是第一步是否走得足够轻快。


获取更多AI镜像

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

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

LLaVA-v1.6-7B小白入门:三步搭建你的视觉聊天助手

LLaVA-v1.6-7B小白入门&#xff1a;三步搭建你的视觉聊天助手 1. 为什么你需要一个“能看懂图”的聊天助手&#xff1f; 你有没有过这样的时刻&#xff1a; 拍下一张商品标签&#xff0c;想立刻知道成分和禁忌&#xff1b;截图一份复杂表格&#xff0c;却要花十分钟手动整理…

作者头像 李华
网站建设 2026/2/9 7:39:22

Qwen2.5法律场景应用:合同生成系统部署实战案例

Qwen2.5法律场景应用&#xff1a;合同生成系统部署实战案例 1. 为什么选Qwen2.5-0.5B-Instruct做法律合同生成 很多人一听到“大模型做法律”&#xff0c;第一反应是&#xff1a;参数不够大&#xff0c;专业度够吗&#xff1f;但实际用下来你会发现&#xff0c;法律场景的合同…

作者头像 李华
网站建设 2026/2/10 22:34:30

Qwen2.5-7B-Instruct镜像免配置部署:中小企业AI应用快速落地方案

Qwen2.5-7B-Instruct镜像免配置部署&#xff1a;中小企业AI应用快速落地方案 1. 为什么中小企业需要一个“开箱即用”的大模型方案 你有没有遇到过这样的情况&#xff1a;公司想用大模型做智能客服、自动生成产品文案、或者把内部文档变成问答系统&#xff0c;但一查技术方案…

作者头像 李华
网站建设 2026/2/10 0:32:07

Qwen3-Reranker-8B应用指南:构建高精度RAG检索增强系统

Qwen3-Reranker-8B应用指南&#xff1a;构建高精度RAG检索增强系统 在当前RAG&#xff08;Retrieval-Augmented Generation&#xff09;系统实践中&#xff0c;检索质量直接决定了最终回答的准确性与专业性。很多团队已经用上了向量数据库和基础嵌入模型&#xff0c;但发现“召…

作者头像 李华
网站建设 2026/2/10 11:50:15

Qwen3-4B多轮对话实战:从代码编写到文案创作全流程

Qwen3-4B多轮对话实战&#xff1a;从代码编写到文案创作全流程 1. 为什么选Qwen3-4B做纯文本对话&#xff1f;不是更大&#xff0c;而是更准、更快、更顺 你有没有试过这样的场景&#xff1a; 想让AI写一段产品介绍文案&#xff0c;等了5秒&#xff0c;页面还卡在“思考中”&…

作者头像 李华