加速python-cod

2024-09-28 23:28:04 发布

您现在位置:Python中文网/ 问答频道 /正文

编辑2:基于评论的附加信息: 该函数用于计算图像的径向积分(即在极坐标系下),然后通过半径进行归一化。一、 e.在数学符号中:rotmean=Integrate[f[r]r,{r,0,rmax}]/Integrate[r,{r,0,rmax}]。实际上,当我将图像从二维像素映射展平到一维径向平均值时,我希望进行双线性插值。如果我不插值,只使用最近的邻居,接近于零半径的值可能会很差。在

所以算法可以描述如下:

  • 计算半径网格

  • 找到半径的底面作为矩阵索引

  • 从底边找出像素的双线性插值的余数

现在,对于底部给出的矢量化解,我做了一些预计算:

  • 找到由双线性插值加权的图像(0和+1像素分别为mage_p和mage\n。这给出了径向和(而不是平均值)积分[f[r]r,{r,0,rmax}]

  • 概念上(对我来说)将问题矢量化的困难一步是将N**2像素的图像压缩成N*sqrt(2)径向和。这是用诸如“rmean[rfloor]=mage_p”这样的行完成的,注意rfloor的长度都是N**2,而rmean的长度是N*sqrt(2)

  • 同时计算权重,得到积分[r,{r,0,rmax}]

  • 从径向和转换为平均值。

原职务: 我正在尝试将一个函数从Matlab移植到Python(基于winpythonx64 2.7.6.4),我正为它的缓慢而挣扎。该代码被设计用来获取图像围绕中心的旋转平均值。典型的应用是求图像的旋转平均功率谱,但它也可以用于图像空间。代码如下:

def rotmean( mage ):
# This is terrifyingly slow
t0 = time.time()

N = int( np.floor( mage.shape[0]/2.0 ) )
M = int( np.floor( mage.shape[1]/2.0 ) )

rmax = np.ceil( np.sqrt( N**2 + M**2 ) ) + 1

rmean = np.zeros( [rmax] )
weights = np.zeros( [rmax] )

[xmesh, ymesh] = np.meshgrid( range(-N, N), range(-M, M) )
rmesh = np.sqrt( xmesh**2 + ymesh**2 )
rfloor = np.floor( rmesh )

remain = rmesh - rfloor
# Make rfloor into an index look-up table
rfloor = rfloor.astype(np.int)

t1 = time.time()
# It takes 300 ms just to get to here in the function.  
print "Init time = " + str(t1-t0)
print "Max rfloor = " + str( rfloor.max() )
print "rmean.shape = " + str( rmean.shape )


# Certainly mage*(1-remain) can be precalculated as well if we want to use more memory

for I in rfloor:
    # Sum pixels
    rmean[rfloor[I]] += mage[I]*(1-remain[I])
    rmean[rfloor[I]+1] += mage[I]*remain[I]

    # Calculate the total area of each pixel so we can compute the average from the sum
    weights[rfloor[I]] += (1-remain[I])
    weights[rfloor[I]+1] += remain[I]

t4 = time.time()
print "Total loop time = " + str(t4 - t1)

rmean /= weights # compute average from sum
raxis = range(0,rmean.size)
return [rmean, raxis]

很难克服这个函数与Matlab相比有多慢。在Matlab中,在我的笔记本电脑上执行大约需要450毫秒,而Python只需要300毫秒就可以到达for循环,而在我功能更强大的桌面上执行2kx2k图像则需要大约180秒。我意识到Matlab使用JIT来编译for循环,但是我尝试将代码编译成Cython来加速for循环,它实际上比解释的代码慢。我怀疑我不了解Python如何分配内存之类的东西,但是我找不到任何关于评测的注意事项。从有限的可用文档中可以看出,我在这里使用+=运算符进行在线(在位)操作?在

通过numpy进行矢量化似乎是一个显而易见的解决方案,但我不知道如何将操作矢量化。在

编辑:好的,我对代码进行了矢量化处理,现在它离我们很近了,在Python中大约是0.5秒(尽管桌面计算机有一个强大得多的CPU,Xeon与i5相比)。我尝试了很多方法来提高for循环的速度,但我能做的最好的就是超过30秒。在

^{pr2}$

Tags: 代码图像fortimenp半径像素矢量化