1、如果你是某BNUer,还在为某多媒体课的作业而烦恼,那么看看我这篇文章或许能够帮助你成功肝完DDL!
2、如果你只是想尝试一下Laplace做边缘检测,那么走过路过不要错过,看看我这篇文章真的是来对地方了!
文章内容:
- 一、实验要求
- 二、实验环境配置
- 1、visual studio + OpenCV的配置
- (1)环境说明
- (2)OpenCV的下载
- (3)OpenCV的配置
- 三、运行源代码
- 1、出现的问题及解决方法
- (1)运行代码时出现了如下问题
- (2)解决方法
- 2、从AVI文件中得到视频流,进行laplace边缘检测的代码 :
- 3、从摄像头中得到视频流进行laplace边缘检测的代码 :
- 四、参考资料
一、实验要求
实验要求:
从AVI文件( bsd.avi)中得到视频流,对视频流进行Laplace边缘检测,并输出结果。
注:
1、Laplace边缘检测
2、主要思想
实验环境: OpenCV2.4.13.6 + visual studio 2019
二、实验环境配置
1、visual studio + OpenCV的配置
(1)环境说明
笔者使用的实验环境是 visual studio 2019 + OpenCV 2.4.13.6。visual studio的安装教程网上有很多,在此就不多bb怎么安装了。这里主要以visual studio 2019为例来讲解如何配置OpenCV 2.4.13.6。各版本配置的方法都差不多,但是需要搜索和下载对应的OpenCV版本,不然的话容易出现一些问题。
如果是其他版本的VS和opencv可以参考一下这个链接https://blog.csdn.net/xinjiang666/article/details/80785210
(2)OpenCV的下载
方式1 :点击下载Opencv2.4.13.6安装包
方式2 :点击官网下载对应版本
(3)OpenCV的配置
1、双击下载好的OpenCV
2、选择好全英文路径并点击Extract
3、可以看到E:OpenCV路径下已经有了一个叫opencv的目录
4、点击进去可以看到opencv中包含的内容
5、添加系统环境变量(x64的版本)
此电脑(我的电脑)——>右键——>属性——>高级系统设置——>环境变量——>系统变量——>path——>编辑——>新建,然后添加刚才opencv目录下对应到bin的路径
6、打开visual studio 2019,点击创建新项目,新建C++控制台应用程序
7、将下图中的x86改为x64
8、视图–>其他窗口–>属性管理器。
9、Debug | x64 ——>右键——>添加新项目属性表
10、添加包含目录
右键刚才新建的属性表——>属性——>VC++目录——>包含目录
添加下面的三个路径(需要根据自己opencv路径自行修改):
11、添加库目录
VC++目录——>库目录——>编辑
12、添加附加依赖项
链接器——>输入——>附加依赖项,可以将下面的内容直接复制到附加依赖项中
opencv_calib3d2413d.lib
opencv_contrib2413d.lib
opencv_core2413d.lib
opencv_features2d2413d.lib
opencv_flann2413d.lib
opencv_gpu2413d.lib
opencv_highgui2413d.lib
opencv_imgproc2413d.lib
opencv_legacy2413d.lib
opencv_ml2413d.lib
opencv_nonfree2413d.lib
opencv_objdetect2413d.lib
opencv_ocl2413d.lib
opencv_photo2413d.lib
opencv_stitching2413d.lib
opencv_superres2413d.lib
opencv_video2413d.lib
opencv_videostab2413d.lib
好的,进行完这一步,说明已经将环境配置好了,接下来可以尝试运行代码了,nice!
三、运行源代码
1、出现的问题及解决方法
(1)运行代码时出现了如下问题
warning MSB8003: 未定义 WindowsSDKDir 属性。可能找不到某些生成工具
(2)解决方法
参考https://blog.csdn.net/dongbao520/article/details/117289543
用Visual Studio Installer进行修复
2、从AVI文件中得到视频流,进行laplace边缘检测的代码 :
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/* 功能:从摄像头或者AVI文件中得到视频流,对视频流进行边缘检测,并输出结果。 */ #include "cv.h" #include "highgui.h" #include <ctype.h> #include <stdio.h> int main(int argc, char** argv) { IplImage* laplace = 0; IplImage* colorlaplace = 0; IplImage* planes[3] = { 0, 0, 0 }; // 多个图像面 CvCapture* capture = 0;//初始化为0,若在后面不对capture的值做修改,则从摄像头获得视频流 //CvCapture //视频获取结构 //typedef struct CvCapture CvCapture; /*结构CvCapture 没有公共接口,它只能被用来作为视频获取函数的一个参数。 下面的语句说明在命令行执行程序时,如果指定AVI文件,那么处理从 AVI文件读取的视频流,如果不指定输入变量,那么处理从摄像头获取的视频流*/ /* if (argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) capture = cvCaptureFromCAM(argc == 2 ? argv[1][0] - '0' : 0); else if (argc == 2) capture = cvCaptureFromAVI(argv[1]); */ //获取视频,不需要上面的if...else语句,需要改为自己电脑上对应的路径 capture = cvCaptureFromAVI( "E://1qq document//bsd.avi" ); if (!capture) //获取视频失败 { fprintf(stderr, "Could not initialize capturing.../n"); return -1; } cvNamedWindow("Laplacian", 0); // 循环捕捉,直到用户按键跳出循环体 for (;;) { IplImage* frame = 0; int i; //cvQueryFrame // //从摄像头或者文件中抓取并返回一帧 //IplImage* cvQueryFrame( CvCapture* capture ); //capture //视频获取结构。 //函数cvQueryFrame从摄像头或者文件中抓取一帧,然后解压并返回这一帧。 //这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。 //返回的图像不可以被用户释放或者修改。 抓取后,capture被指向下一帧, //可用cvSetCaptureProperty调整capture到合适的帧。 // //注意: cvQueryFrame返回的指针总是指向同一块内存。建议cvQueryFrame后拷贝一份 //。而且返回的帧需要FLIP后才符合OPENCV的坐标系。 若返回值为NULL,说明到了视频的最后一帧。 frame = cvQueryFrame(capture); if (!frame) break; if (!laplace) { for (i = 0; i < 3; i++) planes[i] = cvCreateImage(cvSize(frame->width, frame->height), 8, 1); //CreateImage /* 创建头并分配数据 IplImage* cvCreateImage( CvSize size, int depth, int channels ); size 图像宽、高. depth 图像元素的位深度,可以是下面的其中之一: IPL_DEPTH_8U - 无符号8位整型 IPL_DEPTH_8S - 有符号8位整型 IPL_DEPTH_16U - 无符号16位整型 IPL_DEPTH_16S - 有符号16位整型 IPL_DEPTH_32S - 有符号32位整型 IPL_DEPTH_32F - 单精度浮点数 IPL_DEPTH_64F - 双精度浮点数 channels 每个元素(像素)的颜色通道数量.可以是 1, 2, 3 或 4.通道是交叉存取的,例如通常的彩色图像数据排列是: b0 g0 r0 b1 g1 r1 ... 虽然通常 IPL 图象格式可以存贮非交叉存取的图像,并且一些OpenCV 也能处理他, 但是这个函数只能创建交叉存取图像. 函数 cvCreateImage 创建头并分配数据,这个函数是下列的缩写型式 header = cvCreateImageHeader(size,depth,channels); cvCreateData(header); //只是创建空间,并不会初始化空间内的数据 */ laplace = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_16S, 1); colorlaplace = cvCreateImage(cvSize(frame->width, frame->height), 8, 3); } //cvCvtPixToPlane /* openCV里面的一个函数 可以看作cvSplit是他的宏: #define cvCvtPixToPlane cvSplit void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,CvArr* dst2, CvArr* dst3 ); 作用是:分割多通道数组成几个单通道数组或者从数组中提取一个通道 一般用法是cvCvtPixToPlane(IplImage * src,IplImage * dst1,IplImage *dst2,IplImage * dst3,IplImage *dst4) 第一个参数是源图像,后面是分离出来每个通道的目标图像,如果圆筒到时3通道的,可以把最后一个参数设置为空。 例如cvCvtPixToPlane(IplImage * src,IplImage * dst1,IplImage *dst2,IplImage * dst3,NULL) */ cvCvtPixToPlane(frame, planes[0], planes[1], planes[2], 0); for (i = 0; i < 3; i++) { // Laplace //计算图像的 Laplacian 变换 //void cvLaplace( const CvArr* src, CvArr* dst, int aperture_size=3 ); //src //输入图像. //dst //输出图像. //aperture_size //核大小 (与 cvSobel 中定义一样). //在每个通道内进行Laplace变换,计算图像的边缘信息 cvLaplace(planes[i], laplace, 3); // 3: aperture_size //ConvertScaleAbs //使用线性变换转换输入数组元素成8位无符号整型 //void cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 ); //#define cvCvtScaleAbs cvConvertScaleAbs //src //原数组 //dst //输出数组 (深度为 8u). //scale //比例因子. //shift //原数组元素按比例缩放后添加的值。 //函数 cvConvertScaleAbs 与前一函数是相同的,但它是存贮变换结果的绝对值: //dst(I)=abs(src(I)*scale + (shift,shift,...)) //函数只支持目标数数组的深度为 8u (8-bit 无符号) , 对于别的类型函数仿效于cvConvertScale 和 cvAbs 函数的联合 cvConvertScaleAbs(laplace, planes[i], 1, 0); // planes[] = ABS(laplace) } //cvCvtPixToPlane是cvCvtPlaneToPix的逆函数,恢复多通道图像并显示 cvCvtPlaneToPix(planes[0], planes[1], planes[2], 0, colorlaplace); //IplImage // IPL 图像头 // typedef struct _IplImage //{ // int nSize; /* IplImage大小,=sizeof(IplImage)*/ // int ID; /* 版本 (=0)*/ // int nChannels; /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */ // int alphaChannel; /* 被OpenCV忽略 */ // int depth; /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, // IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */ // char colorModel[4]; /* 被OpenCV忽略 */ // char channelSeq[4]; /* 被OpenCV忽略 */ // int dataOrder; /* 0 - 交叉存取颜色通道,对三通道RGB图像,像素存储顺序为BGR BGR BGR ... BGR; // 1 - 分开的颜色通道,对三通道RGB图像,像素存储顺序为RRR...R GGG...G BBB...B。 // cvCreateImage只能创建交叉存取图像 */ // int origin; /* 0 - 顶—左结构, // 1 - 底—左结构 (Windows bitmaps 风格) */ // int align; /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */ // int width; /* 图像宽像素数 */ // int height; /* 图像高像素数*/ // struct _IplROI *roi;/* 图像感兴趣区域. 当该值非空只对该区域进行处理 */ // struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */ // void *imageId; /* 同上*/ // struct _IplTileInfo *tileInfo; /*同上*/ // int imageSize; /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/ // char *imageData; /* 指向排列的图像数据 */ // int widthStep; /* 排列的图像行大小,以字节为单位 */ // int BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */ // int BorderConst[4]; /* 同上 */ // char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */ //} // IplImage; //IplImage结构来自于 Intel Image Processing Library(是其本身所具有的)。OpenCV 只支持其中的一个子集: //alphaChannel 在OpenCV中被忽略。 //colorModel 和channelSeq 被OpenCV忽略。OpenCV颜色转换的唯一函数 cvCvtColor把原图像的颜色空间的目标图像的颜色空间作为一个参数。 //dataOrder 必须是IPL_DATA_ORDER_PIXEL (颜色通道是交叉存取),然而平面图像的被选择通道可以被处理,就像COI(感兴趣的通道)被设置过一样。 //align 是被OpenCV忽略的,而用 widthStep 去访问后继的图像行。 //不支持maskROI 。处理MASK的函数把他当作一个分离的参数。MASK在 OpenCV 里是 8-bit,然而在 IPL他是 1-bit。 //tileInfo 不支持。 //BorderMode和BorderConst是不支持的。每个 OpenCV 函数处理像素的邻近的像素,通常使用单一的固定代码边际模式。 //除了上述限制,OpenCV处理ROI有不同的要求。要求原图像和目标图像的尺寸或 ROI的尺寸必须(根据不同的操作, //例如cvPyrDown 目标图像的宽(高)必须等于原图像的宽(高)除以2 ±1)精确匹配,而IPL处理交叉区域,如图像的大小或ROI大小可能是完全独立的。 colorlaplace->origin = frame->origin; //让他们结构一致 cvShowImage("Laplacian", colorlaplace); if (cvWaitKey(10) >= 0) break; } cvReleaseCapture(&capture);//释放视频 cvDestroyWindow("Laplacian");//关掉视频播放窗口 return 0; }
3、从摄像头中得到视频流进行laplace边缘检测的代码 :
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/* 功能:从摄像头或者AVI文件中得到视频流,对视频流进行边缘检测,并输出结果。 */ #include "cv.h" #include "highgui.h" #include <ctype.h> #include <stdio.h> int main(int argc, char** argv) { IplImage* laplace = 0; IplImage* colorlaplace = 0; IplImage* planes[3] = { 0, 0, 0 }; // 多个图像面 CvCapture* capture = 0;//初始化为0,若在后面不对capture的值做修改,则从摄像头获得视频流 //CvCapture //视频获取结构 //typedef struct CvCapture CvCapture; /*结构CvCapture 没有公共接口,它只能被用来作为视频获取函数的一个参数。 下面的语句说明在命令行执行程序时,如果指定AVI文件,那么处理从 AVI文件读取的视频流,如果不指定输入变量,那么处理从摄像头获取的视频流*/ if (argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) capture = cvCaptureFromCAM(argc == 2 ? argv[1][0] - '0' : 0); else if (argc == 2) capture = cvCaptureFromAVI(argv[1]); //获取视频,不需要上面的if...else语句,需要改为自己电脑上对应的路径 //capture = cvCaptureFromAVI( "E://1qq document//bsd.avi" ); if (!capture) //获取视频失败 { fprintf(stderr, "Could not initialize capturing.../n"); return -1; } cvNamedWindow("Laplacian", 0); // 循环捕捉,直到用户按键跳出循环体 for (;;) { IplImage* frame = 0; int i; //cvQueryFrame // //从摄像头或者文件中抓取并返回一帧 //IplImage* cvQueryFrame( CvCapture* capture ); //capture //视频获取结构。 //函数cvQueryFrame从摄像头或者文件中抓取一帧,然后解压并返回这一帧。 //这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。 //返回的图像不可以被用户释放或者修改。 抓取后,capture被指向下一帧, //可用cvSetCaptureProperty调整capture到合适的帧。 // //注意: cvQueryFrame返回的指针总是指向同一块内存。建议cvQueryFrame后拷贝一份 //。而且返回的帧需要FLIP后才符合OPENCV的坐标系。 若返回值为NULL,说明到了视频的最后一帧。 frame = cvQueryFrame(capture); if (!frame) break; if (!laplace) { for (i = 0; i < 3; i++) planes[i] = cvCreateImage(cvSize(frame->width, frame->height), 8, 1); //CreateImage /* 创建头并分配数据 IplImage* cvCreateImage( CvSize size, int depth, int channels ); size 图像宽、高. depth 图像元素的位深度,可以是下面的其中之一: IPL_DEPTH_8U - 无符号8位整型 IPL_DEPTH_8S - 有符号8位整型 IPL_DEPTH_16U - 无符号16位整型 IPL_DEPTH_16S - 有符号16位整型 IPL_DEPTH_32S - 有符号32位整型 IPL_DEPTH_32F - 单精度浮点数 IPL_DEPTH_64F - 双精度浮点数 channels 每个元素(像素)的颜色通道数量.可以是 1, 2, 3 或 4.通道是交叉存取的,例如通常的彩色图像数据排列是: b0 g0 r0 b1 g1 r1 ... 虽然通常 IPL 图象格式可以存贮非交叉存取的图像,并且一些OpenCV 也能处理他, 但是这个函数只能创建交叉存取图像. 函数 cvCreateImage 创建头并分配数据,这个函数是下列的缩写型式 header = cvCreateImageHeader(size,depth,channels); cvCreateData(header); //只是创建空间,并不会初始化空间内的数据 */ laplace = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_16S, 1); colorlaplace = cvCreateImage(cvSize(frame->width, frame->height), 8, 3); } //cvCvtPixToPlane /* openCV里面的一个函数 可以看作cvSplit是他的宏: #define cvCvtPixToPlane cvSplit void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,CvArr* dst2, CvArr* dst3 ); 作用是:分割多通道数组成几个单通道数组或者从数组中提取一个通道 一般用法是cvCvtPixToPlane(IplImage * src,IplImage * dst1,IplImage *dst2,IplImage * dst3,IplImage *dst4) 第一个参数是源图像,后面是分离出来每个通道的目标图像,如果圆筒到时3通道的,可以把最后一个参数设置为空。 例如cvCvtPixToPlane(IplImage * src,IplImage * dst1,IplImage *dst2,IplImage * dst3,NULL) */ cvCvtPixToPlane(frame, planes[0], planes[1], planes[2], 0); for (i = 0; i < 3; i++) { // Laplace //计算图像的 Laplacian 变换 //void cvLaplace( const CvArr* src, CvArr* dst, int aperture_size=3 ); //src //输入图像. //dst //输出图像. //aperture_size //核大小 (与 cvSobel 中定义一样). //在每个通道内进行Laplace变换,计算图像的边缘信息 cvLaplace(planes[i], laplace, 3); // 3: aperture_size //ConvertScaleAbs //使用线性变换转换输入数组元素成8位无符号整型 //void cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 ); //#define cvCvtScaleAbs cvConvertScaleAbs //src //原数组 //dst //输出数组 (深度为 8u). //scale //比例因子. //shift //原数组元素按比例缩放后添加的值。 //函数 cvConvertScaleAbs 与前一函数是相同的,但它是存贮变换结果的绝对值: //dst(I)=abs(src(I)*scale + (shift,shift,...)) //函数只支持目标数数组的深度为 8u (8-bit 无符号) , 对于别的类型函数仿效于cvConvertScale 和 cvAbs 函数的联合 cvConvertScaleAbs(laplace, planes[i], 1, 0); // planes[] = ABS(laplace) } //cvCvtPixToPlane是cvCvtPlaneToPix的逆函数,恢复多通道图像并显示 cvCvtPlaneToPix(planes[0], planes[1], planes[2], 0, colorlaplace); //IplImage // IPL 图像头 // typedef struct _IplImage //{ // int nSize; /* IplImage大小,=sizeof(IplImage)*/ // int ID; /* 版本 (=0)*/ // int nChannels; /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */ // int alphaChannel; /* 被OpenCV忽略 */ // int depth; /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, // IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */ // char colorModel[4]; /* 被OpenCV忽略 */ // char channelSeq[4]; /* 被OpenCV忽略 */ // int dataOrder; /* 0 - 交叉存取颜色通道,对三通道RGB图像,像素存储顺序为BGR BGR BGR ... BGR; // 1 - 分开的颜色通道,对三通道RGB图像,像素存储顺序为RRR...R GGG...G BBB...B。 // cvCreateImage只能创建交叉存取图像 */ // int origin; /* 0 - 顶—左结构, // 1 - 底—左结构 (Windows bitmaps 风格) */ // int align; /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */ // int width; /* 图像宽像素数 */ // int height; /* 图像高像素数*/ // struct _IplROI *roi;/* 图像感兴趣区域. 当该值非空只对该区域进行处理 */ // struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */ // void *imageId; /* 同上*/ // struct _IplTileInfo *tileInfo; /*同上*/ // int imageSize; /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/ // char *imageData; /* 指向排列的图像数据 */ // int widthStep; /* 排列的图像行大小,以字节为单位 */ // int BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */ // int BorderConst[4]; /* 同上 */ // char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */ //} // IplImage; //IplImage结构来自于 Intel Image Processing Library(是其本身所具有的)。OpenCV 只支持其中的一个子集: //alphaChannel 在OpenCV中被忽略。 //colorModel 和channelSeq 被OpenCV忽略。OpenCV颜色转换的唯一函数 cvCvtColor把原图像的颜色空间的目标图像的颜色空间作为一个参数。 //dataOrder 必须是IPL_DATA_ORDER_PIXEL (颜色通道是交叉存取),然而平面图像的被选择通道可以被处理,就像COI(感兴趣的通道)被设置过一样。 //align 是被OpenCV忽略的,而用 widthStep 去访问后继的图像行。 //不支持maskROI 。处理MASK的函数把他当作一个分离的参数。MASK在 OpenCV 里是 8-bit,然而在 IPL他是 1-bit。 //tileInfo 不支持。 //BorderMode和BorderConst是不支持的。每个 OpenCV 函数处理像素的邻近的像素,通常使用单一的固定代码边际模式。 //除了上述限制,OpenCV处理ROI有不同的要求。要求原图像和目标图像的尺寸或 ROI的尺寸必须(根据不同的操作, //例如cvPyrDown 目标图像的宽(高)必须等于原图像的宽(高)除以2 ±1)精确匹配,而IPL处理交叉区域,如图像的大小或ROI大小可能是完全独立的。 colorlaplace->origin = frame->origin; //让他们结构一致 cvShowImage("Laplacian", colorlaplace); if (cvWaitKey(10) >= 0) break; } cvReleaseCapture(&capture);//释放视频 cvDestroyWindow("Laplacian");//关掉视频播放窗口 return 0; }
四、参考资料
- https://blog.csdn.net/lzheng012019/article/details/121531472
- https://blog.csdn.net/jishijian7408/article/details/100690253?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163806819216780271992167%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163806819216780271992167&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-4-100690253.first_rank_v2_pc_rank_v29&utm_term=vs2010%E9%85%8D%E7%BD%AEopencv2.4&spm=1018.2226.3001.4449
- https://blog.csdn.net/xinjiang666/article/details/80785210?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_utm_term~default-0.no_search_link&spm=1001.2101.3001.4242.1
- https://www.cnblogs.com/gao-hongxiang/p/12342419.html
- https://blog.csdn.net/dongbao520/article/details/117289543
最后
以上就是鳗鱼凉面最近收集整理的关于OpenCV+visual studio 2019 实现对avi视频或摄像头 laplace边缘检测。从AVI文件( bsd.avi)中得到视频流,对视频流进行Laplace边缘检测,并输出结果。的全部内容,更多相关OpenCV+visual内容请搜索靠谱客的其他文章。
发表评论 取消回复