基础入门
图像滤波是数字图像处理中一种非常重要的技术,主要用于图像噪声去除、图像平滑、突出图像特征,或者进行图像风格的转换。它通过数学运算对图像中的像素值进行修改,以达到特定的处理目的。图像滤波可以分为两大类,分别为:线性滤波、非线性滤波。
线性滤波器通过一个固定的权重矩阵(即:滤波核或卷积核)与图像的每个像素及其周围像素进行卷积操作,从而实现对图像的平滑或锐化。这个权重矩阵决定了滤波的效果,常见的线性滤波器有:高斯滤波、均值滤波等。
非线性滤波不遵循线性叠加原则,常见的有中值滤波等。非线性滤波对于消除椒盐噪声尤为有效,因为它能保留边缘细节。
均值滤波
均值滤波是最基础的线性滤波方法,它将每个像素点替换为其邻域像素值的平均值,这有助于消除图像中的随机噪声。在OpenCV中,均值滤波使用cv::blur函数,其函数原型如下。
void cv::blur(InputArray src, OutputArray dst, Size ksize,
Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT);
各个参数的含义如下。
src:需要进行均值模糊处理的图像,类型为cv::Mat。
dst:用于存放处理后的模糊图像,类型为cv::Mat。
ksize:模糊内核的大小,类型为cv::Size,指定在水平和垂直方向上的像素数目。通常使用奇数大小的核,以确保有中心点。
anchor:锚点位置,类型为cv::Point,默认值为Point(-1,-1),表示锚点位于核的中心。锚点是核中的一个点,用于对应输入图像中的像素位置。如果锚点位于核的边界之外,则其实际位置会根据边界规则调整到核的边界上。
borderType:边界填充类型,决定了图像边界的处理方式。默认值为BORDER_DEFAULT。
在下面的实战代码中,我们首先尝试读取图像文件。读取成功后,利用cv::blur函数应用一个5x5大小的核进行均值滤波,以减少图像中的噪声。最后,我们通过cv::imshow分别显示原始图像和经过滤波处理后的图像。
#include <opencv2/opencv.hpp>
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
Mat srcImage = imread("Snowman.jpg");
if(srcImage.empty())
{
cout << "Can not open or find the image" << endl;
return -1;
}
Mat destImage;
// 使用均值滤波,核大小为5 x 5
blur(srcImage, destImage, Size(5, 5));
imshow("Original Image", srcImage);
imshow("Blurred Image", destImage);
waitKey(0);
destroyAllWindows();
return 0;
}
执行上面的代码,运行效果可参考下图。可以看到,通过均值滤波后,图像变得模糊了。
高斯滤波
高斯滤波同样采用卷积的方式,但它使用了加权平均,其中权重是由二维高斯函数确定的。高斯函数确保了中心像素附近的像素权重较大,远离中心的像素权重逐渐减小。这意味着,更靠近中心的像素对结果的影响更大。均值滤波适合对处理速度要求较高且对图像质量损失不敏感的应用,比如:初步的图像预处理。而高斯滤波更适合于需要高质量平滑效果,同时希望尽可能保留图像细节的场合,比如:医学图像处理、图像增强前的预处理等。
在OpenCV中,高斯滤波使用cv::GaussianBlur函数,其函数原型如下。
void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX,
double sigmaY=0, int borderType=BORDER_DEFAULT);
各个参数的含义如下。
src:需要进行高斯模糊处理的图像,类型为cv::Mat。
dst:经过高斯模糊处理后的图像,类型为cv::Mat,此参数用于存放处理后的结果。
ksize:高斯核的大小,类型为cv::Size。它定义了在水平和垂直方向上的核大小,通常是一个奇数,以确保有中心点。如果传递一个单个数值,OpenCV会将其视为在两个方向上的相同大小。
sigmaX:水平方向上的高斯核标准差。如果设为0(默认值),函数会自动从ksize.width计算得到。
sigmaY:垂直方向上的高斯核标准差。如果设为0(默认值),函数会将其设为simgaX的值,从而创建一个在两个方向上大小相同的核。
borderType:边界填充类型,用于外部像素的延伸处理。默认值BORDER_DEFAULT通常足够使用,但也可以根据需要选择其他类型,比如:BORDER_CONSTANT、BORDER_REPLICATE等。
同样的一幅图像,经过高斯滤波后,效果可参考下图。
中值滤波
中值滤波主要用于去除图像中的椒盐噪声,同时能很好地保护边缘信息,不会造成模糊效应。在OpenCV中,中值滤波使用cv::medianBlur函数,其函数原型如下。
void cv::medianBlur(InputArray src, OutputArray dst, int ksize);
各个参数的含义如下。
src:单通道或多通道图像,类型为cv::Mat。
dst:输出图像,与输入图像具有相同的大小和类型。
ksize:中值滤波器的核大小(宽度和高度必须是奇数且相等),决定了考虑邻域的大小。较大的核尺寸能够过滤掉较大的噪声,但也可能模糊图像中的细节。
同样的一幅图像,经过中值滤波后,效果可参考下图。
总结
图像滤波不仅仅是简单地去噪或平滑图像,它至少在以下四个领域都有着非常广泛的应用。
1、预处理。在进行边缘检测、特征提取等操作之前,常使用高斯滤波去除噪声,减少误检。
2、特征增强。通过特定的滤波器(比如:锐化滤波等),可以增强图像中的边缘和细节,便于后续的特征提取。
3、图像复原。在图像去模糊、去噪等复原任务中,滤波器的选择和设计显得至关重要。
4、艺术效果。通过一些非传统的滤波器(比如:双边滤波等),可以在保留边缘的同时进行平滑,常用于图像风格转换。