如何在没有默认 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 分量的主要内容,如果未能解决你的问题,请参考以下文章