Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

匹配滤波器

当在图像 ff 中搜索一个完全已知的子图像或模板 gg 时,计算 ffgg 之间的互相关是一种非常有效的技术。这种技术通常被称为匹配滤波器。其主要目标是通过最大化信噪比(SNR)来检测已知模式在可能带噪声的信号中的存在。

ffgg 之间的互相关产生一个新图像 Rf,gR_{f,g},定义为:

Rf,g(u,v)=m,nf(m,n)g(u+m,v+n).R_{f,g}(u,v) = \sum_{m,n} f(m,n) g(u+m,v+n).

该操作将模板 gg 在图像 ff 上滑动,并在每个位置计算元素乘积的总和。生成的图像 Rf,gR_{f,g} 将在模式存在的位置具有较高的值。

通常,ffgg 会被归一化,以对亮度和对比度的变化不敏感:

f~(m,n)=f(m,n)μfσfg~(m,n)=g(m,n)μgσg\tilde{f}(m,n) = \frac{ f(m,n)-\mu_f }{ \sigma_f } \qquad \tilde{g}(m,n) = \frac{ g(m,n)-\mu_g }{ \sigma_g }

其中 μf\mu_fσf\sigma_f 是图像 ff 的均值和标准差(在模板下的区域计算)。这导致了归一化互相关:

R~f,g(u,v)=m,nf~(m,n)g~(u+m,v+n).\tilde{R}_{f,g}(u,v) = \sum_{m,n} \tilde{f}(m,n) \tilde{g}(u+m,v+n).

Figure 1 给出了一个匹配滤波的例子。

使用左上角所示的模式(字母G)进行的归一化互相关。

Figure 1:使用左上角所示的模式(字母G)进行的归一化互相关。

匹配滤波、卷积和互相关

在信号处理中,匹配滤波操作是作为卷积来实现的。然而,卷积的数学定义与用于模板匹配的互相关之间存在一个微妙但重要的区别。

二维卷积定义为:

(fg)(u,v)=m,nf(m,n)g(um,vn)(f*g)(u,v) = \sum_{m,n} f(m,n) g(u-m,v-n)

注意负号项 (um,vn)(u-m, v-n)。这意味着在应用于图像之前,滤波器 gg 被翻转(旋转180度)。

用于模板匹配的互相关定义则不翻转滤波器。要使用卷积操作执行匹配滤波(即互相关),必须首先翻转模板。换句话说,ffgg 的互相关等价于 ffgg 的空间反转版本的卷积。

如下图所示,当模板(或滤波器)不对称时,这种区别至关重要。互相关通过找到最大响应来正确定位模式的位置,而标准卷积则无法做到这一点。

使用不对称的“L”形核的卷积操作。该操作未能在模式所在位置产生最大响应。

Figure 2:使用不对称的“L”形核的卷积操作。该操作未能在模式所在位置产生最大响应。

互相关(匹配滤波)操作。这通过在图像中心(模式所在位置)产生最大值5来正确定位“L”形模式。

Figure 3:互相关(匹配滤波)操作。这通过在图像中心(模式所在位置)产生最大值5来正确定位“L”形模式。

二维匹配滤波器示例

这是一个使用Python的二维匹配滤波器的简单示例。我们将创建一个带有模式的简单图像,添加一些噪声,然后使用匹配滤波器来找到该模式。

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# 配置中文字体支持
plt.rcParams['font.sans-serif'] = [
    'Noto Sans CJK SC', 'Noto Sans CJK JP', 'SimHei',
    'Microsoft YaHei', 'WenQuanYi Micro Hei', 'DejaVu Sans'
]
plt.rcParams['axes.unicode_minus'] = False

# 创建一个样本图像
image = np.zeros((100, 100))
image[20:40, 30:50] = 1 # 图像中的一个矩形

# 创建一个模板
template = np.ones((20, 20))

# 向图像中添加一些噪声
noisy_image = image + np.random.normal(0, 0.3, image.shape)

# 使用互相关执行匹配滤波
correlation = signal.correlate2d(noisy_image, template, boundary='symm', mode='same')

# 在相关图中找到峰值
y, x = np.unravel_index(np.argmax(correlation), correlation.shape)

# 显示结果
fig, (ax_orig, ax_template, ax_corr) = plt.subplots(1, 3, figsize=(12, 4))

ax_orig.imshow(noisy_image, cmap='gray')
ax_orig.set_title('原始图像')
ax_orig.set_axis_off()

ax_template.imshow(template, cmap='gray')
ax_template.set_title('模板')
ax_template.set_axis_off()

ax_corr.imshow(correlation, cmap='viridis')
ax_corr.set_title('互相关')
ax_corr.set_axis_off()
ax_corr.plot(x, y, 'ro') # 标记峰值

plt.show()

<Figure size 1200x400 with 3 Axes>

与卷积神经网络(CNN)的联系

匹配滤波的概念为理解卷积神经网络(CNN)提供了一个有力的视角。CNN中的核心操作是卷积,其中可训练的核在输入图像或特征图上滑动。

从匹配滤波的角度来看,这些核本质上是网络学习用来检测的模板。在训练过程中,每个核都被优化以“匹配”对给定任务(例如分类)重要的特定特征或模式(如边缘、角点、纹理或更复杂的对象部分)。CNN中的卷积-激活-池化链可以被看作是一种复杂且自适应的匹配滤波形式,网络在其中学习用于分层特征提取的最优滤波器集。

单个匹配滤波器的主要局限性在于它对方向、大小等变化很敏感。为了克服这一点,可以应用多个匹配滤波器,每个滤波器代表模式的不同变体。这正是CNN通过在每一层学习大量滤波器所做的事情,使它们能够在各种变换下稳健地检测模式。

🤖