任务是在3X3窗口中平均邻居值的图像像素。
图像是2.5 MB的标准图像。
为了避免边缘情况,我给它们一个值-1并将它们过滤掉。
运行程序时,它会在624秒后终止。为什么这么慢?
该程序看起来非常简约,但我确信我会错过一些东西。
import scipy
import numpy as np
import scipy.misc
import scipy.ndimage
import timeit
def average_neighbours(mat):
interesting = mat[mat>=0]
return np.average(interesting)
def run_program():
vienna = scipy.misc.imread('kaertnerstrasse.jpg')
vienna1 = scipy.ndimage.filters.generic_filter(vienna, function=average_neighbours, size=(3,3,1),mode="constant",cval=-1.0)
scipy.misc.imsave('kaertnerstrasse3-3.jpg', vienna1)
if __name__ == "__main__":
start = timeit.default_timer()
run_program()
stop = timeit.default_timer()
print stop - start
这是分析器数据。看起来我想做的标准操作需要花费很多时间。是否可以更快地完成它?
479086307 function calls (479086303 primitive calls) in 739.517 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.004 0.004 739.517 739.517 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 BmpImagePlugin.py:173(DibImageFile)
1 0.001 0.001 0.001 0.001 BmpImagePlugin.py:27(<module>)
1 0.000 0.000 0.000 0.000 BmpImagePlugin.py:55(_accept)
1 0.000 0.000 0.000 0.000 BmpImagePlugin.py:61(BmpImageFile)
1 0.006 0.006 0.006 0.006 GifImagePlugin.py:28(<module>)
1 0.000 0.000 0.000 0.000 GifImagePlugin.py:47(_accept)
1 0.000 0.000 0.000 0.000 GifImagePlugin.py:54(GifImageFile)
1 0.000 0.000 0.268 0.268 Image.py:1394(save)
1 0.000 0.000 0.014 0.014 Image.py:1750(new)
1 0.000 0.000 0.029 0.029 Image.py:1786(fromstring)
1 0.000 0.000 0.011 0.011 Image.py:1943(open)
5 0.000 0.000 0.000 0.000 Image.py:2082(register_open)
3 0.000 0.000 0.000 0.000 Image.py:2094(register_mime)
5 0.000 0.000 0.000 0.000 Image.py:2104(register_save)
10 0.000 0.000 0.000 0.000 Image.py:2114(register_extension)
1 0.000 0.000 0.000 0.000 Image.py:219(_conv_type_shape)
2 0.003 0.001 0.011 0.005 Image.py:290(preinit)
2 0.000 0.000 0.000 0.000 Image.py:371(_getdecoder)
2 0.000 0.000 0.000 0.000 Image.py:387(_getencoder)
3 0.000 0.000 0.000 0.000 Image.py:449(__init__)
1 0.000 0.000 0.000 0.000 Image.py:460(_new)
6/2 0.003 0.000 0.224 0.112 Image.py:503(__getattr__)
1 0.000 0.000 0.221 0.221 Image.py:522(tostring)
1 0.000 0.000 0.015 0.015 Image.py:577(fromstring)
4 0.000 0.000 0.000 0.000 Image.py:606(load)
5 0.000 0.000 0.000 0.000 Image.py:83(isStringType)
5 0.000 0.000 0.000 0.000 Image.py:92(isTupleType)
1 0.000 0.000 0.000 0.000 Image.py:98(isImageType)
1 0.000 0.000 0.183 0.183 ImageFile.py:124(load)
1 0.000 0.000 0.004 0.004 ImageFile.py:227(load_prepare)
1 0.000 0.000 0.000 0.000 ImageFile.py:236(load_end)
1 0.000 0.000 0.000 0.000 ImageFile.py:254(StubImageFile)
1 0.000 0.000 0.000 0.000 ImageFile.py:283(_ParserFile)
1 0.000 0.000 0.000 0.000 ImageFile.py:30(<module>)
1 0.000 0.000 0.000 0.000 ImageFile.py:330(Parser)
1 0.000 0.000 0.266 0.266 ImageFile.py:466(_save)
9 0.000 0.000 0.000 0.000 ImageFile.py:516(_safe_read)
1 0.000 0.000 0.000 0.000 ImageFile.py:69(ImageFile)
1 0.000 0.000 0.000 0.000 ImageFile.py:72(__init__)
1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:121(SOF)
2 0.000 0.000 0.000 0.000 JpegImagePlugin.py:168(DQT)
1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:261(_accept)
1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:267(JpegImageFile)
1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:272(_open)
1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:35(<module>)
24 0.000 0.000 0.000 0.000 JpegImagePlugin.py:41(i16)
1 0.000 0.000 0.266 0.266 JpegImagePlugin.py:420(_save)
5 0.000 0.000 0.000 0.000 JpegImagePlugin.py:50(Skip)
1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:54(APP)
1 0.000 0.000 0.000 0.000 PngImagePlugin.py:151(PngInfo)
1 0.000 0.000 0.000 0.000 PngImagePlugin.py:169(PngStream)
1 0.000 0.000 0.000 0.000 PngImagePlugin.py:308(PngImageFile)
1 0.001 0.001 0.001 0.001 PngImagePlugin.py:34(<module>)
1 0.000 0.000 0.000 0.000 PngImagePlugin.py:453(_idat)
1 0.000 0.000 0.000 0.000 PngImagePlugin.py:75(ChunkStream)
1 0.000 0.000 0.000 0.000 PpmImagePlugin.py:18(<module>)
1 0.000 0.000 0.000 0.000 PpmImagePlugin.py:46(PpmImageFile)
29942784 64.011 0.000 81.737 0.000 _methods.py:43(_count_reduce_items)
29942784 126.522 0.000 398.092 0.000 _methods.py:53(_mean)
1 0.000 0.000 0.000 0.000 _ni_support.py:38(_extend_mode_to_code)
2 0.000 0.000 0.000 0.000 _ni_support.py:55(_normalize_sequence)
1 0.000 0.000 0.000 0.000 _ni_support.py:70(_get_output)
29942784 151.188 0.000 701.104 0.000 ex1.py:12(average_neighbours)
1 0.007 0.007 739.513 739.513 ex1.py:18(run_program)
1 0.000 0.000 738.947 738.947 filters.py:1115(generic_filter)
29942784 67.220 0.000 549.916 0.000 function_base.py:436(average)
1 0.000 0.000 0.000 0.000 genericpath.py:85(_splitext)
1 0.000 0.000 0.000 0.000 ntpath.py:161(splitext)
1 0.000 0.000 0.000 0.000 numeric.py:141(ones)
29942789 19.069 0.000 50.684 0.000 numeric.py:394(asarray)
29942784 14.466 0.000 37.300 0.000 numeric.py:464(asanyarray)
1 0.000 0.000 0.000 0.000 numeric.py:773(flatnonzero)
1 0.000 0.000 0.247 0.247 pilutil.py:103(imread)
1 0.002 0.002 0.313 0.313 pilutil.py:130(imsave)
1 0.000 0.000 0.236 0.236 pilutil.py:174(fromimage)
1 0.000 0.000 0.042 0.042 pilutil.py:206(toimage)
1 0.000 0.000 0.000 0.000 pilutil.py:34(bytescale)
1 0.000 0.000 0.000 0.000 re.py:188(compile)
1 0.000 0.000 0.000 0.000 re.py:226(_compile)
5 0.000 0.000 0.000 0.000 sre_compile.py:178(_compile_charset)
5 0.000 0.000 0.000 0.000 sre_compile.py:207(_optimize_charset)
1 0.000 0.000 0.000 0.000 sre_compile.py:32(_compile)
1 0.000 0.000 0.000 0.000 sre_compile.py:359(_compile_info)
2 0.000 0.000 0.000 0.000 sre_compile.py:472(isstring)
1 0.000 0.000 0.000 0.000 sre_compile.py:478(_code)
1 0.000 0.000 0.000 0.000 sre_compile.py:493(compile)
4 0.000 0.000 0.000 0.000 sre_parse.py:138(append)
1 0.000 0.000 0.000 0.000 sre_parse.py:140(getwidth)
1 0.000 0.000 0.000 0.000 sre_parse.py:178(__init__)
7 0.000 0.000 0.000 0.000 sre_parse.py:182(__next)
1 0.000 0.000 0.000 0.000 sre_parse.py:195(match)
6 0.000 0.000 0.000 0.000 sre_parse.py:201(get)
4 0.000 0.000 0.000 0.000 sre_parse.py:257(_escape)
1 0.000 0.000 0.000 0.000 sre_parse.py:301(_parse_sub)
1 0.000 0.000 0.000 0.000 sre_parse.py:379(_parse)
1 0.000 0.000 0.000 0.000 sre_parse.py:67(__init__)
1 0.000 0.000 0.000 0.000 sre_parse.py:675(parse)
1 0.000 0.000 0.000 0.000 sre_parse.py:90(__init__)
11 0.000 0.000 0.000 0.000 string.py:220(lower)
24 0.000 0.000 0.000 0.000 string.py:229(upper)
1 0.000 0.000 0.012 0.012 string.py:308(join)
2 0.000 0.000 0.000 0.000 type_check.py:237(iscomplexobj)
1 0.014 0.014 0.014 0.014 {PIL._imaging.fill}
1 0.004 0.004 0.004 0.004 {PIL._imaging.new}
1 0.000 0.000 0.000 0.000 {_sre.compile}
4 0.000 0.000 0.000 0.000 {apply}
41 0.193 0.005 0.193 0.005 {built-in method decode}
1 0.266 0.266 0.266 0.266 {built-in method encode_to_file}
548 0.025 0.000 0.025 0.000 {built-in method encode}
3 0.000 0.000 0.000 0.000 {built-in method pixel_access}
2 0.000 0.000 0.000 0.000 {built-in method setimage}
26 0.000 0.000 0.000 0.000 {chr}
1 0.000 0.000 0.000 0.000 {divmod}
4 0.000 0.000 0.000 0.000 {getattr}
29942787 9.386 0.000 9.386 0.000 {hasattr}
89828369 34.448 0.000 34.448 0.000 {isinstance}
29942786 12.578 0.000 12.578 0.000 {issubclass}
40 0.000 0.000 0.000 0.000 {len}
3 0.000 0.000 0.000 0.000 {max}
591 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.001 0.001 0.001 0.001 {method 'close' of 'file' objects}
1 0.000 0.000 0.000 0.000 {method 'copy' of 'dict' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {method 'fileno' of 'file' objects}
2 0.000 0.000 0.000 0.000 {method 'flush' of 'file' objects}
11 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects}
13 0.000 0.000 0.000 0.000 {method 'has_key' of 'dict' objects}
1 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects}
1 0.012 0.012 0.012 0.012 {method 'join' of 'str' objects}
11 0.000 0.000 0.000 0.000 {method 'lower' of 'str' objects}
29942784 19.872 0.000 417.964 0.000 {method 'mean' of 'numpy.ndarray' objects}
1 0.000 0.000 0.000 0.000 {method 'nonzero' of 'numpy.ndarray' objects}
1 0.000 0.000 0.000 0.000 {method 'ravel' of 'numpy.ndarray' objects}
79 0.001 0.000 0.001 0.000 {method 'read' of 'file' objects}
29942784 114.221 0.000 114.221 0.000 {method 'reduce' of 'numpy.ufunc' objects}
3 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects}
2 0.000 0.000 0.000 0.000 {method 'seek' of 'file' objects}
2 0.000 0.000 0.000 0.000 {method 'sort' of 'list' objects}
1 0.013 0.013 0.013 0.013 {method 'tostring' of 'numpy.ndarray' objects}
24 0.000 0.000 0.000 0.000 {method 'upper' of 'str' objects}
2 0.000 0.000 0.000 0.000 {min}
59885574 54.461 0.000 54.685 0.000 {numpy.core.multiarray.array}
1 0.000 0.000 0.000 0.000 {numpy.core.multiarray.copyto}
1 0.000 0.000 0.000 0.000 {numpy.core.multiarray.empty}
1 0.000 0.000 0.000 0.000 {numpy.core.multiarray.zeros}
2 0.001 0.000 0.001 0.000 {open}
63 0.000 0.000 0.000 0.000 {ord}
29942785 13.675 0.000 13.675 0.000 {range}
1 37.843 37.843 738.947 738.947 {scipy.ndimage._nd_image.generic_filter}
1 0.000 0.000 0.000 0.000 {zip}
739.529455192
行function_base.py:436(average)是有趣的。看起来好像花了大部分时间。
答案 0 :(得分:3)
我会尝试用更通用,更合适的解决方案替换generic_filter方法。您基本上要做的是使用大小为3x3x1且值为1/9的内核进行卷积:
import numpy as np
import scipy
import scipy.misc
import scipy.ndimage
import scipy.signal
import timeit
def run_program():
my_image = scipy.misc.imread('my_image.png')
kernel = np.ones((3, 3, 1))
kernel /= kernel.size
my_image_smoothed = scipy.signal.fftconvolve(my_image, kernel, mode='valid')
scipy.misc.imsave('my_image_3x3.png', my_image_smoothed)
if(__name__ == '__main__'):
start = timeit.default_timer()
run_program()
print timeit.default_timer() - start
<强> [UPDATE] 强>
要尊重原始图像大小,您可以使用“相同”模式而不是“有效”模式进行fftconvolve。这将自动归零您的图像。然而,为了在图像垫的边界处获得更好的结果,图像具有由numpy的垫功能提升的模式之一
numpy.pad(array, pad_width, mode=<'constant'|'edge'|'reflect'|'symmetric'|...>)
并在交替填充的图像上使用fftconvolve模式'valid'。
padding = [(shape // 2, shape // 2) for shape in kernel.shape]
my_padded_image = np.pad(my_image, shape, mode='edge')
my_image_smoothed = scipy.signal.fftconvolve(my_padded_image, kernel, mode='valid')
<强> [/ UPDATE] 强>
我不确定它是否会运行得更快但它至少应该补偿方法调用开销。 在具有4876x2278像素的测试图像上,代码需要约40秒(硬盘驱动器是SSD)
祝你好运