基于opencv下对视频的灰度变换,高斯滤波,canny边缘检测处理,同窗体显示并保存
2021-04-11 10:28
标签:中心 下载 函数名 基础 vs2013 create rgs 目标 问题 如题:使用opencv打开摄像头或视频文件,实时显示原始视频,将视频每一帧依次做灰度转换、高斯滤波、canny边缘检测处理(原始视频和这3个中间步骤处理结果分别在一个窗口显示),最后将边缘检测结果保存为一个视频avi文件。 这里问题综合性比较大,这里进行分治。 该类问题可分为四个方面的处理: (1)打开 视频或者是摄像头,并播放视频 (2)对视频的每一帧做处理 (3)同窗体显示四个结果 (4)保存视频文件 以下分为这三个方面进行处理: (1)打开 视频或者摄像头,并播放视频 这个利用opencv来说算是非常简单的操作了: 步骤分为四步:(简单操作,播放效果不是最佳的,适用于入门) a.创建摄像头/播放器 b.将视频文件赋值给播放器 c.逐帧播放 d.释放播放器和文件 这里直接给上源码(面向对象的方法): 使用vs2013生成解决方案后,打开window power shell进行测试。寻找到文件夹,打开相应的可执行文件 测试结果: ok.你已经成功完成第一步了。^.^ (2)对视频的每一帧做处理 a.高斯滤波 百度百科的解释:高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。 这里有opencv封装好的方法可以直接操作,这里采用的是cvSmooth的方法,然后填入核函数CV_GAUSSIAN,设置图像源和转变后的接收源。 按照(1)中进行测试,结果: 看上去有点模糊了。 b.灰度变换 百度百科的解释:灰度变换是指根据某种目标条件按一定变换关系逐点改变源图像中每一个像素灰度值的方法。目的是为了改善画质,使图像的显示效果更加清晰。 图像的灰度变换处理是图像增强处理技术中的一种非常基础、直接的空间域图像处理方法,也是图像数字化软件和图像显示软件的一个重要组成部分。 同理,opencv也提供的灰度变化的函数,这里要注意的是转变的时候都是通道变成1 这里多一步的目的是为了后面多个图像显示在一块窗口上(如果不考虑同窗体显示的话就不需要统一通道数) 结果测试: 灰度效果显示出来了。 c.Canny边缘检测 百度百科的解释:Canny 算法使用 4 个 mask 检测水平、垂直以及对角线方向的边缘。原始图像与每个 mask 所作的卷积都存储起来。对于每个点我们都标识在这个点上的最大值以及生成的边缘的方向。 这里使用cvCanny的方法进行转变,但是这个cvCanny边缘检测还需要弄成灰度图。 同样也要统一通道数。 测试结果: 这样我们三个图像处理就完成了。^.^ (3)同窗体显示四个结果 这里参考了CSDN上的一个方法https://blog.csdn.net/augusdi/article/details/9019473 作者稍作整理了下,站在巨人的肩膀上。 这里加入一个多视频播放处理: 结果测试: 成功生成,这里注意一点就是如果放入的图片不是同一通道的话,会报错。 (4)保存视频文件 保存视频就比较简单了。 a.创建视频记录器 CvVideoWriter* writer; b.初始化视频记录器 如初始化代码所示 c.视频记录器记录每一帧 如播放功能代码所示 d.释放视频记录器 如释放代码所示 ok,在window power shell输入的时候要加上保存地址了 视频停止或者终止后,在相应文件下就生成了新文件.avi了 如需要源码请转移至码云:https://gitee.com/cjqbaba/MediaTest/tree/Capture_show进行源码克隆下载 如有问题请留言评论。转载请注明出处,谢谢。 基于opencv下对视频的灰度变换,高斯滤波,canny边缘检测处理,同窗体显示并保存 标签:中心 下载 函数名 基础 vs2013 create rgs 目标 问题 原文地址:https://www.cnblogs.com/cjqbaba/p/9023802.html 1 /******************************************************
2 文件名 :main.cpp
3 描 述 :灰度转换、高斯滤波、canny边缘检测处理视频,并存储canny边缘处理的视频
4 语 言 :c++
5 作 者 :重交亲爸爸
6 修 改 :
7 日 期 :2018-05-10
8 说 明 :opencv的支持
9 ******************************************************/
10 #include
1 /******************************************************
2 函数名称: R_Gussian
3 函数功能: 返回高斯滤波处理
4 传入参数:
5 返 回 值:
6 建立时间: 2018-05-10
7 修改时间:
8 建 立 人:
9 修 改 人:
10 其它说明:
11 ******************************************************/
12 IplImage* MyClass::R_Gussian(IplImage* frame){
13 //IplImage* edges = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, image->nChannels);
14 IplImage* edges = cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels);
15 cvSmooth(frame, edges, CV_GAUSSIAN, 7, frame->nChannels); // Gauss平滑滤波,核大小为7x7
16 return edges;
17 }
/******************************************************
函数名称: R_Gray
函数功能: 返回灰度处理
传入参数:
返 回 值:
建立时间: 2018-05-10
修改时间:
建 立 人:
修 改 人:
其它说明:由于需要在同一个窗体显示,需要将通道数目统一,不能使用单通道
******************************************************/
IplImage* MyClass::R_Gray(IplImage* frame){
//IplImage* edges = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
//IplImage *frame_gray = cvCreateImage(cvGetSize(image), frame->depth, 1);
/*IplImage* edges = cvCreateImage(cvGetSize(imagesrc), imagesrc->depth, imagesrc->nChannels);
cvCvtColor(frame, edges, CV_BGR2GRAY);
return edges;*/
IplImage *frame_gray = cvCreateImage(cvGetSize(frame), frame->depth, 1);
IplImage *frame1 = cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels);
cvCvtColor(frame, frame_gray, CV_RGB2GRAY);
cvCvtColor(frame_gray, frame1, CV_GRAY2BGR);//见说明
return frame1;
}
1 /******************************************************
2 函数名称: R_Canny
3 函数功能: 返回Canny边缘处理
4 传入参数:
5 返 回 值:
6 建立时间: 2018-05-10
7 修改时间:
8 建 立 人:
9 修 改 人:
10 其它说明: 由于需要在同一个窗体显示,需要将通道数目统一,不能使用单通道
11 ******************************************************/
12 IplImage* MyClass::R_Canny(IplImage* frame){
13 //IplImage* edges = cvCreateImage(cvGetSize(grayimage), IPL_DEPTH_8U, 1);
14 IplImage *frame_gray = cvCreateImage(cvGetSize(frame), frame->depth, 1);
15 IplImage *frame1 = cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels);
16 cvCanny(frame, frame_gray, 20, 75, 3);
17 cvCvtColor(frame_gray, frame1, CV_GRAY2BGR);
18 return frame1;
19 }
1 /******************************************************
2 函数名称: cvShowManyImages
3 函数功能: 展示多个图片
4 传入参数: const char* title, int nArgs
5 返 回 值:
6 建立时间: 2018-05-10
7 修改时间:
8 建 立 人: CSDN Augusdi
9 修 改 人:
10 其它说明:
11 ******************************************************/
12 void MyClass::cvShowManyImages(const char* title, int nArgs, ...){
13 // img - Used for getting the arguments
14 IplImage *img;
15
16 // DispImage - the image in which input images are to be copied
17 IplImage *DispImage;
18
19 int size;
20 int i;
21 int m, n;
22 int x, y;
23
24 // w - Maximum number of images in a row
25 // h - Maximum number of images in a column
26 int w, h;
27
28 // scale - How much we have to resize the image
29 float scale;
30 int max;
31
32 // If the number of arguments is lesser than 0 or greater than 12
33 // return without displaying
34 if (nArgs 0) {
35 printf("Number of arguments too small....n");
36 return;
37 }
38 else if (nArgs > 12) {
39 printf("Number of arguments too large....n");
40 return;
41 }
42 // Determine the size of the image,
43 // and the number of rows/cols
44 // from number of arguments
45 else if (nArgs == 1) {
46 w = h = 1;
47 size = 300;
48 }
49 else if (nArgs == 2) {
50 w = 2; h = 1;
51 size = 300;
52 }
53 else if (nArgs == 3 || nArgs == 4) {
54 w = 2; h = 2;
55 size = 300;
56 }
57 else if (nArgs == 5 || nArgs == 6) {
58 w = 3; h = 2;
59 size = 200;
60 }
61 else if (nArgs == 7 || nArgs == 8) {
62 w = 4; h = 2;
63 size = 200;
64 }
65 else {
66 w = 4; h = 3;
67 size = 150;
68 }
69
70 // Create a new 3 channel image
71 DispImage = cvCreateImage(cvSize(100 + size*w, 60 + size*h), 8, 3);
72
73 // Used to get the arguments passed
74 va_list args;
75 va_start(args, nArgs);
76
77 // Loop for nArgs number of arguments
78 for (i = 0, m = 20, n = 20; i 20 + size)) {
79
80 // Get the Pointer to the IplImage
81 img = va_arg(args, IplImage*);
82
83 // Check whether it is NULL or not
84 // If it is NULL, release the image, and return
85 if (img == 0) {
86 printf("Invalid arguments");
87 cvReleaseImage(&DispImage);
88 return;
89 }
90
91 // Find the width and height of the image
92 x = img->width;
93 y = img->height;
94
95 // Find whether height or width is greater in order to resize the image
96 max = (x > y) ? x : y;
97
98 // Find the scaling factor to resize the image
99 scale = (float)((float)max / size);
100
101 // Used to Align the images
102 if (i % w == 0 && m != 20) {
103 m = 20;
104 n += 20 + size;
105 }
106
107 // Set the image ROI to display the current image
108 cvSetImageROI(DispImage, cvRect(m, n, (int)(x / scale), (int)(y / scale)));
109
110 // Resize the input image and copy the it to the Single Big Image
111 cvResize(img, DispImage);
112
113 // Reset the ROI in order to display the next image
114 cvResetImageROI(DispImage);
115 }
116
117 // Create a new window, and show the Single Big Image
118 //cvNamedWindow( title, 1 );
119 cvShowImage(title, DispImage);
120
121 //cvDestroyWindow(title);
122
123 // End the number of arguments
124 va_end(args);
125
126 // Release the Image Memory
127 cvReleaseImage(&DispImage);
128 }
/******************************************************
函数名称: Multi_play
函数功能: 播放
传入参数:
返 回 值:
建立时间: 2018-05-10
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
void MyClass::Multi_play(){
IplImage *frame;
cvNamedWindow("播放页面按Esc退出", 1);
cvResizeWindow("播放页面按Esc退出", 700, 660);
while (true)
{
frame = cvQueryFrame(capture);
if (!frame)break;
IplImage* grayimage = R_Gray(frame);
IplImage* gsimage = R_Gussian(frame);
IplImage* cnimage = R_Canny(frame);
//IplImage *frame_not = cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels);//负片
//cvNot(frame, frame_not);
//cvShowImage("播放页面按Esc退出", R_Canny(R_Gray(frame)));
//cvWriteFrame(writer, cnimage);
cvShowManyImages("播放页面按Esc退出", 4, frame, grayimage, gsimage, cnimage);
char c = cvWaitKey(33);
if (c == 27)break;
cvReleaseImage(&grayimage);
cvReleaseImage(&gsimage);
cvReleaseImage(&cnimage);
//cvReleaseImage(&frame_not);
}
}
1 /******************************************************
2 函数名称: MyClass
3 函数功能: 初始化
4 传入参数:
5 返 回 值:
6 建立时间: 2018-05-10
7 修改时间:
8 建 立 人:
9 修 改 人:
10 其它说明:
11 ******************************************************/
12 MyClass::MyClass(char* argv,char* filepath)
13 {
14 //capture = cvCreateFileCapture(argv[1]);
15 capture = cvCreateFileCapture(argv);
16 if (!cvGetCaptureProperty(capture, CAP_PROP_FRAME_COUNT))
17 {
18 exit(1);
19 }
20 double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
21 CvSize size = cvSize(
22 (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH),
23 (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT)
24 );
25 writer = cvCreateVideoWriter(
26 filepath,
27 CV_FOURCC(‘M‘, ‘J‘, ‘P‘, ‘G‘),
28 fps,
29 size
30 );
31 }
32 /******************************************************
33 函数名称: ~MyClass
34 函数功能: 释放空间
35 传入参数:
36 返 回 值:
37 建立时间: 2018-05-10
38 修改时间:
39 建 立 人:
40 修 改 人:
41 其它说明:
42 ******************************************************/
43 MyClass::~MyClass()
44 {
45 cvReleaseVideoWriter(&writer);
46 cvReleaseCapture(&capture);
47 writer = NULL;
48 capture = NULL;
49 }
50 /******************************************************
51 函数名称: Multi_play
52 函数功能: 播放
53 传入参数:
54 返 回 值:
55 建立时间: 2018-05-10
56 修改时间:
57 建 立 人:
58 修 改 人:
59 其它说明:
60 ******************************************************/
61 void MyClass::Multi_play(){
62 IplImage *frame;
63 cvNamedWindow("播放页面按Esc退出", 1);
64 cvResizeWindow("播放页面按Esc退出", 700, 660);
65 while (true)
66 {
67 frame = cvQueryFrame(capture);
68 if (!frame)break;
69 IplImage* grayimage = R_Gray(frame);
70 IplImage* gsimage = R_Gussian(frame);
71 IplImage* cnimage = R_Canny(frame);
72 IplImage *frame_not = cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels);
73 cvNot(frame, frame_not);
74 //cvShowImage("播放页面按Esc退出", R_Canny(R_Gray(frame)));
75 cvWriteFrame(writer, cnimage);
76 cvShowManyImages("播放页面按Esc退出", 4, frame, grayimage, gsimage, cnimage);
77 char c = cvWaitKey(33);
78 if (c == 27)break;
79
80 cvReleaseImage(&grayimage);
81 cvReleaseImage(&gsimage);
82 cvReleaseImage(&cnimage);
83 cvReleaseImage(&frame_not);
84 }
85 }
文章标题:基于opencv下对视频的灰度变换,高斯滤波,canny边缘检测处理,同窗体显示并保存
文章链接:http://soscw.com/index.php/essay/74230.html