在實際項目中,尤其是涉及人臉識別、換臉、圖像修復等任務時,我們經常需要生成人臉區域的掩膜(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 的完整性,不直接用單個關鍵點連線,而是用 OpenCV 的
-
保存掩膜(mask):
- 最后生成的是一張黑白二值圖,白色部分為人臉區域,黑色為背景,非常適合后續做圖像分割、融合等任務。
效果示例
輸入圖片:

生成的人臉掩膜:

應用場景
- 換臉(Face Swap):掩膜用于融合不同人臉區域。
- 肖像圖像處理:美顏、磨皮、特效。
- 圖像修復(Inpainting):只修復人臉區域,背景保持不變。
- 身份保護:打碼或模糊特定人臉區域。
小結
這個方法雖然簡單,但實用性非常高,適用于各種需要人臉掩膜的小項目。如果需要更精細的面部特征(比如眼睛、嘴巴分開處理),還可以在此基礎上擴展 —— 例如結合不同 landmark 區域單獨提取。
希望這篇分享能幫到你,動手試試看吧!👍