我有以下代码基本上采用图像并将其放在像素上,换句话说,获取图像的每个像素并创建一个10x10“像素”,其中包含它们之间的空白,如下所示:
这变得非常缓慢,我想知道这是不正常还是我做了多余的操作?
import numpy as np
from scipy.misc import lena
import matplotlib.pyplot as plt
def rect(x, y):
res = (np.abs(x) < .5)*(np.abs(y) < .5)
return res
def placeOnSLM(FF, image):
step = .1
x, y = np.mgrid[0:image.shape[0]+step:step, 0:image.shape[1]+step:step]
outImage = np.zeros(x.shape)+np.min(image)
for ix in range(image.shape[0]):
print ix,'of',image.shape[0]
for iy in range(image.shape[1]):
outImage[(np.abs(x-ix-.5)/FF < .5) * (np.abs(y-iy-.5)/FF < .5)] = image[ix, iy]
# outImage += image[ix, iy]*rect((x-ix-.5)/FF, (y-iy-.5)/FF)
return outImage
if __name__ == '__main__':
num = 10
image = placeOnSLM(.9, lena()[:num,:num])
plt.imshow(lena()[:num,:num],'gray', interpolation='none')
plt.colorbar()
plt.figure()
plt.imshow(image,'gray',interpolation='none')
plt.colorbar()
plt.show()
编辑:
我使用的操作系统是Ubuntu 13.10
答案 0 :(得分:2)
没有使用for循环的解决方案怎么样?不确定,因为我没有太多使用matplotlib,但我认为它与matlab类似,所以我将用matlab编写,希望将它转换为matplotlib是微不足道的。
解决方案很简单:使用matlabs imresize函数调整图像大小,但设置插值为&#34;最接近&#34;而不是双线性/双三次。如果使图像大10倍,它基本上会产生10x10个色块,其值等于原始图像的一个像素。下面的代码执行它然后添加边距。 (for循环只是测试n的各种值。)
ns= [10:10:100, 500, 1000];
times= zeros(size(ns));
for i= 1:length(ns)
n= ns(i);
s= 10; % 10x10 pixels in the result = 1x1 of the original image
margin= 2;
% create the image
im= rand(n,n);
tic
% resize the image
im2= imresize(im, (s+margin)*size(im), 'nearest');
% add margins
[x,y]= meshgrid([0:n]*(s+margin), [1:margin]);
inds= x(:)+y(:);
im2(inds,:)=0; im2(:, inds)=0;
times(i)= toc;
% imagesc(im2); pause; % visualize
end
plot(ns, times);
在我的测试中,当n = 1000时,图像在0.96秒内创建(尽管我有一个四核i5 @ 3.3 GHz。操作系统:Ubuntu 11.10。
答案 1 :(得分:1)
您的重要处理步骤如下:
for ix in range(image.shape[0]):
print ix,'of',image.shape[0]
for iy in range(image.shape[1]):
outImage[(np.abs(x-ix-.5)/FF < .5) * (np.abs(y-iy-.5)/FF < .5)] = image[ix, iy]
您的运行时为O(n^2)
,正如您在评论中正确提到的那样。 n = 10
的1s运行时应缩放到100s。但是,您没有考虑存储图像造成的内存损失。每次通过内部for
循环时,都会在图像中添加一块像素。对于较小的n
值,这不是一个很大的问题,但对于较大的n
值,这会增加很多空间(确切地与n*n
成比例!) 。你没有提到你的操作系统,但是在这些较大的n
值下检查Python的内存使用情况可能是值得的。您可能会看到一个阈值,操作开始使批次更长(即不能很好地扩展到代码的运行时)。
编辑:好奇心得到了我的好处,我想看看它在我的机器上是如何工作的。我做了一个快速(尽管有大n
,不那么快)的运行时分析。
红色=实际,蓝色=使用理想的n ^ 2运行时
运行时间与n ,对数比例
运行时间与n
正如你可以清楚地看到的那样,某事发生在n = 60左右。我的内存使用量在那里达到了约80-90%,并且在其余的运行中保持在90%的范围内。我最好的猜测是由于图像本身在内存中,因为在这些运行期间CPU使用率也非常高。
编辑2 :
结果是这条线创造了大瓶颈
outImage[(np.abs(x-ix-.5)/FF < .5) * (np.abs(y-iy-.5)/FF < .5)] = image[ix, iy]
使用以下代码替换它会显着加快速度:
ixD = int(np.ceil((-FF/2 + ix + .5)*10))
ixU = int(np.ceil((FF/2 + ix + .5)*10))
iyD = int(np.ceil((-FF/2 + iy + .5)*10))
iyU = int(np.ceil((FF/2 + iy + .5)*10))
outImage[ixD:ixU, iyD:iyU] = image[ix, iy]