软件编程
位置:首页>> 软件编程>> C语言>> C++ Opencv实现录制九宫格视频

C++ Opencv实现录制九宫格视频

作者:白木木木木  发布时间:2023-08-16 04:11:28 

标签:C++,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;
}
}

来源:https://blog.csdn.net/qq_51444641/article/details/124730825

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com