排序滤波
排序滤波中最常用的就是中值滤波,简单来说,就是给一个滤波范围,然后找到这个范围中的中位数,重新赋值给当前值。
例如,[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。
文章出处登录后可见!
已经登录?立即刷新