图像滤波

图像变换

图像变换是对图像进行某种数学操作以得到新图像的过程。根据操作对象的不同,图像变换分为两大类:

滤波(Filtering)改变像素的——输出图像与输入图像具有相同的空间布局,但每个位置上的像素值被重新计算。用函数的语言来说,滤波改变的是图像函数的值域(Range):

G(x)=h{F(x)}G(\bm{x}) = h\{F(\bm{x})\}

变形(Warping)改变像素的位置——像素值本身不变,但被移动到新的坐标。变形改变的是图像函数的定义域(Domain):

G(x)=F(h{x})G(\bm{x}) = F(h\{\bm{x}\})

本章聚焦于滤波。根据计算方式的不同,滤波又可以分为点操作邻域操作

点操作

点操作(Point Processing)是最简单的图像变换:输出像素值仅取决于输入图像中同一位置的像素值,与邻域无关。常见的点操作包括亮度调整、对比度调整和反色等。

假设原始像素值为 xx(范围 0-255),以下是几种典型的点操作:

操作 公式 效果
变暗 x128x - 128 所有像素减去常数,整体变暗
变亮 x+128x + 128 所有像素加上常数,整体变亮
降低对比度 x/2x / 2 压缩值域,灰度差异减小
提升对比度 x×2x \times 2 拉伸值域,灰度差异增大
反色 255x255 - x 亮暗互换,得到「底片」效果
非线性降低对比度 (x/255)1/3×255(x/255)^{1/3} \times 255 暗部拉伸、亮部压缩
非线性提升对比度 (x/255)2×255(x/255)^{2} \times 255 暗部压缩、亮部拉伸

非线性操作使用幂函数(也称 Gamma 变换),通过指数控制变换曲线的形状:指数小于 1 时,暗部被拉伸(图像整体变亮、对比度降低);指数大于 1 时,暗部被压缩(图像整体变暗、对比度提高)。

邻域操作与滤波

点操作的局限在于它完全忽略了像素的空间上下文。正如上一章所讨论的,单个像素的亮度本身不携带明确信息——信息蕴含在亮度的局部差异中

邻域操作(Neighborhood Operation)则利用了这一点:输出像素值由输入图像中该像素及其邻域内的像素值共同决定。邻域操作就是通常所说的「滤波」——用一个滤波器(Filter)或(Kernel)来指定如何组合邻域内的像素值。

滤波的应用场景:

  • 图像增强:去噪、锐化、调整大小等
  • 信息提取:检测纹理、边缘等
  • 模式检测:模板匹配

滤波可以从三个角度来理解:

flowchart LR
    A["空间域滤波"] --> D["对局部像素块<br/>进行数学运算"]
    B["频率域滤波"] --> E["修改图像的<br/>频率成分"]
    C["模板与图像金字塔"] --> F["将模板与图像<br/>进行匹配"]

    classDef view fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
    classDef desc fill:#f8f9fa,stroke:#495057,stroke-width:2px

    class A,B,C view
    class D,E,F desc

本章主要讨论空间域滤波,频率域滤波和模板匹配将在后续章节中介绍。

图像噪声

噪声的来源

即使对完全静止的场景拍摄多张照片,得到的图像也不会完全相同——这是因为成像过程中不可避免地引入了噪声(Noise)。噪声来自传感器的热噪声、光子的统计波动、电路干扰等多种物理因素。

常见噪声类型

噪声类型 特征 视觉表现
椒盐噪声(Salt and Pepper) 随机出现的纯黑和纯白像素 图像上散布着黑白斑点
脉冲噪声(Impulse) 随机出现的纯白像素 类似椒盐噪声,但只有白点
高斯噪声(Gaussian) 像素值叠加了服从高斯分布的随机扰动 整体呈现颗粒感,噪声强度均匀

降噪的核心思路是:如果有同一场景的多张图片,可以取平均来消除随机噪声。但如果只有一张图片呢?此时需要利用图像的空间相关性——假设相邻像素应该具有相似的值(因为它们通常来自同一表面),而噪声在不同像素之间是独立的。基于这两个假设,我们可以用邻域平均来估计真实强度值。

线性滤波

滑动平均

最简单的降噪方法是滑动平均(Moving Average):将每个像素替换为其邻域内所有像素的均值。

