4、对图像进行滤波操作
前面所描述的各种方法都只针对单像素强度进行处理,因此也称为“点处理”方法。而更多时候,查看像素的邻域关系比只处理单像素强度有更大的用途,我们称之为“邻域处理”技术。邻域可以是3×3,5×5,7×7等以特定像素为中心的矩阵。图像滤波是一种重要的邻域处理技术。
滤波是信号处理中的一个重要概念:拒绝或允许某特定频段通过。如何在图像中测量频率?如果某区域内的灰度级变化缓慢,那么就是低频区域;如果灰度级变化剧烈,这就是高频区域。通常,图像的背景被视为是低频区域,边缘是高频区域。
4.1、均值滤波
平均滤波器对邻域像素执行平均操作。如果图像中存在高斯噪声,则可以使用这种低通平均滤波器来消除噪声,但平均操作会使图像边缘变得模糊。邻域可以是3×3,5×5,7×7,依此类推。滤波器窗口的尺寸越大,图像的模糊程度就越大。
cv::Ptr是智能指针的模板类,用于存储cv::cuda::Filter类型的滤波器。接着用create-BoxFilter函数来创建不同窗口大小的平均滤波器,这个函数需要三个强制参数和三个可选参数:第一个和第二个参数是源图像和目标图像的数据类型,这里设定为8位无符号灰度的CV_8UC1图像;第三个参数定义滤波器窗口的大小,可以是3×3、5×5、7×7等;第四个参数是表示位于内核中心点的锚点,默认值为(-1,-1)。最后还有两个关于像素插值方法和边界值的可选参数,这里省略。
创建出来的滤波器指针有一个apply方法,能将创建的滤波器用在所有图像上,它需要三个参数:第一个参数是源图像,第二个参数是目标图像,第三个可选参数是CUDA流,用于本书前面所述的多任务处理。代码中,在图像上应用了三个不同大小的平均滤波器,执行结果如图6-8所示。往下一次kernel增大:
从输出的结果可以看出,虽然大型滤波器可以消除更多噪声,但是随着滤波器尺寸的增加,更多的像素被平均处理,导致图像变得更加模糊。
4.2、高斯滤波
高斯滤波器使用具有高斯分布的掩码来过滤图像,而不是简单的平均掩码。这个滤波器还在图像上引入平滑模糊,这个方法已经被广泛用于消除图像中的噪声。
createGaussianFilter函数用于为高斯滤波器创建掩码,需要提供源图像/目标图像的数据类型、滤波器的大小以及水平方向标准差作为这个函数的参数。我们还可以提供竖直方向标准差作为参数,如果不提供的话,会用水平方向标准差作为其默认值,然后用apply方法创建出不同大小的高斯掩码应用于图像处理。本段代码的输出如图:
同样地,随着高斯滤波器尺寸的增加,图像变得更加模糊。高斯滤波器用于消除噪声并在图像上引入平滑模糊。
4.3、中值滤波
当图像受到椒盐噪声的影响,那么平均滤波器或高斯滤波器是消除不了的,这时候需要一个非线性的滤波器。用邻域的中值运算去替代平均值的方式可以帮助消除椒盐噪声。在这个滤波器中,邻域中的9像素值的中值放置于中心像素处,这将能消除椒盐噪音所产生的过高或过低的极端值。虽然OpenCV和CUDA提供了中值滤波功能,但它比OpenCV的常规函数慢。
OpenCV中的medianBlur函数用于实现中值滤波器,它需要三个参数:第一个参数是源图像,第二个参数是目标图像,第三个参数是中值运算的窗口大小。中值滤波的输出如图:
如图所示,源图像受椒盐噪声的影响。通过3×3尺寸的中值滤波器完全消除了这种噪声,而且没有产生极端模糊。因此,当图像应用受椒盐噪声影响时,中值滤波是一个非常重要的预处理步骤。