You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求修改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()

关键说明

  1. 模块替换:用FaceMesh替代原代码的Pose,因为它能识别人脸的468个精细地标,覆盖轮廓、眼睛、嘴唇等关键区域
  2. 黄色人脸覆盖:基于人脸轮廓生成蒙版,用半透明黄色填充覆盖原人脸
  3. 爱心眼睛:通过眼睛区域的边界计算中心和尺寸,用椭圆+三角形组合绘制爱心
  4. 微笑嘴唇:根据嘴唇区域的边界绘制弧形微笑线

自定义调整建议

  • 若要使用自定义黄色图像而非纯色,可修改draw_yellow_face函数,加载本地图像后调整尺寸贴合人脸边界框
  • 调整alpha参数可改变黄色人脸的透明度
  • 修改爱心、微笑的颜色、尺寸参数,适配不同脸型

内容的提问来源于stack exchange,提问作者Vakindu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:13:17