【问题标题】:Mean Filter in python without loops没有循环的python中的均值过滤器
【发布时间】:2020-07-23 15:07:01
【问题描述】:

我被要求在具有给定内核的一维数组上创建一个 mean_filter 函数,假设填充为零。

均值滤波器是一种旨在去除噪声的算法。它需要一个数组,一个内核(比如 K),并用周围 K 值的平均值替换数组的每个值,包括本身在内。

此算法用于图像处理。

我能够做到这一点-

def mean_filter(arr, k):
    # applies mean filter to 1-d array with the kernel size 2k+1 . Write your code here
    p=len(arr)
    arr2=np.zeros(2*k+p, dtype=float)
    arr3=np.zeros(2*k+p, dtype=float)
    arr4=np.zeros(p, dtype=float)

    for i in range(p):
        arr2[k+i]=arr[i]

    for i in range(k,k+p):
        sum=0
        for j in range(-k,k+1):
            sum+=arr2[i+j]
        arr3[i]=sum/float(2*k+1)

    for i in range(p):
        arr4[i]=arr3[k+i]

    return arr4

但他们对我的期望是在没有任何循环的情况下做到这一点。

指令如下: "这个任务应该在没有任何类型的循环、理解或函数的情况下完成 比如 np.vectorize 等。

不要为此任务使用内置卷积函数"

我真的不知道如何做到这一点。你能建议点什么吗?线索将不胜感激。

【问题讨论】:

  • 不清楚在这种情况下“平均过滤器”是什么意思。但看起来shift 方法至少在这里对你有用。
  • @Chris 我已经添加了均值滤波器的含义。另外,我不明白 shift 会有什么帮助。

标签: python image-processing mean smoothing


【解决方案1】:

举例:

import numpy as np
k=2
kern=np.ones(2*k+1)/(2*k+1)
arr=np.random.random((10))
out=np.convolve(arr,kern, mode='same')

【讨论】:

  • 问题要求不要使用内置卷积函数
  • 没有填充怎么办?
【解决方案2】:

我找到了一个解决方案,该解决方案的灵感来自我在尝试实现不同的边缘行为时偶然发现的一个 matlab 函数,而在均值滤波中没有填充:https://www.mathworks.com/matlabcentral/fileexchange/23287-smooth2a。 它适用于矩阵乘法,不涉及循环或卷积。 使用一维数组,它会给出这样的结果:

import scipy.sparse
import numpy as np

def mean_filter(arr, k):
    p = len(arr)
    diag_offset = np.linspace(-(k//2), k//2, k, dtype=int)
    eL = scipy.sparse.diags(np.ones((k, p)), offsets=diag_offset, shape=(p, p))
    nrmlize = eL @ np.ones_like(arr)
    return (eL @ arr) / nrmlize

这是如何工作的,您创建一个对角线与内核大小一样多的矩阵,然后对您的数组进行点积。结果是一个数组,其中每个元素都是内核上原始数组元素的总和。基本上,这相当于卷积。最后,您通过内核大小对该总和进行归一化。

需要注意的一点是,在您无法构建完整内核的阵列边缘,使用了适合您的阵列的尽可能多的内核(这就是为什么您不能在之后仅通过标量进行归一化)。

这个解决方案也可以扩展到多维数组。

【讨论】:

    【解决方案3】:
    def meanfilt (x, k):
        """Apply a length-k mean filter to a 1D array x.
        Boundaries are extended by repeating endpoints.
        """
        
        import numpy as np
    
        assert k % 2 == 1, "Mean filter length must be odd."
        assert x.ndim == 1, "Input must be one-dimensional."
        
        k2 = (k - 1) // 2
        y = np.zeros ((len (x), k), dtype=x.dtype)
        y[:,k2] = x
        for i in range (k2):
            j = k2 - i
            y[j:,i] = x[:-j]
            y[:j,i] = x[0]
            y[:-j,-(i+1)] = x[j:]
            y[-j:,-(i+1)] = x[-1]
        return np.mean (y, axis=1)
    

    注意:答案选自repo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-29
      • 2011-02-03
      • 2012-07-02
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      相关资源
      最近更新 更多