在一维情况下,对信号 ff 中的每个位置 ii,取其前后各 kk 个邻居的均值作为输出。效果是信号变得更平滑——高频的细微波动被抑制,但整体趋势保留。

可以为邻域内的像素赋予不同的权重。均匀权重 [1,1,1,1,1]/5[1, 1, 1, 1, 1] / 5 对所有邻居一视同仁;非均匀权重 [1,4,6,4,1]/16[1, 4, 6, 4, 1] / 16 则让距中心越近的邻居贡献越大——后者的平滑效果更自然,不会产生「方块感」。

互相关

将滑动平均推广到二维并允许任意权重,就得到了互相关(Cross-Correlation)运算。

对于大小为 (2k+1)×(2k+1)(2k+1) \times (2k+1) 的邻域窗口,均匀平均可以写成:

G[i,j]=1(2k+1)2u=kkv=kkF[i+u,j+v]G[i, j] = \frac{1}{(2k+1)^2} \sum_{u=-k}^{k} \sum_{v=-k}^{k} F[i+u, j+v]

推广为非均匀权重:

G[i,j]=u=kkv=kkH[u,v]F[i+u,j+v]G[i, j] = \sum_{u=-k}^{k} \sum_{v=-k}^{k} H[u, v] \, F[i+u, j+v]

这就是互相关运算,记作 G=HFG = H \otimes F。其中 H[u,v]H[u, v] 称为滤波器的核或掩模(Mask),它规定了邻域内每个相对位置的像素应该以什么权重参与加权求和。滤波的本质就是用邻域像素的线性组合替代中心像素

均值滤波器

当核 HH 的所有元素都相等时,就得到均值滤波器(Box Filter)。例如 3×33 \times 3 的均值滤波器:

H=19[111111111]H = \frac{1}{9} \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix}

均值滤波器对图像进行均匀平滑:核越大,平滑效果越强,但同时也会让边缘变得更加模糊。

边界处理

当滤波器窗口移动到图像边缘时,部分窗口会落在图像之外。这个问题有几种常见的处理方式:

方法 策略 效果
零填充(Zero Padding) 图像外部视为 0(黑色) 边缘处出现暗边
环绕(Wrap Around) 图像看作周期性重复 适合具有周期性的图像
复制边缘(Replicate) 用最近的边缘像素填充 自然,但可能引入伪影
镜像反射(Reflect) 沿边缘对称翻转 通常效果最好

此外,输出图像的大小也有不同选择:

  • full:输出尺寸为输入与核的尺寸之和(包含所有部分重叠区域)
  • same:输出与输入尺寸相同(最常用)
  • valid:输出尺寸为输入与核的尺寸之差(仅保留核完全在图像内部的区域)

高斯滤波器

均值滤波器对所有邻居赋予相同权重,这并不合理——直觉上,距离中心越近的像素应该对输出有更大的影响。高斯滤波器(Gaussian Filter)正是基于这一思想设计的。

二维高斯滤波器的核由高斯函数定义:

h(u,v)=12πσ2eu2+v22σ2h(u, v) = \frac{1}{2\pi\sigma^2} \e^{-\frac{u^2 + v^2}{2\sigma^2}}

其中 σ\sigma标准差,控制高斯函数的宽度。

离散近似

连续的高斯函数需要离散化为有限大小的核。例如 3×33 \times 3 的高斯核近似为:

H=116[121242121]H = \frac{1}{16} \begin{bmatrix} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \end{bmatrix}

中心权重最大(4),角落权重最小(1),符合「近邻影响大」的直觉。

高斯滤波器有两个关键参数:

标准差 σ\sigma 控制平滑程度。σ\sigma 越大,高斯函数越宽、越平坦,纳入更多远处像素的贡献,平滑效果越强。σ\sigma 是高斯滤波器最重要的参数,通常也被称为滤波器的「尺度」(Scale)。

核大小 应足够大以覆盖高斯函数的有效范围。高斯函数理论上有无限支撑(即在任何位置的值都不为零),但实际中会截断为有限大小的核。如果核太小(例如 σ=5\sigma = 5 但只用 10×1010 \times 10 的核),高斯函数会被截断,导致滤波效果失真;核大小通常取 6σ6\sigma 左右即可覆盖 99.7% 的面积。

