1.图像模糊去噪原理
图像在采集、传输的过程中,因为人为或者系统的因素难免会产生噪声。这时候就需要对图像进行预处理降低噪声。图像模糊降噪的数学原理是图像的卷积操作。假设有一幅6x6的图像矩形。
在6x6的图像像素矩阵上有一个红色中心黄色边框的3x3的窗口,从上到下,从左到右移动。3x3窗口每个位置都对应一个权重,当窗口移动到某一位置时,图像像素矩阵对应像素与权重相乘并求和,将得到的值赋给中心像素。这样就完成了图像的模糊去噪。
其中3x3窗口称为卷积核,中心的红色像素称为锚点。
2.滤波算法
(1)均值滤波
在均值滤波中各个像素的权重都相同,但均值滤波会印制边缘,同时对于椒盐噪声的抑制也不理想。
OpenCV中均值滤波的函数为blur()
函数原型:
参数说明:①src-输入图像,可以是多通道图像
②dst-输出图像
③ksize-卷积核的大小,前面提到了3x3的卷积核,你还可以设置成5x5等。注意卷积核长宽要设置成奇数大小。
④anchor-锚点位置。Point(-1,-1)表示让OpenCV设置默认位置一般是中心点。
⑤borderType-边缘填充的方式,细心的同学一定注意到了上面进行图像卷积的时候,边缘的像素是无法计算的,这就需要对图像的边缘进行填充。OpenCV中填充边缘的方式有如下几种:
其中使用得比较多的是BORDER_CONSTANT、BORDER_REPLICATE和BORDER_DEFAULT。
BORDER_CONSTANT-设置像素的值,即用常像素填充
BORDER_REPLICATE-复制边缘的像素并进行延申。
BORDER_DEFAULT-使用边缘像素映射。
(2)高斯滤波
高斯函数介绍:
高斯函数服从正态分布越靠近中心,值越大。从图中可以看出 和
对图像的影响是
影响图像波峰的位置,
越大图像的峰值越低,反之图像峰值越高。上面介绍的是一维情况下的高斯函数,二维空间中的高斯函数同理:
从二维高斯函数可以看出越靠近中心值越大,对应图像处理中,即越靠近中心锚点的像素所占的权重越大。这样处理的好处是可以保留一定的细节。
OpenCV中高斯滤波的函数为:GaussianBlur()
函数原型:
参数说明:①sigmaX-二维高斯函数中的
②sigmaY-二维高斯函数中的
(3)中值滤波
中值滤波是一种非线性的滤波方式,它对卷积窗口对应的像素进行排序,然后将排序后的像素中值赋值给锚点(中心点),这种处理方式有助于抑制椒盐噪声,一般椒盐噪声都是最大或者最小的像素值。
OpenCV中的中值滤波函数为:medianBlur()
函数原型:
参数说明:ksize-窗口的长或宽,中值滤波中窗口一定是矩形,所有ksize只需要是一个int型的数据。
(4)双边滤波
前面介绍的滤波方式均值滤波、高斯滤波对服从高斯分布或者均匀分布的噪声都有着很好的滤除作用,但是这两种滤波方式也会抑制边缘。虽然高斯滤波在均值滤波的基础上有所改进,但是效果仍不理想,如是就有双边滤波的出现。双边滤波是在高斯滤波的基础上改进的,双边滤波的权重不仅考虑了像素的欧式距离(像素距离中心点的距离),还考虑了像素范围域的差异(考虑卷积核中心像素与其他像素的像素值差异)。在计算中心像素的时候同时考虑这两个权重。
其中(x,y)是卷积核中除锚点外的点,f(x,y)是(x,y)点的像素,其它同高斯滤波,通过分析可以看出某点的像素和中心点像素差值越大则其在卷积核中占的权重越小,那么非边缘像素对边缘像素的影响就会变小,这就达到保留边缘的作用。
从图中可以看出,输入的边缘得到很好的保留,同时噪声得到了很好的剔除。
OpenCV中的函数:bilateralFilter()
函数原型:
参数说明:①d-卷积核的尺寸。如果d的值为负,则从sigmaSpace计算d的值。
②sigmaColor,sigmaSpace-分别是值域和空间域的σ,对应与的
。
3 代码演示
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
using namespace cv;
using namespace std;
#define DIRECTORY "E:/PrivateRepository/ProgramFolder/image/"
/***图像模糊***/
int main()
{
//【1】加载图像
string directory = "";
directory = directory + DIRECTORY + "test.jpg";
//1.读取图像
Mat src = imread(directory);
//2.判断是否读取正确
if (src.empty())
{
printf("could not load the image");
return -1;
}
//【2】创建图像显示窗口标题
char srcTitle[] = "srcImage";
char lineBlurTitle[] = "AvBlurImage";
char gaussianBlurTitle[] = "gaussianBlurImage";
char medianBlurTitle[] = "medianBlurImage";
char bilateralBlurTitle[] = "bilateralBlurImage";
//【3】模糊图像blur
Mat lineBlurImage;
blur(src, lineBlurImage, Size(5, 5));
//【4】高斯模糊GaussianBlur
Mat gaussianBlurImage;
GaussianBlur(src, gaussianBlurImage, Size(5, 5), 5, 5);
//【5】中值模糊medianBlur
Mat medianBlurImage;
medianBlur(src, medianBlurImage, 5);
//【6】双边模糊bilateralFilter
Mat bilateralBlurImage;
bilateralFilter(src, bilateralBlurImage, 5, 100, 11);
//【7】显示图像
imshow(srcTitle, src);
imshow(lineBlurTitle, lineBlurImage);
imshow(gaussianBlurTitle, gaussianBlurImage);
imshow(medianBlurTitle, medianBlurImage);
imshow(bilateralBlurTitle, bilateralBlurImage);
waitKey(0);
destroyAllWindows();
return 0;
}
从图中可以看出中值滤波对椒盐噪声的滤除效果最好,双边滤波很好得滤除了噪声同时保留了边缘。
总结:
高斯分布或者均匀分布的噪声可以使用均值滤波、高斯滤波和双边滤波。双边滤波对边缘保留效果最好,适合边缘较多的图像,但是运行速度会比较慢。均匀和高斯滤波对边缘的保留不怎么好,但是速度快点,其中高斯滤波对边缘的保留效果较好一点。
椒盐噪声只有用中值滤波比较好。