Python 如何在numpy/scipy中生成具有一个圆的矩阵

Python 如何在numpy/scipy中生成具有一个圆的矩阵,python,numpy,scipy,signal-processing,python-2.x,Python,Numpy,Scipy,Signal Processing,Python 2.x,中有一些信号生成辅助函数,但这些函数仅适用于一维信号 我想生成一个2-D理想带通滤波器,它是一个全零矩阵,用一个1圆来去除图像中的周期性噪声 我现在做的是: 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理想带通滤波器,它是一个全零矩阵,用一个1圆来去除图像中的周期性噪声

我现在做的是:

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
有没有更直接的方法来生成一个由一个圆和所有其他零组成的矩阵

编辑:
Python2.7.12

这里是一个纯NumPy的替代方案,它应该运行得更快,看起来更干净,imho。基本上,我们通过将内置的
sqrt
abs
替换为它们的NumPy替代品,并处理索引矩阵,来实现代码的矢量化

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


这是一种矢量化方法-

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)

当前输出是否是您想要的输出?@OhadEytan是的,但感觉有点复杂,希望看到其他解决方案。事实上,我很想知道是否有框架可以生成像scipy提供的一维信号那样的二维信号。您应该始终指定您的python版本,因为除法运算符在Py2和Py3中的工作方式不同,除非您从Py2中的
\uuuuuu future\uuuuuu
导入新运算符。numpy有一个“距离”函数已经
np.hypot(x1,x2)
@EliKorvigo谢谢!您的解决方案确实更干净、更快!奇怪的是,在我的机器上,您的解决方案只快了150微秒(350微秒对500微秒)。你能提供你的机器的规格吗?@EliKorvigo我有一台旧机器:Intel(R)Core(TM)2 Duo CPU T6600@2.20GHz,4GB RAM。但我认为数字应该不会那么接近。@EliKorvigo好吧,所以我在ideone上运行了它,当我在
100
200
1000
上作为输入时,矢量化版本似乎运行在您方法的
2/3
。我想这是可以信任的。以下是ideone运行:这与您的计时一致。使用单个迭代进行测试不是一件好事,因此我使用
timeit
重新运行它。你的解决方案确实快了30%我想知道,是什么让它在你的机器上运行速度慢了近5倍。
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
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