在 OpenCV 中将 YUV 转换为 BGR 或 RGB

新手上路,请多包涵

我有一个电视采集卡,它有一个 YUV 格式的提要。我在这里看到了与这个问题类似的其他帖子,并尝试尝试所有可能的方法,但它们都没有提供清晰的图像。目前最好的结果是使用 OpenCV cvCvtColor(scr, dst, CV_YUV2BGR) 函数调用。

我目前不知道 YUV 格式,老实说让我有点困惑,因为它看起来像存储 4 个通道,但只有 3 个?我已经包含了捕获卡中的图像,希望有人能理解我可以用来填补空白的可能发生的事情。

YUV 到 BGR 转换的图像

提要通过 DeckLink Intensity Pro 卡进入,并在 Windows 7 环境中使用 OpenCV 时在 C++ 应用程序中访问。

更新

我查看了有关此信息的维基百科文章,并尝试在我的应用程序中使用该公式。下面是从它接收到输出的代码块。任何意见是极大的赞赏。

 BYTE* pData;

    videoFrame->GetBytes((void**)&pData);

    m_nFrames++;

    printf("Num Frames executed: %d\n", m_nFrames);

    for(int i = 0; i < 1280 * 720 * 3; i=i+3)
    {
        m_RGB->imageData[i] = pData[i] + pData[i+2]*((1 - 0.299)/0.615);
        m_RGB->imageData[i+1] = pData[i] - pData[i+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[i+2]*((0.299*(1 - 0.299))/(0.615*0.587));
        m_RGB->imageData[i+2] = pData[i] + pData[i+1]*((1 - 0.114)/0.436);
    }

尝试 RGB 转换

原文由 Seb 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.3k
2 个回答

在我看来,您将 YUV422 流解码为 YUV444。尝试对您提供的代码进行此修改:

 for(int i = 0, j=0; i < 1280 * 720 * 3; i+=6, j+=4)
{
    m_RGB->imageData[i] = pData[j] + pData[j+3]*((1 - 0.299)/0.615);
    m_RGB->imageData[i+1] = pData[j] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587));
    m_RGB->imageData[i+2] = pData[j] + pData[j+1]*((1 - 0.114)/0.436);
    m_RGB->imageData[i+3] = pData[j+2] + pData[j+3]*((1 - 0.299)/0.615);
    m_RGB->imageData[i+4] = pData[j+2] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587));
    m_RGB->imageData[i+5] = pData[j+2] + pData[j+1]*((1 - 0.114)/0.436);
}

我不确定你的常数是否正确,但最坏的情况是你的颜色会消失 - 图像应该是可识别的。

原文由 Mark Ransom 发布,翻译遵循 CC BY-SA 3.0 许可协议

我使用以下 C++ 代码使用 OpenCV 将 yuv 数据(YUV_NV21)转换为 rgb 图像(OpenCV 中的 BGR)

 int main()
{
  const int width  = 1280;
  const int height = 800;

  std::ifstream file_in;
  file_in.open("../image_yuv_nv21_1280_800_01.raw", std::ios::binary);
  std::filebuf *p_filebuf = file_in.rdbuf();
  size_t size = p_filebuf->pubseekoff(0, std::ios::end, std::ios::in);
  p_filebuf->pubseekpos(0, std::ios::in);

  char *buf_src = new char[size];
  p_filebuf->sgetn(buf_src, size);

  cv::Mat mat_src = cv::Mat(height*1.5, width, CV_8UC1, buf_src);
  cv::Mat mat_dst = cv::Mat(height, width, CV_8UC3);

  cv::cvtColor(mat_src, mat_dst, cv::COLOR_YUV2BGR_NV21);
  cv::imwrite("yuv.png", mat_dst);

  file_in.close();
  delete []buf_src;

  return 0;
}

转换后的结果就像图像 yuv.png

你可以从 这里 找到 测试原始图像,从我的 Github 项目 中找到 整个项目

原文由 Gavin Gao 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