平滑滤波器的性质

均值滤波器和高斯滤波器都属于平滑滤波器(Smoothing Filter),它们有以下共同性质:

  • 核中所有值为正
  • 核的所有值之和为 1——这保证了常数区域在滤波后保持不变
  • 平滑程度与核的大小成正比
  • 去除高频成分,保留低频成分——即低通滤波器(Low-pass Filter)

卷积

卷积的定义

互相关将核「滑过」图像进行加权求和,但在信号处理中更基本的运算是卷积(Convolution)。设 ff 为图像、gg 为核,卷积定义为:

(fg)[m,n]=k,lf[mk,nl]g[k,l](f * g)[m, n] = \sum_{k, l} f[m - k, n - l] \, g[k, l]

卷积与互相关的唯一区别在于:卷积在求和前将核翻转 180°(即同时沿水平和垂直方向翻转)。对于对称的核(如高斯核、均值核),卷积与互相关的结果完全相同。

直觉上,卷积操作可以分解为三步:(1) 翻转核(上下左右都翻转),(2) 将翻转后的核滑动到图像的每个位置,(3) 在每个位置计算核与图像局部区域的逐元素乘积之。翻转这一步看起来多此一举——下面会看到,正是翻转赋予了卷积良好的数学性质。

为什么需要翻转

翻转使得卷积具有良好的数学性质(如交换律和结合律),这些性质在信号处理的理论分析中至关重要。在实际图像处理中,由于常用的核大多是对称的,卷积和互相关的区别通常不大。

卷积的性质

卷积具有以下重要的代数性质:

交换律ab=baa * b = b * a。滤波器和信号在数学上是完全对称的——可以理解为「用核滑过图像」,也可以理解为「用图像滑过核」。

结合律a(bc)=(ab)ca * (b * c) = (a * b) * c。依次应用多个滤波器 (((ab1)b2)b3)(((a * b_1) * b_2) * b_3) 等价于先将所有核卷积在一起,再一次性对图像滤波:a(b1b2b3)a * (b_1 * b_2 * b_3)

分配律a(b+c)=(ab)+(ac)a * (b + c) = (a * b) + (a * c)

标量可提取kab=akb=k(ab)ka * b = a * kb = k(a * b)

单位元:单位脉冲 e=[,0,0,1,0,0,]e = [\ldots, 0, 0, 1, 0, 0, \ldots] 满足 ae=aa * e = a。与任何信号卷积后原样输出。

此外,卷积还具有两个关键的系统性质:

平移不变性(Shift Invariance):滤波器在图像的任何位置表现相同,即 filter(shift(f))=shift(filter(f))\text{filter}(\text{shift}(f)) = \text{shift}(\text{filter}(f))

线性(Linearity):filter(f1+f2)=filter(f1)+filter(f2)\text{filter}(f_1 + f_2) = \text{filter}(f_1) + \text{filter}(f_2)

一个重要的理论结果是:任何线性且平移不变的算子都可以表示为卷积。这意味着卷积是所有线性空间滤波器的统一表示。

这些性质的实用价值在于:结合律意味着可以把多步滤波「预编译」为一个核,省去重复计算;可分离性(下面讨论)利用特殊的核结构进一步降低计算量;平移不变性则保证了同一个滤波器对图像各处一视同仁。

卷积与互相关的对比

卷积:(fg)(x,y)=i,jf(i,j)g(xi,yj)\text{卷积:} \quad (f * g)(x, y) = \sum_{i, j} f(i, j) \, g(x - i, y - j)

互相关:(fg)(x,y)=i,jf(i,j)g(x+i,y+j)\text{互相关:} \quad (f \otimes g)(x, y) = \sum_{i, j} f(i, j) \, g(x + i, y + j)

两者的区别仅在于索引的符号:卷积用 (xi,yj)(x - i, y - j)(核被翻转),互相关用 (x+i,y+j)(x + i, y + j)(核不翻转)。对于对称核,两者等价。

可分离性

如果一个二维核可以分解为一个列向量和一个行向量的外积,则称其为可分离(Separable)的。此时二维滤波可以拆分为两步一维滤波:先沿行方向用一维核滤波,再沿列方向用另一个一维核滤波。

均值滤波器的可分离性

3×33 \times 3 的均值滤波器可以分解为列向量与行向量的外积:

19[111111111]=13[111]13[111]\frac{1}{9} \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix} = \frac{1}{3}\begin{bmatrix} 1 \\ 1 \\ 1 \end{bmatrix} \cdot \frac{1}{3}\begin{bmatrix} 1 & 1 & 1 \end{bmatrix}

即先用一维核 [1/3,1/3,1/3][1/3,\, 1/3,\, 1/3] 沿行方向滤波,再用同一核沿列方向滤波。

高斯滤波器天然是可分离的,因为二维高斯函数可以写成两个一维高斯函数的乘积:

12πσ2exp ⁣(x2+y22σ2)=[12πσexp ⁣(x22σ2)][12πσexp ⁣(y22σ2)]\frac{1}{2\pi\sigma^2} \exp\!\left(-\frac{x^2 + y^2}{2\sigma^2}\right) = \left[\frac{1}{\sqrt{2\pi}\sigma} \exp\!\left(-\frac{x^2}{2\sigma^2}\right)\right] \cdot \left[\frac{1}{\sqrt{2\pi}\sigma} \exp\!\left(-\frac{y^2}{2\sigma^2}\right)\right]

可分离性带来显著的计算加速:对 n×nn \times n 的图像使用 m×mm \times m 的核,直接卷积的复杂度为 O(n2m2)O(n^2 m^2),而利用可分离性拆分为两次一维卷积后,复杂度降为 O(n2m)O(n^2 m)——核越大,加速比越明显。

非线性滤波

前面介绍的均值滤波器和高斯滤波器都是线性滤波器——输出是邻域像素的线性组合。线性滤波器在处理高斯噪声时效果不错,但面对椒盐噪声时表现欠佳:极端的黑白噪声点虽然被「稀释」,但会向四周扩散,导致整幅图像变得模糊。

非线性滤波器(Non-linear Filter)突破了线性组合的限制,能针对特定类型的噪声取得更好的效果。

中值滤波器

中值滤波器(Median Filter)是最经典的非线性滤波器:将邻域内所有像素值排序,取中间值作为输出。

中值滤波的计算

对于 3×33 \times 3 的邻域:

[101520239027333130]\begin{bmatrix} 10 & 15 & 20 \\ 23 & 90 & 27 \\ 33 & 31 & 30 \end{bmatrix}

排序后为 10,15,20,23,27,30,31,33,9010, 15, 20, 23, \boxed{27}, 30, 31, 33, 90,中值为 27。异常值 90 被完全消除。

中值滤波器的三个重要特性:

不引入新值。输出值始终是邻域中已有的某个像素值,不会产生线性滤波器中常见的「介于两值之间」的模糊过渡。

有效去除脉冲噪声。椒盐噪声和脉冲噪声的特点是少数像素具有极端值——排序后这些极端值位于两端,中值不受影响。这正是线性滤波器难以做到的。

保持边缘锐利。在边缘处,邻域中大部分像素属于边缘某一侧,中值自然落在多数像素一侧,不会像均值那样将两侧的值混合。对比均值滤波在边缘处产生的渐变过渡,中值滤波能保持阶跃状的锐利边缘。

中值滤波是非线性的

中值滤波不满足线性的叠加性。反例:设

A=[111112222],B=[000010000]A = \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 2 \\ 2 & 2 & 2 \end{bmatrix}, \quad B = \begin{bmatrix} 0 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 0 \end{bmatrix}

中值 med(A)+med(B)=1+0=1\text{med}(A) + \text{med}(B) = 1 + 0 = 1,但 med(A+B)=21\text{med}(A + B) = 2 \ne 1。因此中值滤波不能表示为卷积。

双边滤波器

高斯滤波器有一个根本性的缺陷:它只考虑像素间的空间距离,不考虑像素值的差异。因此它在平滑纹理的同时也会模糊边缘。双边滤波器(Bilateral Filter)的设计目标正是解决这个问题——平滑纹理的同时保持边缘

为了建立直觉,先考虑一维情况:想象一个一维信号有一个明显的阶跃(边缘)。普通高斯模糊会把阶跃两侧的值混在一起,让锐利的跳变变成平缓的斜坡。双边滤波器的思路是:在计算加权平均时,不仅考虑邻居的距离,还考虑邻居的像素值是否与当前像素相似——如果相似,说明在同一个区域内,正常平滑;如果差异很大,说明跨越了边缘,降低其权重。

