【发布时间】:2021-10-08 06:14:50
【问题描述】:
我试图简单地用 openCV 打开一个视频,处理帧并将处理后的帧写入一个新的视频文件。
我的问题是,即使我根本不处理帧(只是打开视频,使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件),输出文件看起来比输入更“绿色”。
执行此操作的代码可以在任何 openCV 教程中找到,没什么特别的。
我在 Windows 10 上使用 openCV c++ 4.4.0。 我通过 opencv_videoio_ffmpeg440_64.dll 将 openCV 与 ffmpeg 一起使用 输入视频是mp4。 我用 huffyuv 编解码器将输出写为 .avi:
m_video_writer.reset(new cv::VideoWriter(m_save_video_path.toStdString(), cv::VideoWriter::fourcc('H', 'F', 'Y', 'U'), // lossless compression
m_model->getFps(), cv::Size(m_frame_size.width(), m_frame_size.height())));
我尝试了许多其他编解码器,但问题仍然存在。
像素差异很小,值不是恒定的,但总是以相同的方式变化:蓝色通道较低,红色和绿色较高。
奇怪的事实:当我用 opencv 打开输入或输出视频时,矩阵实际上是完全相同的。所以我猜问题出在阅读上??
以下是每个视频文件的属性,通过 Windows Media Playre (MPC-HC) 导出。
VS
我应该调查什么? 谢谢!!
完整代码在这里(复制我视频的前 100 帧):
VideoCapture original("C:/Users/axelle/Videos/original.MP4");
int frame_height = original.get(CAP_PROP_FRAME_HEIGHT);
int frame_width = original.get(CAP_PROP_FRAME_WIDTH);
int fps = original.get(CAP_PROP_FPS);
VideoWriter output("C:/Users/axelle/Videos/output.avi", VideoWriter::fourcc('H', 'F', 'Y', 'U'),
fps, cv::Size(frame_width, frame_height));
int count = 0;
while (count < 100)
{
count++;
Mat frame;
original >> frame;
if (frame.empty())
{
break;
}
//imshow("test", frame);
//waitKey(0);
output.write(frame);
}
original.release();
output.release();
注意:颜色的差异已经可以在 imshow 中看到了。
【问题讨论】:
-
如果您怀疑是阅读问题,请贴出阅读代码sn-p。
-
这可以根据您选择的编解码器进行。能否请您分享整个代码,以便我们在我们的环境中进行尝试?
-
看起来OpenCV使用BT.601转换公式使用YUV到BGR转换。您的视频流被标记为 BT.709。看起来 OpenCV 忽略了流的颜色特征。这是一个阅读问题!
-
@Rotem,有没有办法让 OpenCV 使用正确的转换??
-
是的,使用 GStreamer 后端而不是 FFmpeg 后端,颜色看起来很完美。默认情况下,OpenCV 不是使用 GStreamer 构建的(至少在 Windows 中不是)。我使用 GStreamer 从源代码构建 OpenCV(在下载并安装 GStreamer 之后)...