C++ Opencv实现录制九宫格视频
作者:白木木木木
这篇文章主要为大家介绍了如何利用C++和OpenCV库实现录制九宫格视频,文中的示例代码讲解详细,对我们学习OpenCV有一定帮助,感兴趣的可以了解一下
在项目开始之前,我的环境已配置完成,具体环境如何配置可参考网络教程。下面我们开始项目的实现
库的导入
#include<iostream> #include<opencv2/opencv.hpp> #include<string.h> using namespace std; using namespace cv;
这就不多说了
开启摄像头
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;
开始摄像头,并获取摄像头的像素高度与宽度
定义所需变量
int num = 3;//原图片长宽皆被划分为三份,共划分成九份 int stepwidth;//划分后单个图片的宽度 int stepheight;//划分后的那个图片的高度 int space = 5;//九宫格中每张图片的间隔
捕获图片并生成视频
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; }
根据九宫格各张图片以及间隔的大小生成新的画布,用于存放新的九宫格图片
实现图片的抓取、转换与保存
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不仅可以实现录制九宫格视频,还能制作出九宫格拼图功能,下面是实现的示例代码,感兴趣的可以学习一下
#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九宫格视频内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!