Python科学计算(第2版)
上QQ阅读APP看书,第一时间看更新

3.6.1 中值滤波

中值滤波能够比较有效地消除声音信号中的瞬间噪声或者图像中的斑点噪声。在signal模块中,medfilt( )对一维信号进行中值滤波,而medfilt2d( )对二维信号进行中值滤波。在scipy.ndimage模块中另有针对多维图像的中值滤波器,这里简单演示medfilt( )的效果。

    t = np.arange(0, 20, 0.1)
    x = np.sin(t)
    x[np.random.randint(0, len(t), 20)] += np.random.standard_normal(20)*
0.6 ❶
    x2 = signal.medfilt(x, 5) ❷
    x3 = signal.order_filter(x, np.ones(5), 2)
    print np.all(x2 == x3)
    pl.plot(t, x, label=u"带噪声的信号")
    pl.plot(t, x2 + 0.5, alpha=0.6, label=u"中值滤波之后的信号")
    pl.legend(loc="best")
    True

❶首先创建一个带有随机的瞬间噪声的正弦波,❷然后调用medfilt( )进行中值滤波,第二个参数为计算中值的窗口大小,它必须是一个奇数。medfilt( )将信号中的每个元素都替换为其窗口内的中值。

最后绘制原始信号和滤波信号,为了便于比较,图中将滤波之后的信号统一向上偏移了0.5,结果如图3-31所示。中值滤波是排序滤波的一个特例。使用排序滤波可以将元素替换为其窗口内指定排序顺序的元素。其调用形式如下:

图3-31 使用中值滤波剔除瞬间噪声

    order_filter(a, domain, rank)

其中a是一个多维数组,domain是维数和a相同的数组,它指定窗口的范围,rank是一个非负整数,用来选择窗口中元素排序后的值,0表示选择最小值,1表示选择第二小的值。中值滤波也可以用order_filter( )计算,注意domain参数是一个长度为5、值全为1的数组。