使用嵌套for循环进行图像处理的性能问题

时间:2013-05-23 14:58:16

标签: python performance numpy

我有代码,显示为here,它使计算机生成的全息图得到初始图像。程序当前使用的图像可以在image directory

中找到

我的程序需要大约。运行一分钟,这是一个10x10像素A,只有14个嵌套for循环实际关心的点。减速是getComplexwave函数:

 def getComplexwave():
    '''Iterate through every source point, and calculate the complex wave
contribution at each sampling pixel on the film.'''
    for o in xrange(objPointShape):
        print o+1

        for i in xrange(ipxShape):
            for j in xrange(ipyShape):
                dx=objectpoints[o][0] - ipx[0][i]
                dy=objectpoints[o][1] - ipy[0][j]
                dz=objectpoints[o][2]

                distance=np.sqrt(dx**2+dy**2+dz**2)
                complexwave=np.exp(1j*k*distance)

                hologram[i][j]=hologram[i][j]+complexwave

有人可以帮助我对此进行矢量化,或者至少可以让它更快到达吗?我仍然是python的新手。

此外,任何其他建议使代码更好将非常感谢!输出应该看起来像this

对于那些想要它的人来说,{p> The profiling information。请注意,这只是前十个,它按内部时间排序。

2 个答案:

答案 0 :(得分:2)

绝对可以进行矢量化。我创建了一组虚拟数据:

objPointShape = 100
objectpoints = np.random.rand(objPointShape, 3)
ipxShape = 100
ipx = np.random.rand(1, ipxShape)
ipyShape = 100
ipy = np.random.rand(1, ipyShape)
k = 1
hologram = np.zeros((ipxShape,ipyShape))
hologram = hologram+0j

你的功能的矢量化版本。 Mine返回全息图,而不是将其存储在全局hologram

def vec_get_complex_wave():
    dx = objectpoints[:, 0, None] - ipx # shape (objPointShape, ipxShape)
    dy = objectpoints[:, 1, None] - ipy # shape (objPointShape, ipyShape)
    dz = objectpoints[:, 2, None] # shape (objPointShape, 1)
    distance = np.sqrt((dx*dx)[..., None] + (dy*dy)[:, None, :] +
                       (dz*dz)[..., None])
    complexwave = np.exp(1j*k*distance)
    return complexwave.sum(axis=0)

objPointShapeipxShapeipyShape的上述情况均等于100,性能显着提高了近x150:

%timeit -n1 -r1 getComplexwave()
1 loops, best of 1: 11.1 s per loop

%timeit vec_get_complex_wave()
10 loops, best of 3: 76.7 ms per loop

np.allclose(hologram, vec_get_complex_wave())
Out[4]: True

答案 1 :(得分:0)

我想知道每件事情是什么,否则我需要阅读并理解你的整个代码才能做出贡献。在这种情况下,什么是ipxShape,ipyShape,objPointShape ...

据我了解你的代码,矢量化最简单的事情之一是从所有像素到给定源的距离,坐标为(x0,y0)。有不止一种方法可以做到这一点,我并不认为我的效率特别高,但对我来说最直观的是在X中构建一个距离矩阵,在Y中建立距离矩阵并在正交中添加这些贡献,给出距离。

import numpy as np
# Assuming values for image width, image height and source coordinates
xwidth = 10    # width of image in x direction
ywidth = 10    # Width of image in y direction
x0,y0 = 5,5    # assuming your source is in coordinates (5,5)

# Calculating distance in X and in Y direction for every pixel at once
x = np.matrix(range(xwidth)) - x0   
y = np.matrix(range(ywidth)).T - y0 
distX = np.ones((ywidth,1)) * x      # matrix of X distances 
distY = y * np.ones(xwidth)       # matrix of Y distances
distance = np.sqrt(np.multiply(distX,distX) + np.multiply(distY,distY))

# Now you can do the exponential of all the elements at one
complexwave = np.exp(1j*k*distance)  # whatever k is... 

# And now the hologram is:
hologram = hologram + complexwave

问候!

相关问题