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

使用C++将UYUV(YUV422交错、BT709)转为RGB遇问题求助

UYUV(YUV422 Interleaved)转RGB的OpenCV C++代码问题

尝试用C将UYUV格式(YUV422 Interleaved、BT709)的YUV文件转换为RGB,编写的程序运行时抛出OpenCV异常,提示「输入图像通道数无效:'VScn::contains(scn)',其中'scn'为1」。将输入Mat的类型改为CV_8UC2后无报错,但转换结果异常;对应的Python代码可正常完成转换并得到正确结果,需解决C代码的问题。

错误信息

terminating with uncaught exception of type cv::Exception: OpenCV(4.5.5) /build/master_pack-android/opencv/modules/imgproc/src/color.simd_helpers.hpp:92: error: (-2:Unspecified error) in function 'cv::impl::(anonymous namespace)::CvtHelper<cv::impl::(anonymous namespace)::Set<2, -1, -1>, cv::impl::(anonymous namespace)::Set<3, 4, -1>, cv::impl::(anonymous namespace)::Set<0, -1, -1>, cv::impl::(anonymous namespace)::NONE>::CvtHelper(cv::InputArray, cv::OutputArray, int) [VScn = cv::impl::(anonymous namespace)::Set<2, -1, -1>, VDcn = cv::impl::(anonymous namespace)::Set<3, 4, -1>, VDepth = cv::impl::(anonymous namespace)::Set<0, -1, -1>, sizePolicy = cv::impl::(anonymous namespace)::NONE]'
Invalid number of channels in input image:
'VScn::contains(scn)'
where
'scn' is 1

异常转换结果

异常转换结果

原C++代码

Size iSize(1920,1080);

int iYUV_Size = iSize.width * (iSize.height + iSize.height / 2);

Mat mSrc_YUV420(cv::Size(iSize.width, iSize.height + iSize.height / 2),CV_8UC1);

ifstream FileIn;
FileIn.open(filename, ios::binary | ios::in);

if (FileIn.is_open())
{
    FileIn.read((char*)mSrc_YUV420.data, iYUV_Size);
    FileIn.close();
}
else
{
    printf("[Error] Unable to Read the Input File! \n");
}

Mat mSrc_RGB(cv::Size(iSize.width, iSize.height), CV_8UC1);

cv::cvtColor(mSrc_YUV420, mSrc_RGB, COLOR_YUV2RGB_UYVY);

cv::imwrite(output_filename, mSrc_RGB);

可正常运行的Python代码

with open(input_name, "rb") as src_file:
    raw_data = np.fromfile(src_file, dtype=np.uint8, count=img_width*img_height*2)
    im = raw_data.reshape(img_height, img_width, 2)

    rgb = cv2.cvtColor(im, cv2.COLOR_YUV2RGB_UYVY)

正确转换结果

正确转换结果

问题分析与修正代码

问题根源

  1. 文件大小计算错误:UYUV是YUV422 interleaved格式,每个像素对应2字节(U-Y-V-Y交替存储),总大小应为width * height * 2,而非原代码中YUV420格式的width*(height + height/2)。
  2. 输入Mat类型与尺寸错误:UYUV是2通道交错格式,需创建与原始图像同尺寸的CV_8UC2类型Mat,原代码错误创建了单通道、尺寸为YUV420的Mat。
  3. 输出Mat类型错误:RGB图像为3通道,需创建CV_8UC3类型Mat,原代码错误使用了单通道CV_8UC1。

修正后的C++代码

#include <opencv2/opencv.hpp>
#include <fstream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
    if (argc != 3) {
        printf("Usage: %s <input_uyuv_file> <output_rgb_file>\n", argv[0]);
        return -1;
    }
    const char* filename = argv[1];
    const char* output_filename = argv[2];

    Size iSize(1920, 1080);
    // UYUV为YUV422 interleaved,总大小=宽×高×2
    int iYUV_Size = iSize.width * iSize.height * 2;

    // 创建2通道Mat,尺寸与原始图像一致
    Mat mSrc_YUV(iSize, CV_8UC2);

    ifstream FileIn;
    FileIn.open(filename, ios::binary | ios::in);

    if (FileIn.is_open()) {
        FileIn.read((char*)mSrc_YUV.data, iYUV_Size);
        FileIn.close();
    } else {
        printf("[Error] Unable to Read the Input File! \n");
        return -1;
    }

    // 创建3通道RGB Mat
    Mat mSrc_RGB(iSize, CV_8UC3);

    // 执行UYVY转RGB转换
    cv::cvtColor(mSrc_YUV, mSrc_RGB, COLOR_YUV2RGB_UYVY);

    cv::imwrite(output_filename, mSrc_RGB);
    printf("转换完成,结果已保存至%s\n", output_filename);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:20:34