You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用NumPy、SciPy或Scikit-image实现3x3窗口的2D均值滤波?

问题解答

首先,你使用np.average的方式并不适用于2D滑动窗口均值滤波——该函数的weights参数在输入数组与权重数组形状不同时,仅支持一维权重,它的设计目标并非实现滑动窗口式的滤波操作。

NumPy实现2D均值滤波的方法

NumPy本身没有内置的滑动窗口均值滤波函数,但可以通过np.lib.stride_tricks.sliding_window_view(NumPy 1.20及以上版本支持)手动构造滑动窗口,再计算均值:

import numpy as np

a = np.arange(25).reshape(5, 5)
# 生成所有3x3的滑动窗口
windows = np.lib.stride_tricks.sliding_window_view(a, window_shape=(3, 3))
# 对每个窗口的所有元素求均值,得到3x3的滤波结果
filtered = windows.mean(axis=(2, 3))

上述代码会截断原矩阵的边缘(5x5矩阵滑3x3窗口后得到3x3结果),如果需要保留原矩阵尺寸,可以先用np.pad对原矩阵进行边缘填充,比如:

# 用0填充边缘,填充后矩阵为7x7
padded_a = np.pad(a, pad_width=1, mode='constant', constant_values=0)
windows = np.lib.stride_tricks.sliding_window_view(padded_a, window_shape=(3, 3))
filtered = windows.mean(axis=(2, 3))  # 结果为5x5,与原矩阵尺寸一致

SciPy的实现方案

SciPy的scipy.ndimage.uniform_filter是专门用于均值滤波的函数,使用非常简便,还支持多种边缘填充模式:

from scipy.ndimage import uniform_filter

a = np.arange(25).reshape(5, 5)
# 3x3窗口均值滤波,默认用0填充边缘,可通过mode参数调整
filtered = uniform_filter(a, size=3)
# 示例:使用反射模式填充边缘
filtered_reflect = uniform_filter(a, size=3, mode='reflect')

mode参数可选值包括'constant'(默认,常数填充)、'reflect'(边缘反射)、'nearest'(最近邻填充)等。

Scikit-image的实现方案

Scikit-image提供了多个可用于均值滤波的函数:

  1. box_filter:适合浮点型输入,支持归一化(即均值滤波):
from skimage.filters import box_filter

a = np.arange(25).reshape(5, 5)
# size指定窗口大小,normalize=True表示计算均值
filtered = box_filter(a, size=3, normalize=True)
  1. rank.mean:适合处理整数类型的图像数据,需要配合结构元素使用:
from skimage.filters.rank import mean
from skimage.util import img_as_ubyte

a = np.arange(25).reshape(5, 5)
# 将数组转换为uint8类型(rank类函数要求输入为整数类型)
a_ubyte = img_as_ubyte(a / a.max())
# 用3x3的全1结构元素做均值滤波
filtered = mean(a_ubyte, np.ones((3, 3)))

内容的提问来源于stack exchange,提问作者Paul Jurczak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:41:19