服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++ Opencv实现录制九宫格视频

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

2022-12-01 14:14白木木木木 C/C++

这篇文章主要为大家介绍了如何利用C++和OpenCV库实现录制九宫格视频,文中的示例代码讲解详细,对我们学习OpenCV有一定帮助,感兴趣的可以了解一下

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

库的导入

?
1
2
3
4
5
#include<iostream>
#include<opencv2/opencv.hpp>
#include<string.h>
using namespace std;
using namespace cv;

这就不多说了

开启摄像头

?
1
2
3
4
5
6
7
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;

开始摄像头,并获取摄像头的像素高度与宽度

定义所需变量

?
1
2
3
4
int num = 3;//原图片长宽皆被划分为三份,共划分成九份
int stepwidth;//划分后单个图片的宽度
int stepheight;//划分后的那个图片的高度
int space = 5;//九宫格中每张图片的间隔

捕获图片并生成视频

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}

根据九宫格各张图片以及间隔的大小生成新的画布,用于存放新的九宫格图片

实现图片的抓取、转换与保存

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    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不仅可以实现录制九宫格视频,还能制作出九宫格拼图功能,下面是实现的示例代码,感兴趣的可以学习一下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#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九宫格视频内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_51444641/article/details/124730825

延伸 · 阅读

精彩推荐
  • C/C++C++ 中指针和引用有什么区别详解

    C++ 中指针和引用有什么区别详解

    这篇文章主要介绍了C++ 中指针和引用有什么区别详解的相关资料,需要的朋友可以参考下...

    卫斯理5252021-05-10
  • C/C++C++编程小心指针被delete两次

    C++编程小心指针被delete两次

    这篇文章主要介绍了C++编程指针被delete两次的严重后果,以实例阐述了C++指针使用中的误区和注意点,需要的朋友可以参考下...

    C++教程网11782021-01-22
  • C/C++c++连接mysql数据库的两种方法(ADO连接和mysql api连接)

    c++连接mysql数据库的两种方法(ADO连接和mysql api连接)

    现在正做一个接口,通过不同的连接字符串操作不同的数据库。要用到mysql数据库,C++连接mysql有2种方法:利用ADO连接、利用mysql自己的api函数进行连接,下...

    zxhpj11762021-01-11
  • C/C++C++如何过滤出字符串的中文(GBK、UTF-8)

    C++如何过滤出字符串的中文(GBK、UTF-8)

    这篇文章主要给大家介绍了关于C++如何过滤出字符串的中文的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价...

    梦涵的帅爸爸11872021-07-31
  • C/C++C语言的随机数rand()函数详解

    C语言的随机数rand()函数详解

    这篇文章主要为大家详细介绍了C语言的随机数rand()函数,使用数据库,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一...

    嵌入式@hxydj3642022-09-27
  • C/C++C++深入探索类真正的形态之struct与class

    C++深入探索类真正的形态之struct与class

    前边我们所定义的类,均是使用struct关键字来定义,但是C++中真正用于定义类的关键字为class,因为要C++兼容C,所以保留struct关键字,struct与class的用法完...

    清风自在 流水潺潺4032022-11-12
  • C/C++C语言实现通用数据结构之通用映射(HashMap)

    C语言实现通用数据结构之通用映射(HashMap)

    这篇文章主要为大家详细介绍了C语言实现通用数据结构之通用映射,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    swwlqw8712022-03-05
  • C/C++C语言实现直角坐标转换为极坐标的方法

    C语言实现直角坐标转换为极坐标的方法

    这篇文章主要介绍了C语言实现直角坐标转换为极坐标的方法,涉及C语言进行三角函数与数值运算相关操作技巧,需要的朋友可以参考下...

    e4210834587472021-05-31