【问题标题】:SciPy medfilt wrong resultSciPy medfilt 错误的结果
【发布时间】:2014-07-05 10:59:37
【问题描述】:

嗨 python 爱好者!

我目前正在为研究目的使用信号过滤,并决定使用 SciPy。没什么特别的,只是日常工作的自动化。

所以,这里是代码

from scipy.signal import medfilt
print(medfilt([2,6,5,4,0,3,5,7,9,2,0,1], 5))

但问题是返回的序列计算错误

SciPy: [ 2. 4. 4. 4. 4. 4. 5. 5. 5. 2. 1. 0.]
Me   : [ 5. 4.5 4. 4. 4. 4. 5. 5. 5. 2. 1.5 1.]

似乎是,包的开发人员搞砸了一个细节。当孔径(SciPy 中的内核)大于要分析的窗口时,还有另一个过滤规则。

例如,kernel=5[2, 6, 5] 的过滤子序列的中位数为 5 而不是 SciPy 计算的 2,不是吗?同样,如果kernel=5 子序列[2,6,5,4] 的中位数是5 和4,我们需要取它们之间的平均值,所以中位数是4.5。

谁能解释一下在这种情况下谁得到了正确的结果?

【问题讨论】:

    标签: python numpy scipy median


    【解决方案1】:

    我相信你和 SciPy 都有正确的结果。不同之处在于边界会发生什么,但我相信你和 SciPy 都做出了正确的选择。

    问题是当您的滑动窗口位于边缘并且没有有效数据可用于填充您的滑动窗口时会发生什么

    您选择采用滑动窗口有效部分的中值,这是有道理的,但可能会增加一些偏差,因为与所有其他点相比,您的边缘点的代表性过高。

    SciPy 选择通过填充零来扩展任一边缘的信号。所以,在边界上,SciPy 本质上是在计算

    >>> np.median([0, 0, 2, 6, 5])
    2.0
    >>> np.median([0, 2, 6, 5, 4])
    4.0
    >>> np.median([9, 2, 0, 1, 0])
    1.0
    >>> np.median([2, 0, 1, 0, 0])
    0.0
    

    SciPy 这样做的原因几乎肯定与速度有关:它针对多次执行相同的事情进行了优化,并且针对一大堆 5 元素数组优化 median 比优化针对一大堆 5 元素数组以及两个 4 元素数组和两个 3 元素数组对其进行优化。肯定有一个论点是它不应该用零填充,而是用边界值填充,但应该注意的是,没有边界策略是完美的;处理边界问题的理想方法将取决于您的特定信号。

    如果您看到Wikipedia's description of median filters,它们会通过在边缘处填充值来扩展信号的任一边缘,这似乎也是合理的。他们还注意到处理边界问题的其他三种方式:

    • 避免处理边界,无论之后是否裁剪信号边界。
    • 从信号中的其他位置获取条目。例如,对于图像,可能会选择来自远水平或垂直边界的条目。
    • 缩小边界附近的窗口,使每个窗口都满了(就像您所做的那样。)

    最后,您确实需要尝试不同的选项,看看哪种方案最适合您的信号。这种过滤的核心假设是您的信号将非常大,并且边界问题永远不应该那么关键(因为大部分信号不存在于边界上)。不过,如果 SciPy 允许您选择它应该在边界处做什么,那就太好了!

    【讨论】:

    猜你喜欢
    • 2014-01-05
    • 1970-01-01
    • 2019-03-24
    • 2018-11-26
    • 1970-01-01
    • 2015-05-24
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多