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

到此這篇關於C++ Opencv實現錄制九宮格視頻的文章就介紹到這瞭,更多相關C++ Opencv九宮格視頻內容請搜索LevelAH以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持LevelAH!

推薦閱讀: