当前位置:主页 > 软件编程 > C代码 >

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

时间:2022-11-04 09:53:55 | 栏目:C代码 | 点击:

在项目开始之前,我的环境已配置完成,具体环境如何配置可参考网络教程。下面我们开始项目的实现

库的导入

#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;
}
}

您可能感兴趣的文章:

相关文章