请求修改Python Mediapipe代码:替换人脸、眼睛及嘴唇为自定义图形
解决方案
你需要改用MediaPipe的Face Mesh模块(而非原代码的Pose模块),它能提供人脸的精细地标点,满足人脸替换、眼睛和嘴唇修改的需求。以下是修改后的完整代码,可实现你想要的效果:
修改后的代码
import cv2 import mediapipe as mp import numpy as np # 初始化Face Mesh工具 mp_face_mesh = mp.solutions.face_mesh mp_drawing = mp.solutions.drawing_utils face_mesh = mp_face_mesh.FaceMesh( static_image_mode=False, max_num_faces=1, min_detection_confidence=0.5, min_tracking_confidence=0.5 ) # 定义人脸各部位的地标索引(来自MediaPipe官方定义) FACE_CONTOUR_IDX = list(mp_face_mesh.FACEMESH_FACE_OVAL) LEFT_EYE_IDX = list(mp_face_mesh.FACEMESH_LEFT_EYE) RIGHT_EYE_IDX = list(mp_face_mesh.FACEMESH_RIGHT_EYE) LIPS_IDX = list(mp_face_mesh.FACEMESH_LIPS) def get_landmark_coords(landmarks, idx_list, image_shape): """提取指定地标点的坐标""" h, w = image_shape[:2] coords = [] for idx_pair in idx_list: for idx in idx_pair: lm = landmarks.landmark[idx] coords.append((int(lm.x * w), int(lm.y * h))) coords = np.unique(coords, axis=0) return coords def draw_yellow_face(image, face_coords): """绘制半透明黄色人脸覆盖层""" mask = np.zeros_like(image) cv2.fillPoly(mask, [np.array(face_coords)], (0, 255, 255)) # BGR黄色 alpha = 0.8 # 透明度可调整 cv2.addWeighted(mask, alpha, image, 1 - alpha, 0, image) def draw_heart(image, eye_coords): """在眼睛区域绘制爱心""" x_min, y_min = np.min(eye_coords, axis=0) x_max, y_max = np.max(eye_coords, axis=0) center_x = (x_min + x_max) // 2 center_y = (y_min + y_max) // 2 size = min(x_max - x_min, y_max - y_min) // 2 # 用椭圆+三角形组合绘制爱心(BGR红色) cv2.ellipse(image, (center_x - size//2, center_y), (size//2, size//2), 0, 0, 180, (0, 0, 255), -1) cv2.ellipse(image, (center_x + size//2, center_y), (size//2, size//2), 0, 0, 180, (0, 0, 255), -1) cv2.polylines(image, [np.array([ (center_x - size, center_y), (center_x, center_y + size), (center_x + size, center_y) ])], True, (0, 0, 255), -1) def draw_smile(image, lips_coords): """绘制微笑弧线""" x_min, y_min = np.min(lips_coords, axis=0) x_max, y_max = np.max(lips_coords, axis=0) center_x = (x_min + x_max) // 2 center_y = (y_min + y_max) // 2 width = x_max - x_min height = width // 4 # 绘制微笑弧线(BGR红色) cv2.ellipse(image, (center_x, center_y + height//2), (width//2, height), 0, 0, 180, (0, 0, 255), 3) cap = cv2.VideoCapture(0) while cap.isOpened(): ret, frame = cap.read() if not ret: break # 镜像翻转画面(符合自拍习惯) frame = cv2.flip(frame, 1) h, w = frame.shape[:2] frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results = face_mesh.process(frame_rgb) if results.multi_face_landmarks: for face_landmarks in results.multi_face_landmarks: # 获取各部位坐标 face_coords = get_landmark_coords(face_landmarks, FACE_CONTOUR_IDX, (h, w)) left_eye_coords = get_landmark_coords(face_landmarks, LEFT_EYE_IDX, (h, w)) right_eye_coords = get_landmark_coords(face_landmarks, RIGHT_EYE_IDX, (h, w)) lips_coords = get_landmark_coords(face_landmarks, LIPS_IDX, (h, w)) # 执行绘制操作 draw_yellow_face(frame, face_coords) draw_heart(frame, left_eye_coords) draw_heart(frame, right_eye_coords) draw_smile(frame, lips_coords) cv2.imshow('Face Filter', frame) if cv2.waitKey(1) == ord('q'): break cap.release() cv2.destroyAllWindows()
关键说明
- 模块替换:用
FaceMesh替代原代码的Pose,因为它能识别人脸的468个精细地标,覆盖轮廓、眼睛、嘴唇等关键区域 - 黄色人脸覆盖:基于人脸轮廓生成蒙版,用半透明黄色填充覆盖原人脸
- 爱心眼睛:通过眼睛区域的边界计算中心和尺寸,用椭圆+三角形组合绘制爱心
- 微笑嘴唇:根据嘴唇区域的边界绘制弧形微笑线
自定义调整建议
- 若要使用自定义黄色图像而非纯色,可修改
draw_yellow_face函数,加载本地图像后调整尺寸贴合人脸边界框 - 调整
alpha参数可改变黄色人脸的透明度 - 修改爱心、微笑的颜色、尺寸参数,适配不同脸型
内容的提问来源于stack exchange,提问作者Vakindu
相关产品推荐
相关产品推荐

