1.1图像滤波理论html
图像滤波即在尽可能保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺乏的操做。消除图像中的噪声又叫作图像滤波或平滑,滤波的目的有两个,一是突出特征以方便处理,二是抑制噪声。编程
空间域滤波就是在图像平面上对像素进行操做。空间域滤波大致分为两类:平滑、锐化。函数
平滑滤波:模糊处理,用于减少噪声,其实是低通滤波,典型的滤波器是高斯滤波。学习
锐化滤波:提取边缘突出边缘及细节、弥补平滑滤波形成的边缘模糊。其实是高通滤波。测试
空间域处理可由下式表示:优化
g(x,y)=T[f(x,y)]spa
式中,f(x,y)是输入图像,g(x,y)是处理后的图像,T是在点(x,y)的邻域上定义的关于f的一种算子,算子可应用于单幅图像或图像集合。.net
1.2邻域滤波算子3d
1)空间滤波器由一个邻域(一般是一个较小的矩形)和对该邻域所包围图像像素执行的预约义操做组成。对预约义的点(x,y)为中心的领域内的像素进行计算。code
2)滤波产生一个新像素,用计算后的新像素值代替点(x,y)的值。
3)循环步骤1和2,滤波器的中心遍历图像中的每一个像素后,就生成了滤波后的图像。
4)若是在图像像素上执行的是线性操做,则该滤波器称为线性空间滤波器,不然,称为非线性空间滤波器。
通常来讲,使用大小为 m×n的滤波器对大小为 M×N的图像进行线性空间滤波,可由下式表示:
滤波处理分为两大类:线性滤波和非线性滤波。OpenCV里有这些滤波的函数,使用起来很是方便。
线性滤波:
1.方框滤波BoxBlur:模糊图像
2.均值滤波Blur:模糊图像
3.高斯滤波GaussianBlur:信号的平滑处理,去除符合正太分布的噪声
非线性滤波:
1.中值滤波mediaBlur:去除椒盐噪声
2.双边滤波BilateralFilter:保边去噪
3.1平滑滤波
通常来讲,图像具备局部连续的性质,即相邻的像素的值相近,而噪声使得噪点处产生像素跳跃,因此经过平滑噪点能够减小噪声,去除图像中的不相关细节。
方框滤波BoxBlur和均值滤波Blur都是对邻域内作平均值来滤波,属于平滑滤波。滤波的输出是包含在滤波器模板邻域内的像素的平均值,方框滤波作归一化以后就变为均值滤波,这两个滤波器都是低通滤波器。
函数原型以下:
CV_EXPORTS_W void boxFilter( InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), bool normalize=true, int borderType=BORDER_DEFAULT ); CV_EXPORTS_W void blur( InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT );
3.2高斯滤波
高斯滤波对于图像来讲就是一个低通滤波,普遍用于消除高斯噪声,高速滤波就是一种加权滤波,只不过模板中的系数由高斯分布来肯定的,高斯滤波器根据高斯函数的形状来选择滤波模板权值的线性平滑滤波器。高斯平滑滤波器对于抑制服从正态分布的噪声很是有效。
CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT );
3.3测试实验
Mat img; Mat img1, img2, img3; int gBoxFilterValue = 3; int gMeanBlurValue = 3; int gGaussianBlurValue = 3; static void OnBoxFilter(int filterSz, void *) { boxFilter(img, img1, -1, Size(filterSz +1, filterSz +1)); imshow("方框滤波", img1); } static void OnMeaanBlur(int filterSz, void *) { blur(img, img2, Size(filterSz + 1, filterSz + 1)); imshow("均值滤波", img2); } static void OnGaussinanBlur(int filterSz, void *) { GaussianBlur(img, img3, Size(filterSz*2 + 1, filterSz*2 + 1), 0, 0); imshow("高斯滤波", img3); } int main() { img = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic2.bmp"); img1 = img.clone(); img2 = img.clone(); img3 = img.clone(); imshow("原图", img); namedWindow("方框滤波", 1); createTrackbar("内核值", "方框滤波", &gBoxFilterValue, 40, OnBoxFilter); OnBoxFilter(gBoxFilterValue, 0); namedWindow("均值滤波", 1); createTrackbar("内核值", "均值滤波", &gMeanBlurValue, 40, OnMeaanBlur); OnMeaanBlur(gMeanBlurValue, 0); namedWindow("高斯滤波", 1); createTrackbar("内核值", "高斯滤波", &gGaussianBlurValue, 40, OnGaussinanBlur); OnGaussinanBlur(gGaussianBlurValue, 0); waitKey(0); }
输出结果以下图。
4.1中值滤波
中值滤波属于非线性滤波,其思想用滤波模板邻域内的像素的平均值来代替像素点的灰度值。中值滤波器是一种统计排序滤波器,图像上点(x,y),中值滤波以该点为中心,领域内全部像素的统计排序中值做为此点的响应,中值滤波是非线性滤波。相比与均值滤波和高斯滤波,中值滤波能够有效的下降随机噪声,直接忽略掉噪声点,把噪声引发的模糊降到最低。线性滤波器在滤波的同时会形成图像细节模糊,中值滤波能够避免这个问题,其典型的应用就是中值滤波消除斑点噪声、椒盐噪声。
CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );
使用中值滤波,滤除椒盐噪声例子以下。
img = imread("D:/WORK/5.OpenCV/LeanOpenCV/pic_src/pic2.bmp"); salt(img, 1000); img1 = img.clone(); img2 = img.clone(); img3 = img.clone(); imshow("原图", img); namedWindow("高斯滤波", 1); createTrackbar("内核值", "高斯滤波", &gGaussianBlurValue, 40, OnGaussinanBlur); OnGaussinanBlur(gGaussianBlurValue, 0); namedWindow("中值滤波", 1); createTrackbar("内核值", "中值滤波", &gMedianBlurValue, 40, OnMedianBlur); OnMedianBlur(gMedianBlurValue, 0); waitKey(0); }
输出结果以下图。高斯滤波在滤除噪点的同时也形成了图像模糊,若是增大内核则会形成严重模糊失真,而中值滤波对椒盐噪声有很好的抑制做用。
4.2双边滤波
高斯滤波属于加权平均滤波,距离中心点越近的点越有较大权重,这种方法符合图像的平滑变化的特征,可是在边缘区域,像素值出现突变,这种方法反而会滤掉边缘轮廓,损失掉有用的边缘信息。边缘保护滤波方法,双边滤波就是最经常使用的边缘保护滤波方法,就是为了处理这种状况而发明的。
双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值类似度的一种折衷处理,同时考虑空域信息和灰度类似性,达到保边去噪的目的。双边滤波将高斯滤波中经过各个点到中心点的空间临近度计算的各个权值进行优化,将其优化为空间临近度计算的权值和像素值类似度计算的权值的乘积,优化后的权值再与图像做卷积运算,从而达到保边去噪的效果。
CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT );
InputArray src: 输入图像,能够是Mat类型,图像必须是8位或浮点型单通道、三通道的图像。
OutputArray dst: 输出图像,和原图像有相同的尺寸和类型。
int d: 表示在过滤过程当中每一个像素邻域的直径范围。若是这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。
double sigmaColor: 颜色空间过滤器的sigma值,这个参数的值越大,更大的值域空间影响结果。
double sigmaSpace: 坐标空间中滤波器的sigma值,若是该值较大,更大的定义域空间影响结果。
int borderType=BORDER_DEFAULT:边界模式,有默认值BORDER_DEFAULT.
static void OnBilateralFilter(int filterSz, void *) { bilateralFilter(img, img3, filterSz, filterSz * 2, filterSz / 2); imshow("双边滤波", img3); } namedWindow("双边滤波", 1); createTrackbar("内核值", "双边滤波", &gMedianBlurValue, 40, OnBilateralFilter); OnBilateralFilter(gMedianBlurValue, 0);
输出效果以下图。双边滤波在较大的参数范围内都保持了很好的噪声抑制特性,而且没有形成边缘模糊。
调节中值滤波的滑动条时,出现异常。
vs报错:
未经处理的异常:
0x00007FF835C09159 处(位于 Day1.exe 中)有未经处理的异常: Microsoft C++ 异常: cv::Exception,位于内存位置 0x000000F29FAFE138 处。
解决方法:
中值滤波的参数ksize须要为偶数。
@param src input 1-, 3-, or 4-channel image; when ksize is 3 or 5, the image depth should be CV_8U, CV_16U, or CV_32F, for larger aperture sizes, it can only be CV_8U. @param dst destination array of the same size and type as src. @param ksize aperture linear size; it must be odd and greater than 1, for example: 3, 5, 7 ... @sa bilateralFilter, blur, boxFilter, GaussianBlur */ CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );
使用例子:
static void OnMedianBlur(int filterSz, void *) { if (filterSz % 2 == 0) filterSz += 1; medianBlur(img, img2, filterSz); imshow("中值滤波", img2); }
测试效果图以下:
一、《OpenCV3 编程入门》,电子工业出版社,毛星雨著
二、《学习OpenCV》,清华大学出版社,Gary Bradski, Adrian kaehler著
三、OpenCV双边滤波详解及实代码实现
https://blog.csdn.net/qq_36359022/article/details/80198890
四、Bilateral Filtering for Gray and Color Images
https://users.soe.ucsc.edu/~manduchi/Papers/ICCV98.pdf
五、Smoothing Images
https://docs.opencv.org/4.1.2/dc/dd3/tutorial_gausian_median_blur_bilateral_filter.html
六、OpenCV图像处理之滤波
https://blog.csdn.net/qq_30815237/article/details/86690190
尊重原创技术文章,转载请注明。