C++?Opencv實(shí)現(xiàn)錄制九宮格視頻
在項(xiàng)目開始之前,我的環(huán)境已配置完成,具體環(huán)境如何配置可參考網(wǎng)絡(luò)教程。下面我們開始項(xiàng)目的實(shí)現(xiàn)
庫(kù)的導(dǎo)入
#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;//原圖片長(zhǎng)寬皆被劃分為三份,共劃分成九份
int stepwidth;//劃分后單個(gè)圖片的寬度
int stepheight;//劃分后的那個(gè)圖片的高度
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;
}
根據(jù)九宮格各張圖片以及間隔的大小生成新的畫布,用于存放新的九宮格圖片
實(shí)現(xiàn)圖片的抓取、轉(zhuǎn)換與保存
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幀的形式呈現(xiàn),共60幀圖片。
補(bǔ)充
當(dāng)然OpenCV不僅可以實(shí)現(xiàn)錄制九宮格視頻,還能制作出九宮格拼圖功能,下面是實(shí)現(xiàn)的示例代碼,感興趣的可以學(xué)習(xí)一下
#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));
//生成隨機(jī)數(shù)
int i, j;
int b[10];//存儲(chǔ)獲取到的隨機(jī)數(shù)。
int f[10] = { 0 };//存儲(chǔ)是否獲取到過。
int nx = 1; //計(jì)數(shù)器。
srand((unsigned)time(NULL));//設(shè)置隨機(jī)數(shù)種子。
while (nx < 10)
{
int my = rand() % 10; //獲取一個(gè)0~9的隨機(jī)數(shù)。
if (f[my]||my==0) continue;//該數(shù)之前已經(jīng)獲取到過。
b[nx++] = my;//將該數(shù)存入數(shù)組。
f[my] = 1;//標(biāo)記該數(shù)已經(jīng)獲取過。
}
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后窗口自動(dòng)關(guān)閉
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;
}
}
到此這篇關(guān)于C++ Opencv實(shí)現(xiàn)錄制九宮格視頻的文章就介紹到這了,更多相關(guān)C++ Opencv九宮格視頻內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)文件內(nèi)容按行隨機(jī)排列的算法示例
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)文件內(nèi)容按行隨機(jī)排列的算法,涉及C語(yǔ)言字符串、數(shù)組遍歷與隨機(jī)數(shù)相關(guān)算法實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-09-09
C語(yǔ)言實(shí)現(xiàn)最長(zhǎng)遞增子序列問題的解決方法
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)最長(zhǎng)遞增子序列問題的解決方法,采用遞歸的方法解決該問題,是非常經(jīng)典的一類算法,需要的朋友可以參考下2014-09-09
C++ 實(shí)現(xiàn)線程安全的頻率限制器(推薦)
這篇文章主要介紹了在 C++ 中實(shí)現(xiàn)一個(gè)線程安全的頻率限制器,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
詳細(xì)分析c++ const 指針與指向const的指針
這篇文章主要介紹了c++ const 指針與指向const的指針的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07
C++ OpenCV實(shí)戰(zhàn)之標(biāo)記點(diǎn)檢測(cè)的實(shí)現(xiàn)
這篇文章主要介紹了如何利用C++ OpenCV實(shí)現(xiàn)關(guān)鍵點(diǎn)的檢測(cè),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定幫助,感興趣的小伙伴可以了解一下2022-03-03
C語(yǔ)言中回調(diào)函數(shù)的含義與使用場(chǎng)景詳解
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言中回調(diào)函數(shù)的含義與使用場(chǎng)景,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03
C++實(shí)現(xiàn)矩陣原地轉(zhuǎn)置算法
這篇文章主要介紹了C++實(shí)現(xiàn)矩陣原地轉(zhuǎn)置算法,非常經(jīng)典的算法,需要的朋友可以參考下2014-08-08

