使用OpenCV读写视频时出现画面伪影及文件体积增大的问题排查
问题描述
尝试使用OpenCV逐帧读取视频、处理后写入另一个视频文件,但生成的视频存在画面伪影,且输出文件体积远大于原文件(原文件约98MB,输出文件约143MB)。
环境:OpenCV 4.6、Visual Studio 2022、Windows 10。测试了两个网络下载的视频(含YouTube下载视频),均出现该问题;提取帧保存为JPG正常,但编码为视频时就会出现伪影。
测试代码如下:
#include <iostream> #include <opencv2/opencv.hpp> #include <conio.h> using namespace cv; using namespace std; int main() { std::string inputFile = "D:\\MyData\\sample2.mp4"; std::string outputFileName = "D:\\MyData\\sample2out.mp4"; VideoCapture inputVideo; inputVideo.open(inputFile); VideoWriter videoWritter; videoWritter.open(outputFileName, inputVideo.get(CAP_PROP_FOURCC), inputVideo.get(CAP_PROP_FPS),Size(inputVideo.get(CAP_PROP_FRAME_WIDTH), inputVideo.get(CAP_PROP_FRAME_HEIGHT))); while (true) // loop until all frames read. this { cv::Mat frame; // Capture frame-by-frame inputVideo >> frame; // If the frame is empty, break immediately if (frame.empty()) break; videoWritter << frame; } inputVideo.release(); videoWritter.release(); }
解决方案与原因分析
一、修复画面伪影
画面伪影大多是编码参数不匹配或者OpenCV默认编码器的行为问题,可以试试下面这些方法:
- 手动指定编码器并添加质量参数
直接复用输入视频的FOURCC编码格式时,可能因为系统编码器配置异常,或者原视频包含私有编码参数导致输出异常。可以手动指定H.264编码器(如avc1),并设置编码质量参数:
// 显式指定H.264编码器(avc1格式) int fourcc = VideoWriter::fourcc('a','v','c','1'); // 设置CRF值控制质量,18-28为常用范围,值越小质量越高、体积越大 vector<int> encodeParams = {VIDEOWRITER_PROP_QUALITY, 20}; VideoWriter videoWritter(outputFileName, fourcc, inputVideo.get(CAP_PROP_FPS), Size(inputVideo.get(CAP_PROP_FRAME_WIDTH), inputVideo.get(CAP_PROP_FRAME_HEIGHT)), true, encodeParams);
- 匹配帧的色彩空间
部分输入视频为YUV色彩空间,但OpenCV的VideoWriter默认期望BGR格式,写入前可统一格式:
if (frame.channels() != 3) { cvtColor(frame, frame, COLOR_GRAY2BGR); }
- 更换帧读取方式
inputVideo >> frame偶尔会出现帧读取不完整的情况,换成read()方法更稳妥:
while (true) { cv::Mat frame; if (!inputVideo.read(frame)) { // 读取失败直接退出循环 break; } videoWritter << frame; }
二、输出文件体积更大的原因
即使参数看似一致,体积变大主要由以下因素导致:
- 压缩配置差异:原视频通常使用了更激进的压缩参数(如更高的CRF值、更多帧间压缩策略),而OpenCV默认调用编码器的兼容模式,压缩率更低,因此体积更大。
- 帧类型分布不同:原视频可能包含大量P帧、B帧(依靠前后帧差异压缩),而OpenCV默认编码可能生成更多I帧(每一帧都是完整画面,体积更大)。
- 编码器实现差异:系统中解码原视频的编码器与OpenCV调用的编码器版本或配置不同,压缩效率自然存在差距。
内容的提问来源于stack exchange,提问作者mans
相关产品推荐
相关产品推荐

