尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MediaPipe face_landmark 模块详解:468/478 关键点人脸网格子图结构与前后端管线实现

MediaPipe face_landmark 模块详解:468/478 关键点人脸网格子图结构与前后端管线实现 MediaPipe face_landmark 模块详解468/478 关键点人脸网格子图结构与前后端管线实现【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe本文以 MediaPipe 仓库中的 face_landmark 模块 为核心系统讲解其对外暴露的四个人脸关键点子图FaceLandmarkCpu/FaceLandmarkGpu/FaceLandmarkFrontCpu/FaceLandmarkFrontGpu的输入输出约定、内部计算管线、with_attention机制与多脸跟踪原理。读完本文你将掌握这些子图在 CPU/GPU 两种计算后端下的调用方式、468 与 478 关键点的差异来源以及如何在自己的 MediaPipe 图Graph中组合使用它们完成单脸/多脸的人脸网格Face Mesh回归任务。一、模块定位与子图总览face_landmark模块位于 mediapipe/modules/face_landmark它提供的不是某个独立的人脸关键点终端应用而是一组可被上层图复用的 MediaPipe 子图Subgraph。这些子图通过mediapipe_simple_subgraph宏注册见 BUILDpackage(default_visibility [//visibility:public])使它们可以被仓库内其他模块如face_mesh、holistic_landmark、iris_tracking直接以 Calculator 形式引用。模块 README 的核心是一张子图清单本模块对外提供四种组合子图职责计算与数据通路FaceLandmarkCpu在给定的单个人脸 ROI 上回归关键点CPU 输入CPU 推理ImageFrame输入CPU 推理FaceLandmarkGpu在给定的单个人脸 ROI 上回归关键点GPU 输入GPU 推理GpuBuffer输入GPU 推理FaceLandmarkFrontCpu检测并跟踪多张人脸的关键点CPU 输入CPU 推理ImageFrame输入CPU 推理FaceLandmarkFrontGpu检测并跟踪多张人脸的关键点GPU 输入GPU 推理GpuBuffer输入GPU 推理从结构上可以把这四者分成两组理解FaceLandmarkCpu / FaceLandmarkGpu单脸回归子图只做在已知 ROI 内回归关键点这一件事是纯回归regression-only子图需要调用方先通过人脸检测给出ROI:roi。它们是整个模块的计算核心内部完成图像裁剪、TFLite 推理、关键点解码与坐标回投FaceLandmarkFrontCpu / FaceLandmarkFrontGpu多脸检测跟踪子图内部把FaceDetectionShortRange人脸检测子图、单脸回归子图以及一套基于上一帧关键点回算 ROI的反馈回路组合起来形成可端到端输出多张人脸关键点的前置型Front-facing子图。其文件注释明确说明设计意图是尽量通过上一帧已检测/回归出的关键点来跳过新一帧的人脸检测face_landmark_front_cpu.pbtxt第 1-3 行。除 README 表格列出的四者外模块目录里还有若干内部辅助子图与变体它们与四张主图共同构成完整实现face_landmark_front_cpu_image.pbtxt、face_landmark_front_gpu_image.pbtxt面向静态图片的单帧多脸处理变体face_landmark_front_side_model_cpu.pbtxt、face_landmark_front_side_model_gpu.pbtxt复用侧脸模型的变体face_detection_front_detection_to_roi.pbtxt 与 face_landmark_landmarks_to_roi.pbtxt两个检测/关键点 → ROI转换辅助子图图中注释明确警告subject to change and should not be used directly结构可能变更不建议直接使用face_landmarks_model_loader.pbtxt按with_attention标志选择并加载对应 TFLite 模型tensors_to_face_landmarks.pbtxt 与 tensors_to_face_landmarks_with_attention.pbtxt把推理输出的张量解码为 468 / 478 个归一化关键点。二、FaceLandmarkCpu / FaceLandmarkGpu单脸 ROI 回归子图的内部管线2.1 输入输出契约以 face_landmark_cpu.pbtxt 为例其顶部声明的类型与接口即调用方需要遵守的契约input_stream: IMAGE:imageCPU 图像ImageFrameinput_stream: ROI:roi图像内人脸所在区域类型为归一化矩形NormalizedRectinput_side_packet: WITH_ATTENTION:with_attention布尔值决定是否运行带注意力的人脸网格模型详见第三节output_stream: LANDMARKS:face_landmarksROI 内的人脸关键点列表NormalizedLandmarkList。文件头部给出了在宿主图中引用该子图的标准写法node { calculator: FaceLandmarkCpu input_stream: IMAGE:image input_stream: ROI:face_roi input_side_packet: WITH_ATTENTION:with_attention output_stream: LANDMARKS:face_landmarks }FaceLandmarkGpu的接口与 CPU 版本一一对应仅把图像输入从ImageFrame换成 GPU 缓冲GpuBufferIMAGE_GPU标签其管线下游会生成使用 GPU delegate 的推理图。2.2 一个关键约定人脸缺失时无输出包子图注释特别强调了一条容易被忽略的语义face_landmark_cpu.pbtxt第 39-42 行如果给定 ROI 内不存在人脸那么在当前时间戳上LANDMARKS流不会有输出包。但 MediaPipe 框架会内部告知下游 Calculator 该包的缺失使下游不必空等。也就是说该子图通过缺包即信号的方式表达当前帧没有脸下游 Calculator 应当能正确处理时间戳上有边界timestamp bound但无包的输入。这一点在编写自己的下游渲染或逻辑节点时务必注意。2.3 从输入图到 192×192 张量子图的第一阶段是把整幅图像按 ROI 变换成模型输入张量由ImageToTensorCalculator完成node: { calculator: ImageToTensorCalculator input_stream: IMAGE:image input_stream: NORM_RECT:roi output_stream: TENSORS:input_tensors options: { [mediapipe.ImageToTensorCalculatorOptions.ext] { output_tensor_width: 192 output_tensor_height: 192 output_tensor_float_range { min: 0.0 max: 1.0 } } } }关键参数模型输入固定为192×192像素归一化到浮点区间[0.0, 1.0]对应 TFLite 输入通常要求的归一化范围。GPU 版本face_landmark_gpu.pbtxt在此节点上额外多出gpu_origin: TOP_LEFT用来协调 GPU 纹理与 CPU 图像在原点/翻转语义上的差异保证裁剪与关键点坐标一致。tensors_to_face_landmarks*.pbtxt里的解码器选项同样写死input_image_width: 192、input_image_height: 192说明 192 是模型约定的输入尺寸两处必须保持一致。2.4 模型加载与推理模型加载封装在FaceLandmarksModelLoader子图中face_landmarks_model_loader.pbtxt。它接收WITH_ATTENTION布尔边包通过SwitchContainer在两个ConstantSidePacketCalculator之间切换模型文件路径with_attention为 false或未提供→ 加载mediapipe/modules/face_landmark/face_landmark.tflitewith_attention为 true → 加载mediapipe/modules/face_landmark/face_landmark_with_attention.tflite。随后ResourceProviderCalculator把路径解析为资源TfLiteModelCalculator把资源转换成tflite::FlatBufferModel。这一设计说明两个模型文件是运行期资源必须在执行环境中位于上述路径主图文件注释也对这一前提做了明确声明。推理由InferenceCalculator承担。CPU 版通过delegate { xnnpack {} }显式启用 XNNPACK 委托加速GPU 版则以空配置占位并保留注释Do not remove. Used for generation of XNNPACK/NNAPI graphs.不要删除供 XNNPACK/NNAPI 图生成使用——这意味着同一个 GPU 子图描述可以被工具链离线改写为不同后端的最终图。此外两版图都并联了TfLiteCustomOpResolverCalculator为模型可能依赖的自定义算子生成 op resolver 边包。2.5 张量拆分与人脸是否存在闸门推理输出的张量被送入SwitchContainer其内部按with_attention分支选用两套SplitTensorVectorCalculator的切分方案不带注意力ranges { begin: 0 end: 1 }与ranges { begin: 1 end: 2 }——输出两个张量前者是关键点张量后者是人脸标志face flag张量带注意力ranges { begin: 0 end: 6 }与ranges { begin: 6 end: 7 }——前 6 个是分区关键点张量mesh、嘴唇、左右眼、左右虹膜第 7 个仍为 face flag 张量。face flag 张量随后进入两条校验链路TensorsToFloatsCalculator以activation: SIGMOID把其换算为[0,1]的人脸存在置信度face_presence_scoreThresholdingCalculator以threshold: 0.5判定face_presence若判定无人脸GateCalculator输入landmark_tensors与ALLOW:face_presence直接丢弃关键点张量产生 2.2 节所述无输出包行为。2.6 张量解码与坐标回投通过闸门的关键点张量再次由SwitchContainer按with_attention选择解码器TensorsToFaceLandmarks把 1 个张量解码为468个归一化关键点TensorsToFaceLandmarksWithAttention把 6 个分区张量精修后合并为478个归一化关键点。两个解码子图内部均由TensorsToLandmarksCalculator承担张量 →NormalizedLandmarkList的转换所有输出坐标按模型输入尺寸192×192归一化。最后一步至关重要解码出的关键点是相对于裁剪后的人脸图的归一化坐标必须还原到原图上。LandmarkProjectionCalculator接收NORM_LANDMARKS:landmarks与NORM_RECT:roi利用 ROI 的平移与旋转把关键点投影回整个输入图像坐标系得到对外输出的face_landmarks。这也解释了为什么整套设计强依赖一个准确的 ROIROI 的质量直接决定裁剪内容与最终坐标精度。三、WITH_ATTENTION 与 468 → 478 关键点的秘密with_attention是本模块最具差异性的开关。README 与各子图注释均说明注意力机制在嘴唇、眼睛区域以及虹膜上提供更高精度开启后多出的10 个关键点正是左右眼的虹膜点。关键点数量语义可总结为with_attention false默认/未设置模型为face_landmark.tflite输出 468 个关键点其中不包含独立虹膜关键点with_attention true模型切换为face_landmark_with_attention.tflite输出478个关键点即在 468 个网格点基础上追加 468–477 共 10 个虹膜关键点左右各 5 个同时嘴唇、眼睛区域的关键点被分区模型的输出精修替换。tensors_to_face_landmarks_with_attention.pbtxt 完整展示了这条精修链路其解码顺序为 6 个张量mesh_tensor——468 点基础网格lips_tensor——80 点嘴唇细化left_eye_tensor——71 点左眼含眼睑与眼眶外圈 haloright_eye_tensor——71 点右眼left_iris_tensor——5 点左虹膜right_iris_tensor——5 点右虹膜。每个分区张量先由独立的TensorsToLandmarksCalculator解码各节点按张量分别设置num_landmarks: 468 / 80 / 71 / 71 / 5 / 5再汇入LandmarksRefinementCalculator。精修规则以indexes_mapping把分区关键点映射回 468 点网格的索引例如嘴唇 80 点映射到网格中的 0、17、61、146 等对应索引并附加 z 轴细化策略copy、none、或对虹膜点用眼睑关键点均值assign_average推算 z 值。虹膜 5 点按固定语义排列左虹膜468 中心、469 右缘、470 上缘、471 左缘、472 下缘右虹膜473 中心、474 右缘、475 上缘、476 左缘、477 下缘。值得注意的是SwitchContainer与with_attention的联动遍布整张图模型文件选择、输出张量切分方式、解码器选择三处都由同一个布尔边包驱动实现了同一子图接口、两种模型能力的动态切换。四、FaceLandmarkFrontCpu / FaceLandmarkFrontGpu多脸检测 跟踪闭环4.1 比单脸子图多了什么如果说FaceLandmarkCpu/Gpu是输入 ROI、输出关键点那么FaceLandmarkFrontCpu/Gpu的目标是输入整幅图、直接输出多张脸的关键点因此其内部把单脸子图与检测、跟踪装配在一起并引入反馈环路。两份前端图的接口几乎一致face_landmark_front_cpu.pbtxtinput_stream: IMAGE:image整幅输入图像input_side_packet: NUM_FACES:num_faces最大检测/跟踪人脸数int通过ClipDetectionVectorSizeCalculator与NormalizedRectVectorHasMinSizeCalculator共同约束input_side_packet: USE_PREV_LANDMARKS:use_prev_landmarks是否用上一帧关键点辅助定位当前帧关键点boolinput_side_packet: WITH_ATTENTION:with_attention同上文的注意力开关output_stream: LANDMARKS:multi_face_landmarksstd::vectorNormalizedLandmarkList每张脸一组关键点。除主输出外前端图还暴露三路调试用输出DETECTIONS检测到的人脸std::vectorDetection、ROIS_FROM_LANDMARKS由关键点算出的 ROI、ROIS_FROM_DETECTIONS由检测框算出的 ROI。这与上层渲染逻辑如 face_mesh_desktop.pbtxt 中FaceRendererCpu同时消费LANDMARKS、ROIS_FROM_LANDMARKS、DETECTIONS直接对应。4.2 基于上一帧关键点的 ROI 回环前端图设计的核心思路是尽可能跳过重复的人脸检测。闭环由PreviousLoopbackCalculator完成见face_landmark_front_cpu.pbtxt第 233-247 行node { calculator: PreviousLoopbackCalculator input_stream: MAIN:image input_stream: LOOP:face_rects_from_landmarks input_stream_info: { tag_index: LOOP back_edge: true } output_stream: PREV_LOOP:prev_face_rects_from_landmarks }它的行为是缓存本帧由关键点反推得到的 ROI在下一帧图像到达时把这些缓存的 ROI 以新图像的时间戳输出为prev_face_rects_from_landmarks。由于LOOP流被显式标记为back_edge: true回边MediaPipe 调度器会做正确的环形图处理注释还指出第一帧到达时会触发一次时间戳边界更新以启动这条反馈回路。后续处理围绕这条回边展开形成能跳过就跳过的策略GateCalculatorALLOW:use_prev_landmarksallow: true当use_prev_landmarks未提供或为 true 时放行上一帧 ROINormalizedRectVectorHasMinSizeCalculator检查上一帧 ROI 数量是否已 ≥num_faces产出prev_has_enough_faces另一个GateCalculatorDISALLOW:prev_has_enough_facesempty_packets_as_allow: true若上一帧已认全了足够多的人脸则丢弃本帧图像不触发检测否则放行图像进入人脸检测——注意empty_packets_as_allow保证在没有任何历史帧的冷启动阶段图像可以正常进入检测。4.3 检测 → ROI 循环当需要真正检测时图像被送入FaceDetectionShortRangeCpu/FaceDetectionShortRangeGpu后者定义于 mediapipe/modules/face_detection 模块的短距离检测子图对应资源为face_detection_short_range.tflite。检测结果随后ClipDetectionVectorSizeCalculator按num_faces截断检测数量BeginLoopDetectionCalculator把检测向量展开为按假时间戳逐个处理的循环同时Clone图像尺寸边包循环体内FaceDetectionFrontDetectionToRoi把单个检测转换为 ROIEndLoopNormalizedRectCalculator汇总成 ROI 向量face_rects_from_detections。其中FaceDetectionFrontDetectionToRoiface_detection_front_detection_to_roi.pbtxt内部使用DetectionsToRectsCalculator生成一个人脸包围框且旋转到双眼连线水平的归一化矩形旋转向量取关键点 0左眼到关键点 1右眼目标角度为 0随后RectTransformationCalculator以scale_x: 1.5、scale_y: 1.5、square_long: true对外扩并化为正方形确保包含完整人脸。4.4 历史 ROI 与检测 ROI 的融合去重AssociationNormRectCalculator把当前帧检测 ROI 与上一帧关键点 ROI 关联融合min_similarity_threshold: 0.5其作用注释所述是保证输出的face_rects不包含重叠区域。换言之上一帧已跟踪到的脸不重复检测、不产生重叠框只有上一帧缺失新入镜的脸才由检测分支补充这正是检测 跟踪混合架构的收敛点。4.5 关键点回归循环与跨帧跟踪融合后的face_rects由BeginLoopNormalizedRectCalculator展开循环体内对每个 ROIImagePropertiesCalculator计算图像尺寸调用单脸子图FaceLandmarkCpuGPU 版为FaceLandmarkGpu回归face_landmarksFaceLandmarkLandmarksToRoi由关键点反推更紧凑的 ROIface_rect_from_landmarks——该 ROI 会被送入反馈环PreviousLoopbackCalculator供下一帧复用。FaceLandmarkLandmarksToRoiface_landmark_landmarks_to_roi.pbtxt内部先由LandmarksToDetectionCalculator生成紧密包络的检测再由DetectionsToRectsCalculator旋转对齐其旋转向量改用关键点33左眼外侧到 263右眼外侧随后同样经RectTransformationCalculator以scale_x/y: 1.5、square_long: true外扩——扩大后的矩形保证即使人脸有轻微运动下一帧的人脸仍在 ROI 内。循环结束后EndLoopNormalizedLandmarkListVectorCalculator把每个 ROI 的关键点汇成multi_face_landmarks输出同时EndLoopNormalizedRectCalculator汇出face_rects_from_landmarks供回环缓存。至此一条完整的多脸跟踪管线闭环形成上一帧关键点 ROI →够数则跳过检测→ ROI 融合 → 单脸回归 → 新关键点 ROI → 缓存供下一帧。五、资源依赖与运行前提运行这套子图需要满足以下资源前提主图文件注释中均有明确声明单脸回归必选mediapipe/modules/face_landmark/face_landmark.tflitewith_attentionfalse时注意力增强可选mediapipe/modules/face_landmark/face_landmark_with_attention.tflitewith_attentiontrue时前端多脸图额外必选mediapipe/modules/face_detection/face_detection_short_range.tflite短距离人脸检测模型。两个模型文件路径由FaceLandmarksModelLoader中的ConstantSidePacketCalculator硬编码见 face_landmarks_model_loader.pbtxt 第 27、37 行因此部署时资源名必须与之一致。MediaPipe 的资源加载机制ResourceProviderCalculator会按项目构建的 resource 目录解析这些相对路径若缺失会直接导致图运行失败。六、在宿主图中组合使用的完整示例仓库内现成的组合范例是 face_mesh_desktop.pbtxt桌面端 CPU 人脸网格示例同类移动端/其他示例 也基于本模块。它展示了前端子图的典型装配方式input_side_packet: input_video_path input_side_packet: output_video_path max_queue_size: 1 # 通过限流保证图一次只处理一帧 # 通过常量边包注入 num_faces 与 with_attention node { calculator: ConstantSidePacketCalculator output_side_packet: PACKET:0:num_faces output_side_packet: PACKET:1:with_attention node_options: { [type.googleapis.com/mediapipe.ConstantSidePacketCalculatorOptions]: { packet { int_value: 1 } packet { bool_value: true } } } } # 组合 FaceLandmarkFrontCpu 进行人脸检测与关键点回归 node { calculator: FaceLandmarkFrontCpu input_stream: IMAGE:input_video input_side_packet: NUM_FACES:num_faces input_side_packet: WITH_ATTENTION:with_attention output_stream: LANDMARKS:multi_face_landmarks output_stream: ROIS_FROM_LANDMARKS:face_rects_from_landmarks output_stream: DETECTIONS:face_detections output_stream: ROIS_FROM_DETECTIONS:face_rects_from_detections } # 渲染关键点标注 node { calculator: FaceRendererCpu input_stream: IMAGE:input_video input_stream: LANDMARKS:multi_face_landmarks input_stream: NORM_RECTS:face_rects_from_landmarks input_stream: DETECTIONS:face_detections output_stream: IMAGE:output_video }该示例同时把num_faces1、with_attentiontrue通过ConstantSidePacketCalculator注入验证了边包驱动的调用风格。读者可以据此把FaceLandmarkFrontCpu/Gpu换成对应后端或改用FaceLandmarkCpu/Gpu自行提供检测 ROI仓库中 mediapipe/graphs/iris_tracking/iris_tracking_cpu.pbtxt、mediapipe/graphs/holistic_tracking 等图还对FaceLandmarkFrontCpu做了复用以提取眼部/面部区域可继续参考。七、小结读懂 face_landmark 的一张图把本模块的全部 pbtxt 串联起来可以得到如下心智模型四个公开子图 两套能力 × 两个后端单脸 ROI 回归Cpu/Gpu是计算核心前端多脸FrontCpu/FrontGpu是在其之上叠加了短距人脸检测 跨帧 ROI 反馈 ROI 关联去重的完整解决方案同一个with_attention贯穿三层模型文件选择 → 输出张量切分 → 关键点解码三处联动决定了最终输出 468 还是 478 个点所有关键点坐标都归一化且会回投到输入图解码时按 192×192 模型输入归一化输出前经LandmarkProjectionCalculator用 ROI 逆变换还原无脸即缺包是显式协议子图通过帧级空输出表达检测失败下游必须正确处理时间戳边界。对于需要在自有 MediaPipe 图中接入人脸网格能力的开发者最直接的做法就是复用本模块的四个已注册子图并遵循上述边包与流契约如需深度定制例如替换模型、调整 ROI 外扩系数、改变关键点数量则可从 face_landmark_cpu.pbtxt 这份最小管线出发进行修改。【免费下载链接】mediapipeCross-platform, customizable ML solutions for live and streaming media.项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表