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

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

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

库的导入

#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

标签:C++,Opencv,九宫格,视频
0
投稿

猜你喜欢

  • IDEA插件之彩虹括号Rainbow Brackets使用介绍

    2022-03-14 09:09:51
  • C#中把英文字母转换为大写或小写的方法

    2021-06-13 18:46:55
  • Winform项目中TextBox控件DataBindings属性

    2023-03-29 15:25:15
  • Flutter质感设计之持久底部面板

    2021-10-19 07:54:18
  • 通过实例解析JMM和Volatile底层原理

    2023-05-20 19:10:48
  • 详解微信小程序 同步异步解决办法

    2022-08-14 00:08:58
  • C#并发编程入门教程之概述

    2022-08-08 09:44:23
  • Java常用排序算法及性能测试集合

    2022-01-15 22:29:09
  • Android使用CrashHandler来获取应用的crash信息的方法

    2023-07-25 20:27:38
  • Java中工具Jstack的使用实例

    2023-07-26 15:18:02
  • Java毕业设计实战之校园一卡通系统的实现

    2022-11-26 06:32:56
  • SpringBoot YAML语法基础详细整理

    2023-04-16 14:15:30
  • java使用jacob实现word转pdf

    2023-05-12 11:45:33
  • 不依赖于Activity的Android全局悬浮窗的实现

    2022-04-08 00:42:43
  • SpringBoot任务之详解邮件任务

    2021-08-12 12:49:16
  • java 中 poi解析Excel文件版本问题解决办法

    2023-11-15 16:49:45
  • Java集合中的fail-fast(快速失败)机制详解

    2023-05-10 16:31:33
  • C# 输出参数out问题

    2023-02-27 00:19:32
  • AOP从静态代理到动态代理(Emit实现)详解

    2023-11-27 14:49:56
  • Winform应用程序如何使用自定义的鼠标图片

    2021-07-09 16:01:24
  • asp之家 软件编程 m.aspxhome.com