在项目开始之前,我的环境已配置完成,具体环境如何配置可参考网络教程。下面我们开始项目的实现
库的导入
1
2
3
4
5
|
#include<iostream> #include<opencv2/opencv.hpp> #include<string.h> using namespace std; using namespace cv; |
这就不多说了
开启摄像头
1
2
3
4
5
6
7
|
Mat frame; Mat newframe; string outputVideoPath = "F:\\C++language\\robocon.avi" ; VideoCapture capture(0); int frame_width = capture.get(CAP_PROP_FRAME_WIDTH); int frame_height = capture.get(CAP_PROP_FRAME_HEIGHT); VideoWriter writer; |
开始摄像头,并获取摄像头的像素高度与宽度
定义所需变量
1
2
3
4
|
int num = 3; //原图片长宽皆被划分为三份,共划分成九份 int stepwidth; //划分后单个图片的宽度 int stepheight; //划分后的那个图片的高度 int space = 5; //九宫格中每张图片的间隔 |
捕获图片并生成视频
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
capture >> frame; stepwidth = frame.cols / num; stepheight = frame.rows / num; resize(frame, frame, Size(stepwidth * num, stepheight * num), 1, 1, INTER_LINEAR); newframe = Mat(Size(frame.cols + (num - 1) * space, frame.rows + (num - 1) * space), CV_8UC3, Scalar(255, 255, 255)); //新画布的生成 writer.open(outputVideoPath, cv::VideoWriter::fourcc( 'M' , 'J' , 'P' , 'G' ), 10, Size(frame.cols + (num - 1) * space, frame.rows + (num - 1) * space)); if (!capture.isOpened()) { cout << "The camera cannot be opened" << endl; } if (!writer.isOpened()) { cout << "The video cannot be saved" << endl; } |
根据九宫格各张图片以及间隔的大小生成新的画布,用于存放新的九宫格图片
实现图片的抓取、转换与保存
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
|
int count = 1; while (count <= 60) { capture >> frame; stepwidth = frame.cols / num; stepheight = frame.rows / num; resize(frame, frame, Size(stepwidth * num, stepheight * num), 1, 1, INTER_LINEAR); Mat newframe = Mat(Size(frame.cols + (num - 1) * space, frame.rows + (num - 1) * space), CV_8UC3, Scalar(255, 255, 255)); int i = 0; int j = 0; for (i = 0; i < num; i++) { for (j=0; j < num; j++) { int x = stepwidth * j; int y = stepheight * i; frame(Rect(x, y, stepwidth, stepheight)).copyTo(newframe(Rect(x + space * j, y + space * i, stepwidth, stepheight))); } } imshow( "output" , newframe); waitKey(100); writer << newframe; count += 1; } } |
视频以10帧的形式呈现,共60帧图片。
补充
当然OpenCV不仅可以实现录制九宫格视频,还能制作出九宫格拼图功能,下面是实现的示例代码,感兴趣的可以学习一下
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <stdlib.h> #include <time.h> using namespace cv; using namespace std; Mat img = imread( "C:\\picture\\aa.jpg" ); int m = img.cols; //宽 int n = img.rows; //高 cv::Mat combine = cv::Mat::zeros(m, n, img.type()); Mat imgROI1 = combine(Rect(0, 0, m / 3, n / 3)); Mat imgROI2 = combine(Rect(m / 3, 0, m / 3, n / 3)); Mat imgROI3 = combine(Rect(m / 3 * 2, 0, m / 3, n / 3)); Mat imgROI4 = combine(Rect(0, n / 3, m / 3, n / 3)); Mat imgROI5 = combine(Rect(m / 3, n / 3, m / 3, n / 3)); Mat imgROI6 = combine(Rect(m / 3 * 2, n / 3, m / 3, n / 3)); Mat imgROI7 = combine(Rect(0, n / 3 * 2, m / 3, n / 3)); Mat imgROI8 = combine(Rect(m / 3, n / 3 * 2, m / 3, n / 3)); Mat imgROI9 = combine(Rect(m / 3 * 2, n / 3 * 2, m / 3, n / 3)); Mat a[10]; Mat imge[10]; int t = 0; int first; int second; Mat temp; int f( int xx, int yy); void onMouseHandle( int event, int x, int y, int flags, void *param); int main() { //分割图像rect() imge[1] = img(Rect(0, 0, m / 3, n / 3)); imge[2] = img(Rect(m / 3, 0, m / 3, n / 3)); imge[3] = img(Rect(m / 3 * 2, 0, m / 3, n / 3)); imge[4] = img(Rect(0, n / 3, m / 3, n / 3)); imge[5] = img(Rect(m / 3, n / 3, m / 3, n / 3)); imge[6] = img(Rect(m / 3 * 2, n / 3, m / 3, n / 3)); imge[7] = img(Rect(0, n / 3 * 2, m / 3, n / 3)); imge[8] = img(Rect(m / 3, n / 3 * 2, m / 3, n / 3)); imge[9] = img(Rect(m / 3 * 2, n / 3 * 2, m / 3, n / 3)); //生成随机数 int i, j; int b[10]; //存储获取到的随机数。 int f[10] = { 0 }; //存储是否获取到过。 int nx = 1; //计数器。 srand ((unsigned) time (NULL)); //设置随机数种子。 while (nx < 10) { int my = rand () % 10; //获取一个0~9的随机数。 if (f[my]||my==0) continue ; //该数之前已经获取到过。 b[nx++] = my; //将该数存入数组。 f[my] = 1; //标记该数已经获取过。 } for (i = 1; i <= 9; i++) { a[i] = imge[b[i]]; } namedWindow( "九宫格" ); resize(a[1], imgROI1, imgROI1.size()); resize(a[2], imgROI2, imgROI2.size()); resize(a[3], imgROI3, imgROI3.size()); resize(a[4], imgROI4, imgROI4.size()); resize(a[5], imgROI5, imgROI5.size()); resize(a[6], imgROI6, imgROI6.size()); resize(a[7], imgROI7, imgROI7.size()); resize(a[8], imgROI8, imgROI8.size()); resize(a[9], imgROI9, imgROI9.size()); imshow( "九宫格" , combine); setMouseCallback( "九宫格" , onMouseHandle, ( void *)&combine); // 等待6000 ms后窗口自动关闭 waitKey(0); return 0; } int f( int xx, int yy) { int s; if (xx + yy == 2) { s = 1; } if (xx + yy == 3 && xx > yy) { s = 2; } if (xx + yy == 4 && xx > yy) { s = 3; } if (xx + yy == 3 && xx < yy) { s = 4; } if (xx + yy == 4 && xx == yy) { s = 5; } if (xx + yy == 5 && xx > yy) { s = 6; } if (xx + yy == 4 && xx < yy) { s = 7; } if (xx + yy == 5 && xx < yy) { s = 8; } if (xx + yy == 6) { s = 9; } return s; } void onMouseHandle( int event, int x, int y, int flags, void *param) { int xx ; int yy ; switch (event) { case CV_EVENT_LBUTTONDOWN : //左键单击 { xx = x / (m / 3) + 1; yy = y / (n / 3) + 1; ++t; if (t % 2 == 1) { first = f(xx, yy); } if (t % 2 == 0) { second = f(xx, yy); if (second == first + 3 || second == first - 3 || second == first + 1 || second == first - 1) { temp = a[first]; a[first] = a[second]; a[second] = temp; resize(a[1], imgROI1, imgROI1.size()); resize(a[2], imgROI2, imgROI2.size()); resize(a[3], imgROI3, imgROI3.size()); resize(a[4], imgROI4, imgROI4.size()); resize(a[5], imgROI5, imgROI5.size()); resize(a[6], imgROI6, imgROI6.size()); resize(a[7], imgROI7, imgROI7.size()); resize(a[8], imgROI8, imgROI8.size()); resize(a[9], imgROI9, imgROI9.size()); } } imshow( "九宫格" , combine); } break ; default : break ; } } |
到此这篇关于C++ Opencv实现录制九宫格视频的文章就介绍到这了,更多相关C++ Opencv九宫格视频内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/qq_51444641/article/details/124730825