【C++ & Opencv】【第七天】读网上的一条程序(给滤波器加一个可调的刻度条(轨迹条))
此程序和95%的注释出自浅墨大神https://blog.csdn.net/poem_qianmo/article/details/22745559
我对代码中的一点点小错误进行了修改,另外在第一个creatTrackbar函数处加了一点点注释。
程序作用是对一幅图分别进行了方框滤波、均值滤波、高斯滤波,特别的是在每一次滤波结果图中都添加了一个轨迹条(或者说可读条),使得滤波器“核”的大小可以任意调节。
先给出轨迹条函数的声明如下:
(上面的图片出自蒋酱酱大神https://www.cnblogs.com/Nelsoner/p/6718842.html)
[code]//-----------------------------------【程序说明】----------------------------------------- // 程序名称::【OpenCV入门教程之八】线性滤波专场:方框滤波、均值滤波与高斯滤波 配套源码 // 开发所用OpenCV版本:2.4.8 // 2014年3月31 日 Create by 浅墨//------------------------------------------------------------------------------------------------//-----------------------------------【头文件包含部分】----------------------------------- // 描述:包含程序所依赖的头文件 //--------------------------------------------------------------------------------------- #include <opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> //-----------------------------------【命名空间声明部分】----------------------------------// 描述:包含程序所使用的命名空间 //--------------------------------------------------------------------------------------- using namespace std;using namespace cv; //-----------------------------------【全局变量声明部分】----------------------------------// 描述:全局变量声明 //--------------------------------------------------------------------------------------- Mat g_srcImage,g_dstImage1,g_dstImage2,g_dstImage3;//存储图片的Mat类型 int g_nBoxFilterValue=3; //方框滤波参数值 int g_nMeanBlurValue=3; //均值滤波参数值 int g_nGaussianBlurValue=3; //高斯滤波参数值 //-----------------------------------【全局函数声明部分】----------------------------------// 描述:全局函数声明 //--------------------------------------------------------------------------------------- //轨迹条的回调函数声明 static void on_BoxFilter(int, void *) //方框滤波 static void on_MeanBlur(int, void *); //均值滤波 static void on_GaussianBlur(int, void *);//高斯滤波 //-----------------------------------【main( )函数】-------------------------------------- // 描述:控制台应用程序的入口函数,我们的程序从这里开始 //--------------------------------------------------------------------------------------- int main( ){ //改变console(控制台???)字体颜色 system("color5E"); //载入原图 g_srcImage= imread( "1.jpg", 1 ); if(!g_srcImage.data ) { printf("Oh,no,读取srcImage错误~!\n"); return false; } //克隆原图到三个Mat类型中 g_dstImage1= g_srcImage.clone( ); g_dstImage2= g_srcImage.clone( ); g_dstImage3= g_srcImage.clone( ); //显示原图 namedWindow("【<0>原图窗口】", 1); imshow("【<0>原图窗口】",g_srcImage); //=================【<1>方框滤波】================== //创建窗口 namedWindow("【<1>方框滤波】", 1); //创建轨迹条 createTrackbar("内核值:", "【<1>方框滤波】",&g_nBoxFilterValue, 40,on_BoxFilter ); //解释一下creteTrackbar函数的参数: //"内核值"是轨迹条上可变参数的名字 //"【<1>方框滤波】"是轨迹条依附的窗口名,它必须与前面nameWindow声明的完全一致 //g_nBoxFilterValue是轨迹条上可变参数的初始值(至于为啥要用&取地址的形式,我也不知道) //40是轨迹条的最大值 //on_BoxFilter是回调函数,我会在下面解释 on_BoxFilter(g_nBoxFilterValue,0);/*这一句只是为了让图片在一开始有一个显示,不至于空白(可自行删去这一句,看看效果就明白了)*/ //================================================ //=================【<2>均值滤波】================== //创建窗口 namedWindow("【<2>均值滤波】", 1); //创建轨迹条 createTrackbar("内核值:", "【<2>均值滤波】",&g_nMeanBlurValue, 40,on_MeanBlur ); on_MeanBlur(g_nMeanBlurValue,0);/*同上,这一句只是为了让图片在一开始有一个显示,不至于空白(可自行删去这一句,看看效果就明白了)*/ //================================================ //=================【<3>高斯滤波】===================== //创建窗口 namedWindow("【<3>高斯滤波】", 1); //创建轨迹条 createTrackbar("内核值:", "【<3>高斯滤波】",&g_nGaussianBlurValue, 40,on_GaussianBlur ); on_GaussianBlur(g_nGaussianBlurValue,0);/*同上,这一句只是为了让图片在一开始有一个显示,不至于空白(可自行删去这一句,看看效果就明白了)*/ //================================================ //输出一些帮助信息 cout<<"\t嗯。好了,请调整滚动条观察图像效果~\n\n"<<"\t按下“q”键时,程序退出~!\n"<<"\n\n\t\t\t\tby浅墨"<<endl; //按下“q”键时,程序退出 while(char(waitKey(1))!= 'q') {} return 0; } //-----------------------------【on_BoxFilter( )函数】------------------------------------// 描述:方框滤波操作的回调函数 //--------------------------------------------------------------------------------------- static void on_BoxFilter(int, void *){ //方框滤波操作 boxFilter(g_srcImage, g_dstImage1, -1,Size( g_nBoxFilterValue+1, g_nBoxFilterValue+1)); //显示窗口 imshow("【<1>方框滤波】", g_dstImage1);} //-----------------------------【on_MeanBlur( )函数】------------------------------------// 描述:均值滤波操作的回调函数 //--------------------------------------------------------------------------------------- static void on_MeanBlur(int, void *){ //均值滤波操作 blur(g_srcImage, g_dstImage2, Size( g_nMeanBlurValue+1, g_nMeanBlurValue+1),Point(-1,-1)); //显示窗口 imshow("【<2>均值滤波】", g_dstImage2); } //-----------------------------【on_GaussianBlur( )函数】---------------------------------// 描述:高斯滤波操作的回调函数 //--------------------------------------------------------------------------------------- static void on_GaussianBlur(int, void *){ //高斯滤波操作 GaussianBlur(g_srcImage, g_dstImage3, Size( g_nGaussianBlurValue*2+1,g_nGaussianBlurValue*2+1 ), 0, 0); //显示窗口 imshow("【<3>高斯滤波】", g_dstImage3); } --------------------- 作者:浅墨_毛星云 来源:CSDN 原文:https://blog.csdn.net/poem_qianmo/article/details/22745559 版权声明:本文为博主原创文章,转载请附上博文链接!
①读此程序的第一个小启发是关于全局变量的声明,原来只要在所有函数外声明的变量就是全局变量。
②另一个不太懂的地方程序最后定义的三个回调函数,为什么在形参处都只写了形参的类型,而没写形参变量名?网上说,只要这个形参在函数中没用到,就可以只声明类型,而不声明名字。
没用到为啥还要声明它呢?浪费内存吗?不是的。
从网上查到,回调函数位置处可以不写,因为已经声明了一个οnchange=0;但是如果要写,由于TrackbarCallback已经规定了由它声明的函数(如TrackbarCallback T,那么,其中,T是一个由TrackbarCallback类型声明的函数)的格式(返回类型,形参类型等),因此这个onchange的参数就一定要按照
(int a,void* b)的形式写,其中int类型的形参表示轨迹条的位置,void*类型的形参用来输入creatTrackbar()函数的最后一个参数userdata。(开头也说了,如果第三个参数value是一个全局变量的话,就不用管userdata。)
③最难懂的是creatTrackbar中的回调函数on_BoxFilter,从网上学习了一下,不晓得对不对:
此回调函数on_BoxFilter是在轨迹条位置改变时才被调用的,用来显示新获取的图像。上面第②条中讲到了,由于TrackbarCallback的存在,它的回调函数的形参一定得是(int,void*)样式,至于需不需要写形参的变量名,则看需要而定。
而为了满足“此回调函数是用来显示新获取的图像”这个需要,其内容就必须要处理并显示图片,也就是上面程序中所写的那样。
再有疑问就需要去看源代码了,太麻烦,暂时不看。
另外有个东西 https://www.cnblogs.com/drunknbeard/p/9414467.html 看不懂,先存着吧
- opencv在C++窗体程序中 导包出错
- 用c++和opencv写的电脑版flappy bird过关程序
- 基于OpenCV的RGB和HSV色彩空间相互转换C++程序
- Qt Creator 开发opencv 纯 C++程序
- C++ Opencv人脸检测+分类器训练+识别 程序制作
- 基于OpenCV的RGB和HSV色彩空间相互转换C++程序
- 利用OpenCV和C++实现由RGB图像转化为灰度图,再将灰度图转化为二值图的程序
- 基于c++opencv的导向滤波器
- c#调用c++程序(DLL方法,以及opencv,运行开源的人脸识别seetaface)
- Linux学习笔记(十二) -- 第一个基于Opencv的C++程序
- OpenCV26(c++风格的标定程序)
- 图片模糊度判断程序(C++、opencv)
- c++、opencv、python中计算程序运行时间
- 基于opencv的Gabor滤波器设计(C++)版
- 在mfc c++ 以及opencv 编写程序当中,很多常用的类型转换
- 初学OpenCV3,运行编程入门上读取并播放视频的原版程序,编译通过但是没有任何输出,已按网上博主各种方法试,还是没有结果,大家看怎么解决?
- Matlab调用OpenCV(C++)程序
- opencv+opencl c++程序移植心酸路
- OpenCV程序加速及C++中一些编程语法速度比较
- Android调用C++OpenCV程序的方法(NDK+JNI)