如何在没有默认 YUV2RGB->RGB2GRAY 转换的情况下从 H264 4:2:0 视频中读取 Y 分量

Posted

技术标签:

【中文标题】如何在没有默认 YUV2RGB->RGB2GRAY 转换的情况下从 H264 4:2:0 视频中读取 Y 分量【英文标题】:How to read Y-component from H264 4:2:0 video without default YUV2RGB->RGB2GRAY conversion 【发布时间】:2014-09-18 15:46:08 【问题描述】:

我需要快速处理灰度帧,因此我只需要来自 YUV 4:2:0 视频的 Y 分量。正如我从分析器中看到的,很多时间都浪费在无用的 YUV->RGB 转换上。

VideoCapture::cap.set(CV_CAP_PROP_CONVERT_RGB, false) 

没有效果,正如我从拆分中看到的那样

Mat ch[3]; split(frame,ch); imshow("it must be U-channel", ch[1]);

frames 仍然是 RGB,而不是 YUV,即 VideoCapture ignores CV_CAP_PROP_CONVERT_RGB 标志(我相信 openCV 用于视频解码的 ffmpeg 库可以理解这种标志)。

那么,请问有人知道如何更快地从视频序列中获取灰度图像吗? OpenCL 方法也可以,因为我将 Mat 转换为 oclMat 以在读取后处理此帧(包括当前无用的 ocl::cvtColor(A, B, CV_RGB2GRAY) )。

【问题讨论】:

你处理普通的视频文件吗?不涉及简历? 是的,它是我拥有的 100 多个常规视频文件之一 - 仅 1-2 小时来自 Internet 的电影。不涉及简历。而且我确定它是由 ffmpeg 编码的。你有没有从 CV_CAP_PROP_CONVERT_RGB 标志与任何 4:2:0 电影一起使用的效果?正如我在这里找到的problem for camera is the same。 【参考方案1】:

对于常规视频解码,您不需要 OpenCV。可以使用 ffmpeg 库来完成。下载并构建最新版本的 ffmpeg 并查看sample,其中您需要video_decode_example 功能。在它的正文中,第 401 行:

if (got_picture) 
    printf("saving frame %3d\n", frame);
    fflush(stdout);

    /* the picture is allocated by the decoder. no need to free it */
    snprintf(buf, sizeof(buf), outfilename, frame);
    pgm_save(picture->data[0], picture->linesize[0], c->width, c->height, buf);
    frame++;

由于 ffmpeg 使用 Y Cb Cr 颜色表示,解码帧的 Y 平面存储在 picture->data[0] 中。将其复制到您的 OpenCL 内存对象中,就是这样。

【讨论】:

是的,在我提问之前我看到了your answer,谢谢。当然 ffmpeg lib 是一个决定。但是只使用openCV函数更方便,而且无论如何它都使用opencv_ffmpeg.dll。好吧,似乎没有 openCV-only-way,至少只要打开this bug(我仍然不确定它是否真的是错误)。我认为你的回答很有用,但相信有人会教我们解决这个问题的 openCV-only-way。

以上是关于如何在没有默认 YUV2RGB->RGB2GRAY 转换的情况下从 H264 4:2:0 视频中读取 Y 分量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swig & python 中为没有默认构造函数的 std::pair<> 创建接口?

如何修改eclipse中@author的默认选项

CSS 如何恢复到默认样式?

使用 OpenGL 更快的相机预览?

如何将 XPath 与没有前缀的默认命名空间一起使用?

apache当没有index文件时如何显示目录文件的全部文件名