【问题标题】:Overlaying/merging two (and more) YUV images in OpenCV在 OpenCV 中叠加/合并两个(或更多)YUV 图像
【发布时间】:2014-09-29 15:47:13
【问题描述】:

我调查并删除了我之前的问题 (Is there a way to avoid conversion from YUV to BGR?)。我想在生成的更大图像上叠加少量图像(格式为 YUV)(将其视为画布)并通过网络库 (OPAL) 将其发送,而不将其转换为 BGR。

代码如下:

    Mat tYUV;
    Mat tClonedYUV;
    Mat tBGR;
    Mat tMergedFrame;
    int tMergedFrameWidth = 1000;
    int tMergedFrameHeight = 800;
    int tMergedFrameHalfWidth = tMergedFrameWidth / 2;

    tYUV = Mat(tHeader->height * 1.5f, tHeader->width, CV_8UC1, OPAL_VIDEO_FRAME_DATA_PTR(tHeader));
    tClonedYUV = tYUV.clone();

    tMergedFrame = Mat(Size(tMergedFrameWidth, tMergedFrameHeight), tYUV.type(), cv::Scalar(0, 0, 0));
    tYUV.copyTo(tMergedFrame(cv::Rect(0, 0, tYUV.cols > tMergedFrameWidth ? tMergedFrameWidth : tYUV.cols, tYUV.rows > tMergedFrameHeight ? tMergedFrameHeight : tYUV.rows)));
    tClonedYUV.copyTo(tMergedFrame(cv::Rect(tMergedFrameHalfWidth, 0, tYUV.cols > tMergedFrameHalfWidth ? tMergedFrameHalfWidth : tYUV.cols, tYUV.rows > tMergedFrameHeight ? tMergedFrameHeight : tYUV.rows)));


    namedWindow("merged frame", 1);
    imshow("merged frame", tMergedFrame);
    waitKey(10);

上述代码的结果如下所示:

我猜图像没有正确解释,所以图片保持黑/白(Y 分量),在它们下方,我们可以看到 U 和 V 分量。有图片,很好地描述了问题(http://en.wikipedia.org/wiki/YUV):

和:http://upload.wikimedia.org/wikipedia/en/0/0d/Yuv420.svg

有没有办法正确读取这些值?我想我不应该将整个图像(它们的 Y、U、V 分量)直接复制到计算出的位置。 U 和 V 分量应该在它们下方并且按正确的顺序排列,对吗?

【问题讨论】:

  • tYUV 的类型应该是 CV_8UC3,(如果你想要所有 3 个 yuv 通道)。此外,如果您只有 w*h 像素,则无法像您一样将图像放大。 (tHeader->height * 1.5f 必须离开)
  • 我在 OpenCV 文档中找不到任何线索,它是否能够在 YUV 模式下执行“copyTo() 子图像”(由于数据的组织,它一定是一团糟),事实上,图像绝对不再以矩阵的形式组织了
  • @berak 我不太明白为什么我应该有三个频道。 AFAIK,如果我有图像 x 像素宽和 y 像素高,在 YUV 格式中,我将获得 Y 分量的 x * y 数字,U 的 x * y / 4 数字和 V 分量的 x * y / 4 数字。所以总的来说我有1.5 * x * y 号码。这就是为什么我把那个tHeader->height * 1.5f.

标签: c++ opencv image-processing merge yuv


【解决方案1】:

首先,有几种 YUV 格式,所以你需要清楚你使用的是哪一种。
根据您的图片,您的 YUV 格式似乎是 Y'UV420p。
无论如何,在那里转换为 BGR 工作然后再转换回来要简单得多。

如果这不是一个选项,您几乎必须自己管理投资回报率。 YUV 通常是一种平面格式,其中通道没有(完全)多路复用 - 并且有些具有不同的大小和深度。如果您不使用内部颜色转换,那么您将必须知道确切的 YUV 格式并自己管理像素复制 ROI。

对于 YUV 图像,CV_8UC* 格式说明符并不意味着超出实际内存要求。它当然没有指定像素/通道复用。

例如,如果您只想使用 Y 分量,那么 Y 通常是图像中的第一个平面,因此整个图像的前“一半”可以被视为单色8UC1 图像。在这种情况下,使用 ROI 很容易。

【讨论】:

  • 我想缩放图像,然后将它们复制到更大的画布上(就像在线视频会议的屏幕)。所以我需要使用所有的组件。除了手动复制 U 和 V 之外,您有什么建议吗?
  • 您应该真正转向基于频道的格式,例如 BGR。 cv::resize 独立调整每个通道的大小。它假定固定/已知数量的相同大小的多路复用通道。如果您在(大多数格式的)YUV 上使用它,如果它不会由于不同的通道图像大小(例如 U 和 V 通常是 Y 大小的 1/4)而不会崩溃,它将跨通道混合值。
猜你喜欢
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
相关资源
最近更新 更多