当前位置: 首页 > web >正文

使用 MediaPipe 和 OpenCV 快速生成人脸掩膜(Face Mask)

在实际项目中,尤其是涉及人脸识别、换脸、图像修复等任务时,我们经常需要生成人脸区域的掩膜(mask)。这篇文章分享一个简单易用的小工具,利用 MediaPipe 和 OpenCV,快速提取人脸轮廓并生成二值掩膜图像。

下面是完整代码,配合详细讲解,适合初学者和需要快速上手的小伙伴!

环境准备

首先,需要安装以下 Python 库(如果尚未安装,可以用 pip 安装):

pip install opencv-python mediapipe pillow numpy

核心代码

import cv2
import numpy as np
import mediapipe as mp
from PIL import Imagedef generate_face_mask(image_path, save_path=None, show=False):# 初始化 MediaPipe 的 FaceMesh 模型mp_face_mesh = mp.solutions.face_meshface_mesh = mp_face_mesh.FaceMesh(static_image_mode=True, refine_landmarks=True)# 读取图像img = cv2.imread(image_path)h, w, _ = img.shape# 人脸检测与关键点提取results = face_mesh.process(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))# 初始化黑色背景的 maskmask = np.zeros((h, w), dtype=np.uint8)# 如果检测到人脸if results.multi_face_landmarks:for face_landmarks in results.multi_face_landmarks:# 获取人脸关键点坐标points = [(int(p.x * w), int(p.y * h)) for p in face_landmarks.landmark]# 使用凸包(convex hull)拟合整个脸部区域hull = cv2.convexHull(np.array(points))# 将凸包区域填充为白色cv2.fillConvexPoly(mask, hull, 255)# 可选:展示生成的 maskif show:cv2.imshow("Mask", mask)cv2.waitKey(0)# 保存 mask 到本地if save_path:cv2.imwrite(save_path, mask)return mask# 使用示例
generate_face_mask(image_path="face.png",  # 替换为你的图像路径save_path="face_mask.png",# show=True  # 如果想看效果可以打开
)

代码讲解

  • MediaPipe FaceMesh

    • MediaPipe 提供了轻量级的人脸关键点检测(共468个关键点),非常适合快速处理。
    • refine_landmarks=True 参数会进一步优化面部区域,如眼睛轮廓、嘴唇轮廓。
  • 提取关键点并绘制凸包(Convex Hull)

    • 为了保证 mask 的完整性,不直接用单个关键点连线,而是用 OpenCV 的 convexHull 函数,将人脸外围自动拟合成一个封闭轮廓。
    • 这样能确保 mask 覆盖整个脸部,即便脸部角度有倾斜或旋转。
  • 保存掩膜(mask)

    • 最后生成的是一张黑白二值图,白色部分为人脸区域,黑色为背景,非常适合后续做图像分割、融合等任务。

效果示例

输入图片:

生成的人脸掩膜:

应用场景

  • 换脸(Face Swap):掩膜用于融合不同人脸区域。
  • 肖像图像处理:美颜、磨皮、特效。
  • 图像修复(Inpainting):只修复人脸区域,背景保持不变。
  • 身份保护:打码或模糊特定人脸区域。

小结

这个方法虽然简单,但实用性非常高,适用于各种需要人脸掩膜的小项目。如果需要更精细的面部特征(比如眼睛、嘴巴分开处理),还可以在此基础上扩展 —— 例如结合不同 landmark 区域单独提取。

希望这篇分享能帮到你,动手试试看吧!👍

http://www.xdnf.cn/news/2363.html

相关文章:

  • 后端响应巨量数据,如何优化性能?
  • [GXYCTF2019]Ping Ping Ping
  • Monorepo、Lerna、Yarn Workspaces、pnpm Workspaces 用法
  • 深入解析 npm 与 Yarn:Node.js 包管理工具对比与选型指南
  • 全栈量子跃迁:当Shor算法破解RSA时,我们如何用晶格密码重构数字世界的信任基岩?
  • MySQL:13.用户管理
  • Flutter 泛型 泛型方法 泛型类 泛型接口
  • HarmonyOS Next~鸿蒙系统UI创新实践:原生精致理念下的设计革命
  • flask uri 怎么统一加前缀
  • zynq7035的arm一秒钟最多可以支持触发多少次中断
  • 【合新通信】---Mini单路光模块(Mini SFF/USOT)
  • [Lc_week] 447 | 155 | Q1 | hash | pair {}调用
  • 【Linux网络】Http服务优化 - 增加请求后缀、状态码描述、重定向、自动跳转及注册多功能服务
  • 51单片机所有寄存器介绍
  • FFmpeg之三 录制音频并保存, API编解码从理论到实战
  • Linux红帽:RHCSA认证知识讲解(十 四)分区管理、交换分区,创建逻辑卷与调整逻辑卷的大小
  • Spark Streaming实时数据处理实战:从DStream基础到自定义数据源集成
  • FPGA基础之基础语法
  • Unreal Engine 实现智慧水库周边环境以及智慧社区模拟的实例
  • Flutter 学习之旅 之 flutter 有时候部分手机【TextField】无法唤起【输入法软键盘】的一些简单整理
  • LINUX的使用(2)- 安装软件
  • Comfy UI 笔记
  • Selenium自动化测试+OCR-获取图片页面小说
  • 入职学习记录-RT-thread实时操作系统_1
  • Android HAL HIDL
  • C语言:数据的存储
  • matplotlib画图工具使用(1) 画折线统计图python代码
  • 【教学类-102-19】蝴蝶三色图作品1——卡纸蝴蝶(滴颜料按压对称花纹)A4横版最大号22.85CM
  • 如何在学习通快速输入答案(网页版),其他学习平台通用,手机上快速粘贴
  • 时间序列成像之点对称模式(Symmetrized Dot Pattern,SDP)