使用opencv从帧创建divx编码的avi

时间:2016-11-15 19:42:00

标签: c++ windows opencv bitblt

这个问题类似于this one,特别是this one,但我想要的输出是不同的。我正在尝试使用opencv将桌面捕获到视频。首选输出是带有divx编码的avi文件。我一般都是opencv和位图编程的新手。

作为第一步,为了确保divx编解码器存在,我创建一个纯色(黄色)的单帧(cv :: Mat)并将其写入视频文件100次,如下所示: / p>

[&]

这非常有效 - 视频文件已创建,可以在我的Win 10机器上使用VLC,Windows Media Player或电影和电视应用播放。它是100帧纯黄色,但它显示视频正在正确创建。

下一步:使用桌面的一系列屏幕截图替换上面代码中的虚拟cv :: Mat帧。我使用GetDesktopWindow()获取桌面窗口的句柄,然后使用函数hwnd2mat(取自this SO问题 - 谢谢!)将从桌面句柄获得的位图转换为cv :: Mat我可以写信给我的视频。

我逐字复制了hwnd2mat函数,除了我没有缩放图像 - 桌面位图已经是1920x1200,而且我创建的cv :: Mat是CV_8UC3而不是CV_8UC4(CV_8UC4导致我的应用程序崩溃)。

这是代码,包括hwnd2mat的重印:

g++

这样做的结果是创建了视频文件并且可以毫无错误地播放,但它只是纯灰色。看起来桌面的位图没有被正确地复制到cv :: Mat框架中。我已经尝试了BITMAPINFOHEADER中的数值组合,但没有任何作用,我不知道我在做什么是诚实的。我知道opencv有转换功能但是我甚至都不知道我想要转换成什么。

任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:1)

找出一种方法让它发挥作用 - 我不知道这是否是最佳方式,因此仍然欢迎评论或替代解决方案。

似乎GetDIBits可以工作,cv :: Mat 是4通道,即CV_8UC4,就像我改变它之前的原始代码hwnd2mat一样。如果它不是CV_8UC4,则不会复制数据(GetDIBits返回0条复制的扫描线),这就是为什么我的avi只是灰色的原因。所以第一个改变是将src cv :: Mat创建为4通道:

src.create(height, width, CV_8UC4);

但是对于我试图创建的divx编码的avi文件,帧应该是3通道(不要问我为什么)。我在调用GetDIBits()之后添加了对opencv转换函数的调用,如下所示:

cv::Mat dst;
dst.create(height, width, CV_8UC3); 
cv::cvtColor(src, dst, CV_RGBA2RGB);

然后我从hwnd2mat而不是src返回dst。对cvtColor的调用删除了alpha通道(RGBA中的A),dst最后只有R,G,B通道。

答案 1 :(得分:0)

您可以从 GetDIBits 获取没有 alpha 通道的位图并将其直接写入 cv::VideoWriter。只需将 biBitCount 更改为 24。将 Mat 格式保留为 CV_8IC3。这对我有用。 src.create(height, width, CV_8UC3);

bi.biBitCount = 24; // 这是要改变的地方