5.14. 高斯平滑与边缘

在经典机器视觉中,邻域窗口主要用于两类工作:干净地平滑像素与像素之间的变化,以及找出图像发生急剧变化处的边缘。高斯滤波器是前者的标准工具,基于拉普拉斯的检测器是后者的标准工具——而且二者可以组合使用,因为每种边缘检测器在经过轻度平滑的输入上都能更好地工作。

5.14.1. 高斯滤波器

gaussian()mean() 的中心加权表亲。二者都对每个像素的邻域计算平均值,但高斯滤波器的权重并不均匀:靠近邻域中心的像素权重更大,邻域边缘的像素权重更小,权重遵循那条赋予该滤波器名字的著名钟形曲线。

正是这种钟形加权使高斯滤波器比方框平均更平滑。均值滤波可能在物体边缘产生可见的伪影——权重中的硬性截断会在急剧过渡处引入微小的振铃图案。高斯滤波器平滑下降的权重避免了这种振铃,并产生看起来更接近“模糊”应有效果的结果。代价是每像素的计算量比均值滤波器更多,但差距并不大——其每像素成本仍远低于双边滤波器。

img.gaussian(1)    # 3x3 Gaussian -- a clean light blur
img.gaussian(2)    # 5x5 Gaussian -- stronger smoothing

高斯平滑几乎是每条边缘检测管线的标准第一阶段。下面的边缘检测器都会放大高频内容,包括算法实际上并不想检测的传感器噪声。先运行一次轻度高斯滤波,可以在不太软化真实边缘的情况下抑制这些噪声,让边缘检测器去找真实边缘而非斑点噪声。

5.14.2. 非锐化掩蔽

图像的高斯模糊副本是非锐化掩蔽技术用于经典锐化的原材料。在滤波器上设置 unsharp=True,会将其从“产生模糊图像”切换为“从原图中减去模糊图像,再将差值加回到原图”——其效果是高频边缘相对于平滑的内部区域得到放大。

img.gaussian(1, unsharp=True)

可选的 muladd 参数用于缩放非锐化结果的强度;其默认值(mul=1.0add=0.0)提供的是不会夸大传感器噪声的适度锐化。

5.14.3. 拉普拉斯滤波器

laplacian() 运行图像二阶空间导数的离散近似。在像素值快速变化处,输出较大;在数值恒定或线性变化处,输出接近零。对该结果的自然解读是一种边缘响应:图像快速变化处的像素会变亮,平滑内部区域的像素则保持暗淡。

img.laplacian(1)   # 3x3 Laplacian -- edge response

可用的参数与 gaussian 相同。sharpen=True 会产生一幅锐化图像(即将拉普拉斯结果加回原图,而非单独返回)。muladd 用于缩放响应。

除边缘检测之外的一个实用用途是对焦测量。在某个区域内对拉普拉斯响应求平均,可粗略衡量该区域携带了多少高频内容;对于对焦良好的帧,该平均值较高,对于模糊的帧则会下降。比较不同帧之间的拉普拉斯响应,是无需更昂贵的对比度度量即可询问“镜头是否对焦?”的廉价方法。

5.14.4. find_edges 方法

find_edges() 运行的是一条完整的边缘检测管线,而不仅仅是一个边缘响应滤波器。它作用于灰度图像,结果是一幅二值图像,其非零像素标记出输入中具有应当算作边缘的那种亮度变化的位置。

该方法接受一个 edge_type 参数,用于在两种算法之间选择:

EDGE_SIMPLE 运行一个高通滤波器,应用阈值,然后返回结果。速度快,但输出包含所有高于阈值的亮度变化,包括应用程序可能并不关心的噪声和纹理。它适用于干净的图像,以及噪声将由后续形态学处理清除的情况。

EDGE_CANNY 运行 Canny 边缘检测器——经典的多阶段算法。它计算亮度梯度,沿梯度方向抑制所有非极大响应(使每条边缘宽一个像素),并应用滞后阈值(使某处较强的边缘即使在中间淡化处也能被追踪到)。其结果是一组干净、纤细、相互连通的边缘像素,正是每个经典的基于边缘的算法所需要的。

threshold 参数是一个两元素元组 (low, high)。对于 EDGE_CANNYhigh 值是高于此值像素就肯定是边缘的截止值,low 值是高于此值像素仅在与某个确定边缘相连时才算边缘的截止值。对于 EDGE_SIMPLE,只有 high 值起作用;它是高于此值像素就算作边缘的单一截止值。默认值 (100, 200) 是一个起点,值得针对具体场景进行调校。

img.gaussian(1)                                   # pre-smooth
img.find_edges(image.EDGE_CANNY, threshold=(50, 100))

对于几乎所有边缘很重要的应用程序,Canny 检测器都是更好的选择。在 Canny 的成本成为问题、而其滞后处理的抗噪能力实际上又用不上的情况下,更快的 EDGE_SIMPLE 值得记住。

5.14.5. 在高斯滤波上进行自适应阈值处理

统计滤波器 一样,gaussian() 接受用于自适应阈值处理的 threshold=True / offset=N 关键字参数对。其行为与 mean() 相同:每个位置的高斯统计量成为局部截止值,源像素与该统计量加上偏移量进行比较,从而产生二值结果。

当输入相当无噪声时,高斯变体通常是自适应阈值处理最干净的选择。加权平均比均值滤波器产生的截止值更平滑,在急剧的光照过渡处伪影更少。