点击上方“3D视觉工坊”,选择“星标”
干货第一时间送达
人脸3D点云提取网络
2019出现的一个可以在移动端实时运行的人脸3D表面提取模型-FaceMesh,被很多移动端AR应用作为底层算法实现人脸检测与人脸3D点云生成。相关的论文标题为:
《Real-time Facial Surface Geometry from Monocular Video on Mobile GPUs》
github有pytorch版本的实现地址如下:
https://github.com/thepowerfuldeez/facemesh.pytorch
已经提供了预训练模型文件pth,可以用Netron打开查看。它的输入与输出显示截图如下:
图-2
最终输出的点云数据是468个3D坐标人脸点云坐标,输入人脸的ROI区域,大小为192x192。使用Pytorch支持的脚本可以把该模型转换为ONNX格式模型,转换的脚本与代码如下:
from facemesh import FaceMeshimport torch net = FaceMesh()net.load_weights("facemesh.pth")torch.onnx.export(net, torch.randn(1, 3, 192, 192, device='cpu'), "facemesh.onnx", input_names=("image", ), output_names=("preds", "confs"), opset_version=9)
这样我们就得到了ONNX版本的模型文件。
OpenVINO调用facemesh模型
OpenVINO2020.x版本以后均支持直接读取ONNX格式模型文件,实现模型加载与推理调用。这里以OpenVINO2021.2版本为例。我们的基本思路是首先通过OpenVINO自带的人脸检测模型实现人脸检测,然后截取人脸ROI区域再送到facemesh模型中实现人脸3D表面点云468个点提取。人脸检测这里我们选择了OpenVINO自带的face-detection-0202模型文件,该模型是基于MobileNet SSDv版本,输入格式如下:
NCHW = 1x3x384x384
输出格式为:
1x1xNx7
通道的顺序是:BGR
从图-2得知人脸3D点云提取模型facemesh的输入格式为1x3x192x192,输出层有两个分别是preds与confs,其中preds是点云数据,confs表示置信度。preds的1404表示的是468个点每个点的三维坐标,总计468x3=1404。代码演示部分的步骤与运行结果详解说明与步骤。加载模型与获取输入与输出信息:
# 加载人脸检测模型 net = ie.read_network(model=model_xml, weights=model_bin) input_blob = next(iter(net.input_info)) out_blob = next(iter(net.outputs)) # 人脸检测的输入格式 n, c, h, w = net.input_info[input_blob].input_data.shape print(n, c, h, w) exec_net = ie.load_network(network=net, device_name="CPU") # 加载人脸3D点云预测模型 face_mesh_onnx = "facemesh.onnx" mesh_face_net = ie.read_network(model=face_mesh_onnx) # 输入格式 em_input_blob = next(iter(mesh_face_net.input_info)) en, ec, eh, ew = mesh_face_net.input_info[em_input_blob].input_data.shape print(en, ec, eh, ew) em_exec_net = ie.load_network(network=mesh_face_net, device_name="CPU")
人脸检测与获取人脸ROI然后提取人脸3D点云数据,然后显示:
# 设置输入图像与人脸检测模型推理预测 image = cv.resize(frame, (w, h)) image = image.transpose(2, 0, 1) inf_start = time.time() res = exec_net.infer(inputs={input_blob: [image]}) ih, iw, ic = frame.shape res = res[out_blob] # 解析人脸检测,获取ROI for obj in res[0][0]: if obj[2] > 0.75: xmin = int(obj[3] * iw) ymin = int(obj[4] * ih) xmax = int(obj[5] * iw) ymax = int(obj[6] * ih) if xmin < 0: xmin = 0 if ymin < 0: ymin = 0 if xmax >= iw: xmax = iw - 1 if ymax >= ih: ymax = ih - 1 # 截取人脸ROI,提取3D表面点云数据 roi = frame[ymin:ymax, xmin:xmax, :] roi_img = cv.resize(roi, (ew, eh)) roi_img = np.float32(roi_img) / 127.5 roi_img = roi_img.transpose(2, 0, 1) em_res = em_exec_net.infer(inputs={em_input_blob: [roi_img]}) # 转换为468个3D点云数据, 然后显示 prob_mesh = em_res["preds"] prob_mesh= np.reshape(prob_mesh, (-1, 3)) cv.rectangle(frame, (xmin, ymin), (xmax, ymax), (0, 255, 255), 2, 8) sx, sy= ew / roi.shape[1], eh / roi.shape[0] for i in range(prob_mesh.shape[0]): x, y = int(prob_mesh[i, 0] / sx), int(prob_mesh[i, 1] / sy) cv.circle(frame, (xmin + x, ymin + y), 1, (0, 0, 255), 1) # 计算帧率与显示点云结果 inf_end = time.time() - inf_start cv.putText(frame, "infer time(ms): %.3f, FPS: %.2f" % (inf_end * 1000, 1 / inf_end), (10, 50), cv.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 255), 2, 8) cv.imshow("Face Detection + 3D mesh", frame)
运行显示结果如下:
本文仅做学术分享,如有侵权,请联系删文。
下载1
在「3D视觉工坊」公众号后台回复:3D视觉,即可下载 3D视觉相关资料干货,涉及相机标定、三维重建、立体视觉、SLAM、深度学习、点云后处理、多视图几何等方向。
下载2
在「3D视觉工坊」公众号后台回复:3D视觉github资源汇总,即可下载包括结构光、标定源码、缺陷检测源码、深度估计与深度补全源码、点云处理相关源码、立体匹配源码、单目、双目3D检测、基于点云的3D检测、6D姿态估计源码汇总等。
下载3
在「3D视觉工坊」公众号后台回复:相机标定,即可下载独家相机标定学习课件与视频网址;后台回复:立体匹配,即可下载独家立体匹配学习课件与视频网址。
重磅!3DCVer-学术论文写作投稿 交流群已成立
扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。
同时也可申请加入我们的细分方向交流群,目前主要有3D视觉、CV&深度学习、SLAM、三维重建、点云后处理、自动驾驶、多传感器融合、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流、ORB-SLAM系列源码交流、深度估计等微信群。
一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。
▲长按加微信群或投稿
▲长按关注公众号
3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列、三维点云系列、结构光系列、手眼标定、相机标定、orb-slam3等视频课程)、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答五个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近2000星球成员为创造更好的AI世界共同进步,知识星球入口:
学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
圈里有高质量教程资料、可答疑解惑、助你高效解决问题
觉得有用,麻烦给个赞和在看~