OpenCV4入门015:视频文件读取与保存

系列教程索引地址:系列索引

视频文件简单读取和显示以及操作介绍完毕,能读就可以写,下面介绍将读取的帧在写入视频容器中。

流程为:

  • 获取视频信息
  • 分离每帧的RGB通道
  • 保存B通道数据为新视频
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main() {
// 视频读入与输出路径设置
string sourceVideoPath = "1.mp4";
string outputVideoPath = "2.mp4";
// 视频输入
VideoCapture inputVideo(sourceVideoPath,CAP_FFMPEG);
// 检测视频输入的有效性
if (!inputVideo.isOpened()) {
cout << "fail to open!" << endl;
return -1;
}
VideoWriter outputVideo;
// 获取视频分辨率
cv::Size videoResolution = cv::Size((int)inputVideo.get(CAP_PROP_FRAME_WIDTH),
(int)inputVideo.get(CAP_PROP_FRAME_HEIGHT));
double fps = inputVideo.get(CAP_PROP_FPS);
// 获取视频帧率
cout << "totalFrame:" << inputVideo.get(CAP_PROP_FRAME_COUNT) << endl;
// 获取视频总帧数
cout << "fps:" << inputVideo.get(CAP_PROP_FPS) << endl;
// 获取视频图像宽高
cout << "videoResolution:" << videoResolution.width << " " << videoResolution.height << endl;
// open方法相关设置
outputVideo.open(outputVideoPath, CAP_FFMPEG, 25.0, videoResolution, true);
if (!outputVideo.isOpened()) {
cout << "fail to open!" << endl;
return -1;
}
cv::Mat frameImg;
int count = 0;
// vector RGB分量
std::vector<cv::Mat> rgb;
cv::Mat resultImg;
for (int i = 0; i < 30; i++) {
inputVideo >> frameImg;
// 视频帧结束判断
if (!frameImg.empty()) {
count++;
cv::imshow("frameImg", frameImg);
// 分离出三通道rgb
cv::split(frameImg, rgb);
for (int i = 0; i < 3; i++) {
if (i != 0) {
// 提取B通道分量
rgb[ i ] = cv::Mat::zeros(videoResolution, rgb[ 0 ].type());
}
// 通道合并
cv::merge(rgb, resultImg);
}
cv::imshow("resultImg", resultImg);
outputVideo << resultImg;
} else {
break;
}
// 按下键盘上q键退出
if (char(waitKey(1)) == 'q') {
inputVideo.release();
outputVideo.release();
break;
}
}
std::cout << "writeTotalFrame:" << count << std::endl;

inputVideo.release();
outputVideo.release();
return 0;
}

编译运行,会报错

1
OpenCV: FFMPEG: tag 0x0000076c/'l???' is not found (format 'avi / AVI (Audio Video Interleaved)')'

将写部分修改为

1
outputVideo.open(outputVideoPath, VideoWriter::fourcc('M','J','P','G'), 25.0, videoResolution, true);

再次编译运行

输出结果为:

1
2
3
4
5
6
totalFrame:2530
fps:8.04132
videoResolution:1610 1030
OpenCV: FFMPEG: tag 0x47504a4d/'MJPG' is not supported with codec id 7 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
writeTotalFrame:30

视频效果为:

play

我们拆分的是B通道,即Blue部分。

保存的文件为

files