3、空间域滤波去噪:均值滤波、中径滤波、高斯滤波原理与Python实现

各位同学,今天我们来聊聊遥感图像去噪里最基础、也最实用的三个滤波器。说实话,我刚开始做遥感图像处理那会儿,拿到一张满是椒盐噪声的卫星图,第一反应就是直接上均值滤波。结果呢?噪声是淡了,但地物边缘也糊成了一片。后来才明白——滤波这事儿,没有银弹,只有对症下药

核心观点:空间域滤波的本质,就是用邻域像素的某种统计值来替换中心像素值。你选什么统计方式,就决定了滤波器的性格。

3.1 均值滤波:简单但代价明显

均值滤波的原理,说白了就是取一个窗口(比如3×3),把窗口内所有像素的灰度值加起来求平均,然后用这个平均值去替换窗口中心的像素值。

数学表达:

g(x,y) = (1/(m×n)) × Σ f(i,j)  其中(i,j)属于窗口W

我在项目中遇到过一件事:处理某地区的Landsat影像时,用3×3均值滤波去噪,结果把一条很细的公路给滤没了。为什么?因为公路在影像上只有1-2个像素宽,均值滤波一平均,它就和周围农田混在一起了。

避坑指南:我曾经用5×5均值滤波处理高分辨率遥感影像,结果建筑物边缘全部模糊,后续的建筑物提取完全没法用。均值滤波的窗口越大,模糊越严重,这是它的硬伤。

Python实现:

import cv2
import numpy as np

# 读取遥感图像
img = cv2.imread('remote_sensing.tif', 0)  # 灰度图

# 均值滤波
mean_blur = cv2.blur(img, (3, 3))  # 3×3窗口
mean_blur_5 = cv2.blur(img, (5, 5))  # 5×5窗口

# 或者用卷积核手动实现
kernel = np.ones((3,3), np.float32) / 9
mean_manual = cv2.filter2D(img, -1, kernel)

3.2 中值滤波:椒盐噪声的克星

中值滤波的思路完全不同——它不取平均,而是取窗口内所有像素的中位数。你想想看,如果窗口里有个像素值是255(亮点噪声),其他都是正常值,中位数大概率还是正常值,噪声就被剔除了。

我个人习惯在处理椒盐噪声时首选3×3中值滤波。为什么?因为椒盐噪声是孤立的亮点或暗点,中值滤波天然对这类噪声免疫。

经验之谈:我在处理某次台风前后的SAR影像时,图像上全是斑点噪声(类似椒盐噪声),均值滤波效果很差,但中值滤波一次就干净了。记住:中值滤波保边缘、去椒盐,但计算量比均值滤波大

Python实现:

# 中值滤波
median_blur = cv2.medianBlur(img, 3)  # 3×3窗口
median_blur_5 = cv2.medianBlur(img, 5)  # 5×5窗口

# 手动实现中值滤波(理解原理)
def median_filter(img, kernel_size=3):
    pad = kernel_size // 2
    padded = cv2.copyMakeBorder(img, pad, pad, pad, pad, cv2.BORDER_REFLECT)
    result = np.zeros_like(img)
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            window = padded[i:i+kernel_size, j:j+kernel_size]
            result[i,j] = np.median(window)
    return result

3.3 高斯滤波:更自然的平滑

高斯滤波和均值滤波有点像,但它不是简单平均,而是加权平均——离中心像素越近的像素,权重越大。这个权重由高斯函数决定。

高斯核公式:

G(x,y) = (1/(2πσ²)) × exp(-(x²+y²)/(2σ²))

σ(sigma)控制了权重的分布。σ越大,中心像素的权重越小,平滑效果越强。我建议你记住:σ=0.8到1.2之间,是遥感图像去噪的黄金区间

为什么用高斯滤波?因为自然图像(包括遥感影像)中的噪声往往服从高斯分布,用高斯滤波去噪,理论上是最匹配的。而且它比均值滤波更保边缘——虽然还是会模糊,但没那么生硬。

Python实现:

# 高斯滤波
gaussian_blur = cv2.GaussianBlur(img, (3, 3), sigmaX=1.0)  # σ=1.0
gaussian_blur_2 = cv2.GaussianBlur(img, (5, 5), sigmaX=1.5)  # 更大窗口

# 手动生成高斯核
def gaussian_kernel(size=3, sigma=1.0):
    kernel = np.zeros((size, size))
    center = size // 2
    for i in range(size):
        for j in range(size):
            x, y = i - center, j - center
            kernel[i,j] = np.exp(-(x**2 + y**2) / (2 * sigma**2))
    kernel /= kernel.sum()  # 归一化
    return kernel

kernel_3x3 = gaussian_kernel(3, sigma=1.0)
gaussian_manual = cv2.filter2D(img, -1, kernel_3x3)

3.4 三种滤波器的对比与选择

滤波器 原理 适用噪声 保边缘能力 计算速度
均值滤波 邻域平均 高斯噪声
中值滤波 邻域中位数 椒盐噪声 中等
高斯滤波 加权平均 高斯噪声 中等

嗯,这里要注意:没有哪个滤波器是万能的。我在实际项目中,经常是先用中值滤波去椒盐噪声,再用高斯滤波做一次平滑。两步走,效果比单用任何一个都好。

我的建议:拿到一张遥感影像,先看噪声类型。如果是黑白点(椒盐),用中值滤波;如果是整体灰蒙蒙(高斯噪声),用高斯滤波;如果只是随便看看,均值滤波也能凑合——但别指望它保边缘。

3.5 本章知识体系

下面这张图,是我自己总结的三种滤波器的核心逻辑。你看一眼,就能明白它们之间的区别和联系。

空间域滤波去噪核心逻辑 输入遥感图像 均值滤波 中值滤波 高斯滤波 邻域平均 → 模糊边缘 适用:高斯噪声 | 速度快 邻域中位数 → 保边缘 适用:椒盐噪声 | 速度中等 加权平均 → 自然平滑 适用:高斯噪声 | 保边缘中等 去噪后图像

最后说一句:滤波器的选择,取决于你的后续任务。如果要做地物分类,保边缘比去噪更重要,那就优先选中值滤波或高斯滤波。如果只是做可视化,均值滤波也能用——但别用太大窗口,3×3就够了。

一句话总结:均值滤波求平均,中值滤波取中位,高斯滤波加权平均。三种方法,三种性格,选对了,事半功倍。

专注资料整理