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

基于OpenCV与Mediapipe的高真实感唇色修改优化方案求助

唇色修改的稳定性与融合优化方案

一、抑制关键点波动(解决多边形抖动)

1. 时间平滑滤波

对连续帧的唇部关键点坐标采用移动平均滤波,维护一个固定长度的队列存储最近3-5帧的关键点坐标,取队列内坐标的均值作为当前帧的最终关键点,平衡平滑效果与实时性。

2. 关键点约束修正

基于唇部解剖结构的连续性,设定关键点的合理变动阈值:计算当前帧与前一帧对应关键点的欧氏距离,若超出阈值(如10像素),则用前一帧的关键点坐标替换当前帧的异常点,避免单次检测偏差导致的大幅抖动。

3. 提高Mediapipe检测置信度

调整Mediapipe FaceMesh的min_detection_confidence和min_tracking_confidence参数至0.7-0.8,过滤低置信度的关键点检测结果,减少异常点的出现。

二、优化掩码生成与融合(解决融合不均)

1. 自适应渐变羽化

放弃固定半径的羽化操作,根据唇部关键点的位置生成渐变掩码:

  • 计算唇部区域内每个点到唇部中心的距离,将距离归一化作为羽化系数;
  • 唇部边缘区域(距离中心远)采用更高的羽化强度,内部区域保留较低羽化,模拟真实唇部的颜色过渡效果。

2. 双轮廓分层掩码

利用Mediapipe提供的唇部内外轮廓关键点(如上唇外轮廓、上唇内轮廓),分别生成两层掩码:

  • 内轮廓掩码直接填充目标唇色;
  • 内外轮廓之间的区域生成从目标色到原唇色的渐变过渡层,避免生硬的颜色边界。

3. 高斯模糊分区域处理

生成初始多边形掩码后,仅对掩码的边缘区域进行高斯模糊,内部区域保持清晰:

  • 通过边缘检测提取掩码的边缘部分;
  • 对边缘区域应用较大核的高斯模糊,再与原掩码融合,既平滑边界又保留唇部内部的颜色饱和度。

三、代码调整示例

关键点平滑实现

from collections import deque
import numpy as np

# 初始化存储最近3帧唇部关键点的队列
lip_points_queue = deque(maxlen=3)

def smooth_lip_points(current_points):
    lip_points_queue.append(current_points)
    # 计算队列内所有关键点的均值,转换为整数坐标
    smoothed_points = np.mean(lip_points_queue, axis=0).astype(np.int32)
    return smoothed_points

自适应羽化掩码生成

import cv2

def generate_adaptive_lip_mask(frame, lip_points):
    # 创建初始多边形掩码
    mask = np.zeros_like(frame[:, :, 0])
    cv2.fillPoly(mask, [lip_points], 255)
    
    # 计算唇部中心坐标
    center = np.mean(lip_points, axis=0).astype(np.int32)
    # 生成距离映射:每个点到唇部中心的距离
    y, x = np.ogrid[:mask.shape[0], :mask.shape[1]]
    distance_map = np.sqrt((x - center[0])**2 + (y - center[1])**2)
    
    # 仅在唇部区域内计算最大距离
    lip_distances = distance_map[mask == 255]
    max_dist = np.max(lip_distances) if len(lip_distances) > 0 else 1
    
    # 生成渐变羽化系数:距离越远,系数越高(羽化越强)
    feather_coeff = distance_map[mask == 255] / max_dist
    adaptive_mask = mask.copy()
    adaptive_mask[mask == 255] = (255 * (1 - feather_coeff)).astype(np.uint8)
    
    # 最后做一次轻度模糊优化边缘
    return cv2.GaussianBlur(adaptive_mask, (7, 7), 0)

分层融合唇色

def apply_lip_color(frame, inner_mask, outer_mask, target_color):
    color_bgr = np.array(target_color[::-1], dtype=np.uint8)  # 转换为OpenCV的BGR格式
    color_layer = np.full_like(frame, color_bgr)
    
    # 内轮廓区域直接叠加目标色
    alpha_inner = inner_mask / 255.0
    frame = (frame * (1 - alpha_inner[:, :, np.newaxis]) + color_layer * alpha_inner[:, :, np.newaxis]).astype(np.uint8)
    
    # 内外轮廓之间的区域做渐变融合
    alpha_outer = outer_mask / 255.0
    frame = (frame * (1 - alpha_outer[:, :, np.newaxis]) + color_layer * alpha_outer[:, :, np.newaxis]).astype(np.uint8)
    
    return frame

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 01:32:48