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

使用OpenCV将YU12格式摄像头帧转换为RGB失败求助

解决OpenCV读取YU12编码摄像头帧异常及转RGB报错问题

首先咱们拆解下问题的核心根源:

  • OpenCV的VideoCapture.read()默认会自动将摄像头原始格式转换为BGR(3通道),但如果摄像头输出的是YU12(YV12)这类平面YUV格式,自动转换过程会出错,导致你拿到的raw_frame既不是正确的BGR,也不是原始的YU12单通道格式——这就是直接保存画面怪异、转RGB时通道数不匹配报错的原因。
  • 从mplayer的输出来看,你的摄像头实际输出可能是YUY2格式(mplayer识别为rawyuy2),它是自行转换为YV12显示的,这也能解释OpenCV自动转换失败的问题。

解决方案:强制读取原始帧+匹配格式转换

下面是修正后的代码,我会逐段说明关键改动:

import os
import sys
import cv2

videoSource = 0

def getFrame():
    cv_cam_0 = cv2.VideoCapture(videoSource)
    if not cv_cam_0.isOpened():
        raise Exception(f'video source: {videoSource} could not be opened')
    
    # 关键:禁止OpenCV自动转RGB/BGR,直接读取摄像头原始输出帧
    cv_cam_0.set(cv2.CAP_PROP_CONVERT_RGB, 0)
    
    # 获取并打印摄像头实际fourcc编码,确认输出格式
    codec_char_code = int(cv_cam_0.get(cv2.CAP_PROP_FOURCC))
    a = chr(codec_char_code & 0xFF)
    b = chr((codec_char_code >> 8) & 0xFF)
    c = chr((codec_char_code >> 16) & 0xFF)
    d = chr((codec_char_code >> 24) & 0xFF)
    print(f'codec 4 char code: {a+b+c+d}')
    
    ret, raw_frame = cv_cam_0.read()
    if not ret:
        raise Exception('Failed to read frame')
    
    # 打印原始帧形状验证格式:YU12是单通道,1280x720的话形状应为(1080, 1280)(H*3//2, W)
    print(f'Raw frame shape: {raw_frame.shape}')
    
    # 根据实际编码选择对应转换方式
    codec = a+b+c+d
    if codec == 'YV12' or codec == 'YU12':
        # YU12/YV12是平面4:2:0格式,用对应转换码
        rgbFrame = cv2.cvtColor(raw_frame, cv2.COLOR_YUV2RGB_YV12)
    elif codec == 'YUY2':
        # 对应mplayer识别的YUY2格式
        rgbFrame = cv2.cvtColor(raw_frame, cv2.COLOR_YUY2RGB)
    else:
        raise Exception(f'Unsupported codec: {codec}')
    
    # 原始YUV帧直接保存会显示异常(平面格式特性),转换后的RGB帧可正常显示
    cv2.imwrite('/tmp/test0.jpg', raw_frame)
    cv2.imwrite('/tmp/testConvert.jpg', rgbFrame)
    
    # 释放摄像头资源
    cv_cam_0.release()

def main(args):
    getFrame()
    sys.exit()

if __name__ == "__main__":
    main(sys.argv)

关键改动说明

  1. 禁止自动格式转换:通过cv2.CAP_PROP_CONVERT_RGB = 0让OpenCV直接读取摄像头原始输出,避免自动转换导致的格式错乱。
  2. 确认实际编码:打印fourcc编码,明确摄像头输出格式(是YU12还是YUY2),对应选择正确的转换常数。
  3. 匹配颜色空间转换:
    • 对于YU12/YV12,使用cv2.COLOR_YUV2RGB_YV12(注意YU12是Y-V-U平面顺序,和I420的Y-U-V顺序不同,不能混用转换码);
    • 对于YUY2,使用cv2.COLOR_YUY2RGB。

之前报错的原因

你之前的代码中,OpenCV尝试自动将原始YUV转换为BGR但失败,导致raw_frame变成了错误的3通道数组。而cv2.COLOR_YUV2RGB_I420要求输入是单通道的平面YUV帧,因此抛出了Invalid number of channels in input image的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:22:31