在OpenCV4中实现实时的磨皮美颜并推流到直播服务器。

流程图如下:

摄像头视频捕获
cv2.VideoCapture
美颜处理管线
人脸与皮肤检测
磨皮与美白
细节增强与融合
处理后的帧
编码与推流
FFmpeg子进程
RTMP服务器
观众端播放

🔧 实现美颜效果

美颜算法的核心目标是在平滑皮肤瑕疵的同时,尽可能地保留面部细节(如眉毛、睫毛、嘴唇轮廓),避免产生不自然的“塑料感”。

  1. 皮肤区域检测
    为了只对皮肤区域进行磨皮,首先需要将图像转换到对亮度不敏感的颜色空间(如YCbCr或HSV)来识别肤色范围。

    import cv2
    import numpy as np
    
    def create_skin_mask(image):
        # 转换到YCbCr颜色空间
        ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)
        # 定义亚洲肤色的典型范围(需根据实际光照调整)
        lower_skin = np.array([0, 133, 77], dtype=np.uint8)
        upper_skin = np.array([255, 173, 127], dtype=np.uint8)
        skin_mask = cv2.inRange(ycrcb, lower_skin, upper_skin)
        
        # 使用形态学操作(如闭运算)优化掩码,去除噪声点,平滑区域
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
        skin_mask = cv2.morphologyEx(skin_mask, cv2.MORPH_CLOSE, kernel)
        return skin_mask
    
  2. 核心磨皮算法:双边滤波
    双边滤波是美颜的关键,它是一种能在平滑颜色相近区域的同时保留边缘信息的非线性滤波器。

    def smooth_skin(image, d=9, sigma_color=75, sigma_space=75):
        # d: 邻域直径,建议从9或15开始尝试
        # sigma_color: 颜色空间标准差,值越大,颜色混合范围越广,平滑效果越强
        # sigma_space: 坐标空间标准差,值越大,越远的像素会相互影响
        smoothed = cv2.bilateralFilter(image, d, sigma_color, sigma_space)
        return smoothed
    
  3. 肤色提亮(美白)​
    在Y通道(亮度通道)上增加亮度可以实现美白效果。

    def brighten_skin(image, brightness_gain=15):
        ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)
        y, cr, cb = cv2.split(ycrcb)
        # 增加Y通道亮度,使用cv2.add避免溢出
        y = cv2.add(y, brightness_gain)
        ycrcb_bright = cv2.merge([y, cr, cb])
        brightened_image = cv2.cvtColor(ycrcb_bright, cv2.COLOR_YCrCb2BGR)
        return brightened_image
    
  4. 效果融合
    最后,我们将处理好的皮肤区域和原始图像的非皮肤区域(如眼睛、眉毛、嘴唇)进行融合,确保重要细节不被破坏。

    def apply_beauty_filter(frame):
        skin_mask = create_skin_mask(frame)
        smoothed_face = smooth_skin(frame)
        brightened_face = brighten_skin(smoothed_face)
        
        # 将美颜后的皮肤区域与原始图像融合
        result = frame.copy()
        result[skin_mask > 0] = brightened_face[skin_mask > 0]
        return result
    

📡 集成FFmpeg进行直播推流

处理完每一帧后,我们需要将其高效地编码并推送到RTMP服务器(如配置了nginx-rtmp-module的服务器)。

  1. 启动FFmpeg子进程
    使用Python的subprocess模块启动一个FFmpeg命令,该命令将接收原始的BGR24格式视频帧,编码后推流。

    import subprocess
    import cv2
    
    # 摄像头初始化
    cap = cv2.VideoCapture(0)  # 0表示默认摄像头
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
    cap.set(cv2.CAP_PROP_FPS, 30)
    
    # 配置FFmpeg命令
    rtmp_url = "rtmp://your-server-ip:1935/live/streamkey"
    ffmpeg_cmd = [
        'ffmpeg',
        '-y',  # 无需询问,直接覆盖输出
        '-f', 'rawvideo',      # 输入格式:原始视频
        '-vcodec', 'rawvideo', # 输入编码:原始视频
        '-pix_fmt', 'bgr24',   # 输入像素格式:OpenCV默认格式
        '-s', '640x480',       # 分辨率
        '-r', '30',            # 帧率
        '-i', '-',             # 输入来自标准输入(stdin)
        '-c:v', 'libx264',     # 视频编码器:H.264
        '-pix_fmt', 'yuv420p', # 输出像素格式:广泛兼容的格式
        '-preset', 'veryfast', # 编码速度预设:非常快,适合直播
        '-tune', 'zerolatency',# 调优:零延迟,降低编码延迟
        '-f', 'flv',           # 输出容器格式:FLV
        rtmp_url
    ]
    
    # 启动FFmpeg进程
    ffmpeg_process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)
    
  2. 主循环:处理并推流
    在主循环中,捕获摄像头帧,进行美颜处理,然后将处理后的帧写入FFmpeg的标准输入。

    try:
        while True:
            ret, frame = cap.read()
            if not ret:
                break
    
            # 应用美颜滤镜
            beautified_frame = apply_beauty_filter(frame)
    
            # 将处理后的帧写入FFmpeg进程的标准输入进行推流
            ffmpeg_process.stdin.write(beautified_frame.tobytes())
    
            # 可选:在本地窗口预览效果(实际部署时可关闭)
            cv2.imshow('Beauty Live', beautified_frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
    finally:
        # 清理资源
        cap.release()
        cv2.destroyAllWindows()
        if ffmpeg_process:
            ffmpeg_process.stdin.close()
            ffmpeg_process.wait()
    

⚙️ 参数调优与进阶技巧

  • 美颜参数​:根据实际效果调整双边滤波dsigmaColorsigmaSpace参数以及美白brightness_gain。强度过高容易导致“塑料感”。
  • 性能与延迟​:使用-preset ultrafast-tune zerolatency有助于降低推流延迟。如果CPU负载过高,可以考虑降低推流分辨率或帧率。
  • 进阶功能​:
    • 人脸特征点检测​:集成Dlib或OpenCV的DNN模块进行精准的人脸特征点(如68点)检测,可以实现更高级的美颜效果,如瘦脸大眼,并能更精确地保护非皮肤区域。
    • 音频支持​:上述示例仅处理视频。如需同步推送音频,需要在FFmpeg命令中添加音频输入源和音频编码参数(如-c:a aac)。
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