站点图标 AI技术聚合

python中值滤波

排序滤波

排序滤波中最常用的就是中值滤波,简单来说,就是给一个滤波范围,然后找到这个范围中的中位数,重新赋值给当前值。

例如,[1,3,2,4]这个数组,给定一个长度为3的滤波窗口,那么元素3所在位置的滤波范围就是1,3,2这三个数,这三个数的中位数是2,所以要把3更改为2。

import numpy as np
import scipy.signal as ss
x = np.arange(15)
x = [1,3,2,4]
ss.medfilt(x,3)
# array([1, 2, 3, 2])

二维的中值滤波在图像处理中非常常见,对椒盐噪声有着非常霸道的效果。

import matplotlib.pyplot as plt
img = plt.imread('img.jpg').astype(float)/255
rand = np.random.rand(*img.shape)
rand = rand * (rand > 0.9)
img += rand

fig = plt.figure("medfilt2")
ax = fig.add_subplot(1,2,1)
ax.imshow(img)
ax = fig.add_subplot(1,2,2)
img1 = img + 0  #深拷贝
for i in range(3):
    img1[:,:,i] = ss.medfilt2d(img1[:,:,i], [3,3])

ax.imshow(img1)
plt.show()


(上面这个图是我在搜lena图的时候出来的,虽然不是我认识的那个lena,但感觉用来做图像处理也不错,不知道这个算不算lena二代)

中值滤波要做的第一件事,就是对滤波窗口中的数据排序,然后才能找到中位数。但从另一个角度来看,仅仅认为中位数是有效值,貌似并不公平,所以scipy提供了更加高级的排序滤波函数order_filter

其输入参数除了待滤波函数之外,还包括一个滤波窗口以及保留值的大小次序。

from scipy import signal
x = np.arange(25).reshape(5, 5)
domain = np.identity(3)
x
'''
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])
'''
signal.order_filter(x, domain, 0)
'''
array([[  0.,   0.,   0.,   0.,   0.],
       [  0.,   0.,   1.,   2.,   0.],
       [  0.,   5.,   6.,   7.,   0.],
       [  0.,  10.,  11.,  12.,   0.],
       [  0.,   0.,   0.,   0.,   0.]])
'''
signal.order_filter(x, domain, 2)
'''
array([[  6.,   7.,   8.,   9.,   4.],
       [ 11.,  12.,  13.,  14.,   9.],
       [ 16.,  17.,  18.,  19.,  14.],
       [ 21.,  22.,  23.,  24.,  19.],
       [ 20.,  21.,  22.,  23.,  24.]])
'''

其中,domain是一个单位阵,order_filter(x, domain, 0)表示选出对角阵所对应元素中排名第0的元素,也就是最小值;order_filter(x, domain, 2)选择的是排名第2的元素,也就是最大值。

就实际情况来看,domain覆盖的第一个子阵中,以0为中心,则只能覆盖到2×2的范围,其对角元素为0,6,最小值是0,最大值是6。如以6为中心,则可以完全覆盖3×3的内容,最小值为0,最大值为12。

文章出处登录后可见!

已经登录?立即刷新
退出移动版