图像滤波通过改变图像中像素点的值来实现去噪、平滑、锐化和边缘检测等目的,根据空间滤波的特性分为:线性滤波和非线性滤波
简单来说,图像滤波就是将一个窗口(也称为卷积核)在图像上滑动,对每个窗口内的像素进行计算,并取得计算结果替代原像素值,从而改变图像的特征。
要求:图像视觉效果应当更好,不能损坏图像轮廓及边缘
常见的图像滤波方法包括:
- 均值滤波(Mean Filter):使用 cv2.blur() 函数或 cv2.boxFilter() 函数进行均值滤波,可以通过指定卷积核的大小来实现不同程度的平滑效果。
- 高斯滤波(Gaussian Filter):使用 cv2.GaussianBlur() 函数进行高斯滤波,通过指定卷积核的大小和标准差来控制平滑效果,高斯滤波能够有效地去除高斯噪声。
- 中值滤波(Median Filter):使用 cv2.medianBlur() 函数进行中值滤波,该方法能够有效地去除椒盐噪声和斑点噪声,对于保留图像细节很有帮助。
- 双边滤波(Bilateral Filter):使用 cv2.bilateralFilter() 函数进行双边滤波,该方法能够在平滑图像的同时保留边缘信息,对于图像降噪和保留细节非常有效。
- 拉普拉斯滤波(Laplacian Filter):使用 cv2.Laplacian() 函数进行拉普拉斯滤波,该方法可以增强图像的边缘和细节,常用于图像锐化。
- 方框滤波(boxFilter): 对图像进行简单的线性滤波,常用于图像的平滑处理。
线性滤波 :方框滤波、高斯滤波、均值滤波
非线性滤波:双边滤波、中值滤波
五种滤波器函数功能解析:
方框滤波
方框滤波是一种简单的线性滤波方法,用于图像平滑处理。
c
void cv::boxFilter(
InputArray src, // 输入图像
OutputArray dst, // 输出图像
int ddepth, // 输出图像的深度,-1 表示与输入图像相同
Size ksize, // 滤波内核的大小
Point anchor = Point(-1,-1), // 锚点,默认为核的中心
bool normalize = true, // 是否进行归一化,默认为true
int borderType = BORDER_DEFAULT // 边界扩展类型,用于推断图像外部像素的某种边界模式
);
高斯滤波
高斯滤波通常用于去除图像中的高斯噪声,并且能够更好地保留图像的边缘信息。
c
void cv::GaussianBlur(
InputArray src, // 输入图像
OutputArray dst, // 输出图像
Size ksize, // 滤波内核的大小
double sigmaX, // X 方向上的标准差
double sigmaY = 0, // Y 方向上的标准差,默认为 0
int borderType = BORDER_DEFAULT // 边界扩展类型
);
均值滤波
均值滤波将每个像素的值替换为其邻域内像素值的平均值,用于平滑图像并减少噪声。
均值滤波是一种简单的线性滤波方法,可能会导致图像细节的丢失。
c
void cv::blur(
InputArray src, // 输入图像
OutputArray dst, // 输出图像
Size ksize, // 滤波内核的大小
Point anchor = Point(-1,-1), // 锚点,默认为核的中心
int borderType = BORDER_DEFAULT // 边界扩展类型
);
双边滤波
双边滤波能够在平滑图像的同时保留边缘信息,并且对于去除噪声效果也较好。它使用两个不同的标准差来考虑像素值的相似性和空间距离的相似性,从而在滤波过程中保持图像细节。
c
void cv::bilateralFilter(
InputArray src, // 输入图像
OutputArray dst, // 输出图像
int d, // 邻域直径,表示双边滤波核的大小
double sigmaColor, // 色彩空间中的标准差
double sigmaSpace, // 坐标空间中的标准差
int borderType = BORDER_DEFAULT // 边界扩展类型
);
中值滤波
中值滤波将每个像素的值替换为其邻域内像素值的中值,用于去除椒盐噪声等类型的噪声。
中值滤波能够有效地保留图像的边缘信息,并且在去除噪声的同时不会引入过多的模糊。
请注意,滤波核的大小必须是奇数,例如 3、5、7 等。
c
void cv::medianBlur(
InputArray src, // 输入图像
OutputArray dst, // 输出图像
int ksize // 滤波核的大小,必须是奇数
);
代码演示:
c
int main(int argc,char* argv)
{
Mat target1,target2,target3,target4,target5;
Mat MatSource = imread("fish.jpg");
imshow("原图像:",MatSource);
//方框滤波
boxFilter(MatSource,target1,MatSource.depth(),Size(2,2),Point(-1,-1),false);
imshow("测试1:方框滤波图像",target1);
//高斯滤波
GaussianBlur(MatSource,target2,Size(3,3),0,0);
imshow("测试2:高斯滤波图像",target2);
//均值滤波
blur(MatSource,target3,Size(6,6));
imshow("测试3:均值滤波图像",target3);
//双边滤波
bilateralFiltre(MatSource,target4,10,10,10);
imshow("测试4:双边滤波图像",target4);
//中值滤波
medianBlur(matSource,target5,9);
imshow("测试5:中值滤波图像",target5);
}