普通高斯模糊的公式为:

Ipb=qSGσs(pq)IqI_{\bm{p}}^{\text{b}} = \sum_{\bm{q} \in \mathcal{S}} G_{\sigma_s}(\|\bm{p} - \bm{q}\|) \, I_{\bm{q}}

权重仅取决于像素 p\bm{p}q\bm{q} 之间的空间距离 pq\|\bm{p} - \bm{q}\|

双边滤波器在此基础上增加了一个值域权重

Ipbf=1WpbfqSGσs(pq)空间权重  Gσr(IpIq)值域权重  IqI_{\bm{p}}^{\text{bf}} = \frac{1}{W_{\bm{p}}^{\text{bf}}} \sum_{\bm{q} \in \mathcal{S}} \underbrace{G_{\sigma_s}(\|\bm{p} - \bm{q}\|)}_{\text{空间权重}} \; \underbrace{G_{\sigma_r}(|I_{\bm{p}} - I_{\bm{q}}|)}_{\text{值域权重}} \; I_{\bm{q}}

其中 WpbfW_{\bm{p}}^{\text{bf}} 是归一化因子(确保权重之和为 1),GσsG_{\sigma_s}GσrG_{\sigma_r} 分别是空间域和值域的高斯函数。

空间权重 Gσs(pq)G_{\sigma_s}(\|\bm{p} - \bm{q}\|):与普通高斯模糊相同,空间上越近的像素权重越大。参数 σs\sigma_s 控制空间平滑范围。

值域权重 Gσr(IpIq)G_{\sigma_r}(|I_{\bm{p}} - I_{\bm{q}}|):像素值越相似的邻居权重越大,像素值差异越大的邻居权重越小。参数 σr\sigma_r 控制值域的容忍范围。

flowchart LR
    subgraph 高斯模糊
        A1["仅考虑空间距离"] --> A2["边缘处也平滑<br/>→ 边缘模糊"]
    end
    subgraph 双边滤波
        B1["空间距离 + 值域距离"] --> B2["边缘两侧像素值差异大<br/>→ 值域权重接近 0<br/>→ 边缘保持"]
    end

    classDef gauss fill:#ffebee,stroke:#c62828,stroke-width:2px
    classDef bilateral fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px

    class A1,A2 gauss
    class B1,B2 bilateral

双边滤波器的核形状是空间变化(Spatially Varying)的——在平坦区域,值域权重几乎不起作用,核接近标准高斯;在边缘附近,值域权重会大幅削弱边缘另一侧像素的贡献,核变得不对称,从而避免跨边缘平滑。

双边滤波的局限

双边滤波器对高斯噪声有良好的平滑效果,但无法有效去除椒盐噪声。这是因为椒盐噪声的像素值与邻居差异极大,值域权重会将这些噪声点视为「边缘」而保留它们。对于椒盐噪声,中值滤波仍然是更好的选择。

双边滤波器的计算代价较高:由于值域权重依赖于图像内容,每个像素的核都不同,无法利用 FFT 加速,需要对每个像素遍历其邻域进行计算。暴力实现的时间复杂度为 O(n2m2)O(n^2 m^2)nn 为图像边长,mm 为核的边长),在大图像上可能需要数分钟。虽然存在快速近似算法,但会带来一定的精度损失。

滤波器的选择

不同类型的噪声适合使用不同的滤波器:

噪声类型 推荐滤波器 原因
高斯噪声 高斯滤波器 / 双边滤波器 高斯滤波有效平滑随机波动;双边滤波可同时保持边缘
椒盐噪声 中值滤波器 排序操作天然排除极端值
一般降噪 + 保边缘 双边滤波器 值域权重自动适应边缘

线性 vs 非线性滤波器

线性滤波器(均值、高斯)可以用卷积表示,具有交换律、结合律等良好的数学性质,可利用可分离性和 FFT 加速计算。非线性滤波器(中值、双边)不能表示为卷积,但能在特定任务上(如保边缘去噪)显著优于线性滤波器。选择哪种滤波器取决于具体的应用需求。