如何在java中编写中值过滤器?

时间:2014-06-17 05:31:41

标签: java python filtering

我在python中有以下中值过滤器,我需要将其转换为java作为项目的一部分。问题是,我不知道这应该如何运作。

def medfilt (x, k):
    """Apply a length-k median filter to a 1D array x.
    Boundaries are extended by repeating endpoints.
    """
    assert k % 2 == 1, "Median 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]fi
    return np.median (y, axis=1)

任何帮助/资源将不胜感激!感谢。

编辑:我理解alg正在做什么,但不知道如何最好地将范围内容转换为java:

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]fi

2 个答案:

答案 0 :(得分:1)

这看起来像是调用numpy方法。对于中值方法调用,请查看此处:http://docs.scipy.org/doc/numpy/reference/generated/numpy.median.html。要了解如何使用numpy更好地了解此方法的工作原理,请执行以下操作:http://docs.scipy.org/doc/numpy/

正如我所知,A'中值滤波器用于信号处理以降低噪声。这个例子似乎与某种科学数据集有关,虽然我不确定只有这一个代码片。 wikipedia article将是一个很好的起点,scipy even has such a method。这似乎是中值滤波器的特殊实现。

答案 1 :(得分:0)

这是一个有趣的中值滤波器,我不得不承认我无法想到它的用途。从性能的角度来看,在那里执行的矢量化似乎并不是非常有益,因此实际的中值发现可以在循环内完成。

为了看看循环的作用,让我们假设k = 7。然后k2 = 3,循环运行三次(两次足以显示发生的情况):

i = 0
j = 3
# fill in row 0
# shift the x vector right by three and fill the beginning with the first element
y[3:,0] = x[:-3]
y[:3,0] = x[0] 
# fill in the last row (-1), i.e. row 6
# shift the x vector left by 3 and fill the end by the last element   
y[:-3,-1] = x[3:]
y[-3:,-1] = x[-1]

i = 1
j = 2
# fill in row 1
# shift the x vector right by 2 and fill the beginning with the first element
y[2:,0] = x[:-2]
y[:2,0] = x[0] 
# fill in the second last row (-2), i.e. row 5
# shift the x vector left by 2 and fill the end by the last element   
y[:-2,-1] = x[2:]
y[-2:,-1] = x[-1]

...

(我想告诉代码的原作者,for循环并不昂贵,而python是易读性的。两个循环本来就容易阅读,而且这个算法在其他方面可以更快。 )

无论如何,所需的数组是:

x0 x0 x0 x0 x1 x2 x3 ...          x(n-4)
x0 x0 x0 x1 x2 x3 ...             x(n-3)
x0 x0 x1 x2 x3 ...                x(n-2)
x0 x1 x2 x3 ...                   x(n-1)
x1 x2 x3 ...               x(n-1) x(n-1)
x2 x3 x4 ...        x(n-1) x(n-1) x(n-1)
x3 x4 x5 ... x(n-1) x(n-1) x(n-1) x(n-1)

,结果向量是每个中位数。

在我看来,无论语言如何,算法都有很大的改进空间。在任何情况下,计算数组然后取中位数并不是很有用。只为每个循环创建一个向量y会更好。

(作为一个BTW,代码可以用百万种方式编写,以便更清晰,例如:

n = len(x)
k2 = k / 2
y = np.empty(n + 2 * k2)
m = np.empty(k)
for i in range(k):
    y[:i] = x[0]
    y[i, i:n+i] = x
    y[n+i:] = x[-1]
    m[i] = median(y[k2:-k2])
return m

但这是另一个故事。)

在这种情况下,计算完整向量x(将给出x - (k-1)/ 2个样本)的可用中位数就足够了。然后可以分别计算不同的边缘填充,即:

median( x0 x0 x1 x2 x3 x4 x5)
median( x0 x0 x0 x1 x2 x3 x4)
median( x0 x0 x0 x0 x1 x2 x3) = x0
median( x0 x0 x0 x0 x0 x1 x2) = x0
median( x0 x0 x0 x0 x0 x0 x1) = x0

median( x(n-6) x(n-5) x(n-2) x(n-3) x(n-2) x(n-1) x(n-1) )
median( x(n-5) x(n-4) x(n-3) x(n-2) x(n-1) x(n-1) x(n-1) )
median( x(n-4) x(n-3) x(n-2) x(n-1) x(n-1) x(n-1) x(n-1) ) = x(n-1)
median( x(n-3) x(n-2) x(n-1) x(n-1) x(n-1) x(n-1) x(n-1) ) = x(n-1)
median( x(n-2) x(n-1) x(n-1) x(n-1) x(n-1) x(n-1) x(n-1) ) = x(n-1)

所以,实际上你可以通过简单地获取向量的中值来获得该算法给出的所有信息:

x0 x0 x0 x0 x1 x2 ... x(n-2) x(n-1) x(n-1) x(n-1) x(n-1)

对于k点中值滤波器,每端的填充量是(k-1)/ 2。似乎算法有点傻或者我错过了什么。