如何在numpy / scipy中生成一个带圆圈的矩阵

时间:2016-08-22 07:50:22

标签: python numpy scipy signal-processing python-2.x

python's scipy中有一些信号生成辅助函数,但这些函数仅适用于1维信号。

我想生成一个2-D理想带通滤波器,它是一个全零的矩阵,带有一个圆圈,用于从我的图像中去除一些周期性噪声。

我现在正在做:

def unit_circle(r):
    def distance(x1, y1, x2, y2):
        return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
    d = 2*r + 1
    mat = np.zeros((d, d))
    rx , ry = d/2, d/2
    for row in range(d):
        for col in range(d):
            dist = distance(rx, ry, row, col)
            if abs(dist - r) < 0.5:
                mat[row, col] = 1
    return mat

结果:

In [18]: unit_circle(6)
Out[18]:
array([[ 0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.,  0.],
       [ 0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.],
       [ 0.,  0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.]])

是否有更直接的方式来生成matrix of circle of ones, all else zeros

编辑: Python 2.7.12

2 个答案:

答案 0 :(得分:3)

这是一个纯粹的NumPy替代品,应该运行得更快,看起来更干净,imho。基本上,我们通过用其NumPy替代品替换内置sqrtabs并处理索引矩阵来矢量化代码。

已更新distance替换np.hypot(由James K提供)

In [5]: import numpy as np

In [6]: def my_unit_circle(r):
   ...:     d = 2*r + 1
   ...:     rx, ry = d/2, d/2
   ...:     x, y = np.indices((d, d))
   ...:     return (np.abs(np.hypot(rx - x, ry - y)-r) < 0.5).astype(int)
   ...: 

In [7]: my_unit_circle(6)
Out[7]: 
array([[ 0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.,  0.],
       [ 0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.],
       [ 0.,  0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.]])

基准

In [12]: %timeit unit_circle(100)
100 loops, best of 3: 17.7 ms per loop

In [13]: %timeit my_unit_circle(100)
1000 loops, best of 3: 480 µs per loop

答案 1 :(得分:2)

这是一种矢量化方法 -

def unit_circle_vectorized(r):
    A = np.arange(-r,r+1)**2
    dists = np.sqrt(A[:,None] + A)
    return (np.abs(dists-r)<0.5).astype(int)

运行时测试 -

In [165]: %timeit unit_circle(100) # Original soln
10 loops, best of 3: 31.1 ms per loop

In [166]: %timeit my_unit_circle(100) #@Eli Korvigo's soln
100 loops, best of 3: 2.68 ms per loop

In [167]: %timeit unit_circle_vectorized(100)
1000 loops, best of 3: 582 µs per loop