OpenCV C++窗口录制程序生成AVI损坏、视频尺寸固定问题求解
窗口录制AVI损坏问题排查与修复
1. 图像通道格式不匹配(核心问题)
hwnd2mat()返回的是CV_8UC4(带Alpha通道的BGRA格式),当前使用的MJPG编码器仅支持3通道BGR输入,直接写入4通道帧会导致编码器输出无效数据,生成损坏文件。- 修复:写入前转成3通道格式,替换原有
write逻辑:cv::Mat bgr_frame; cv::cvtColor(src, bgr_frame, cv::COLOR_BGRA2BGR); outputVideo.write(bgr_frame);
2. 未正确释放VideoWriter资源(高频踩坑)
VideoWriter内部存在帧缓存,程序直接退出时缓存的帧未写入磁盘,视频文件头也未完成封装,必然出现损坏。- 修复:while循环结束、程序退出前补充释放逻辑:
outputVideo.release(); cv::destroyAllWindows();
3. 未校验VideoWriter初始化状态
- 代码创建
VideoWriter后直接写帧,没有判断是否初始化成功。如果编码器不兼容、路径无写入权限、分辨率不合法,VideoWriter会初始化失败,后续写入内容全部无效。 - 修复:创建后立即加判断:
cv::VideoWriter outputVideo; outputVideo.open("output.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 15, cv::Size(src.cols, src.rows)); if (!outputVideo.isOpened()) { std::cerr << "视频编码器初始化失败" << std::endl; return -1; }
4. 捕获帧尺寸与预设分辨率不匹配
- 你观察到输出视频尺寸始终固定,是因为
VideoWriter初始化时就锁定了分辨率。如果录制过程中目标窗口大小改变,hwnd2mat()返回的帧尺寸会和预设分辨率不匹配,write()会直接丢弃帧或写入错误数据,引发文件损坏。 - 修复二选一即可:
- 录制全程禁止调整目标窗口大小,保证捕获帧尺寸和初始化时一致
- 每次捕获新帧后缩放到预设分辨率再写入:
cv::Size target_size((int)outputVideo.get(cv::CAP_PROP_FRAME_WIDTH), (int)outputVideo.get(cv::CAP_PROP_FRAME_HEIGHT)); cv::Mat resized_frame; cv::resize(bgr_frame, resized_frame, target_size); outputVideo.write(resized_frame);
5. 修正BITMAPINFOHEADER的错误参数
- 你设置的
bi.biClrUsed = 3; bi.biClrImportant = 4;对32位真彩色位图是无效的,该模式下这两个参数必须设为0,否则部分系统上会出现捕获图像颜色异常。修改为:bi.biClrUsed = 0; bi.biClrImportant = 0;
6. 帧率优化
- 当前初始化VideoWriter时帧率设为1,但代码用
waitKey(60)实际约16帧每秒,会导致播放速度异常。建议把帧率调整为和实际捕获速率匹配的15即可。
内容的提问来源于stack exchange,提问作者Skiv Hisink
相关产品推荐
相关产品推荐

