这是我第一次在numpy中使用步幅,相对于简单迭代不同的过滤器,它确实提高了速度,但仍然相当缓慢(感觉至少有一两个完全冗余或低效的地方)。所以我的问题是:是否有更好的执行方式或调整我的代码可以使其显着更快?该算法对每个像素执行9个不同过滤器的局部评估,并选择具有最小标准偏差的过滤器(我试图按照图像分析书籍中描述的Nagau和Matsuyma(1980)“复杂区域照片的结构分析”进行实现)。结果是既平滑又锐化的图像(如果您问我,那相当酷!)
import numpy as np
from scipy import ndimage
from numpy.lib import stride_tricks
def get_rotating_kernels():
kernels = list()
protokernel = np.arange(9).reshape(3, 3)
for k in xrange(9):
ax1, ax2 = np.where(protokernel==k)
kernel = np.zeros((5,5), dtype=bool)
kernel[ax1: ax1+3, ax2: ax2+3] = 1
kernels.append(kernel)
return kernels
def get_rotation_smooth(im, **kwargs):
kernels = np.array([k.ravel() for k in get_rotating_kernels()],
dtype=bool)
def rotation_matrix(section):
multi_s = stride_tricks.as_strided(section, shape=(9,25),
strides=(0, section.itemsize))
rot_filters = multi_s[kernels].reshape(9,9)
return rot_filters[rot_filters.std(1).argmin(),:].mean()
return ndimage.filters.generic_filter(im, rotation_matrix, size=5, **kwargs)
from scipy import lena
im = lena()
im2 = get_rotation_smooth(im)
(仅供评论,由于几乎没有时间花在那里,get_rotating_kernel
实际上没有进行优化)
在我的网络本上,它花费了126秒,而Lena毕竟是一张相当小的图像。
编辑:
我得到了建议,将rot_filters.std(1)
更改为rot_filters.var(1)
可以节省很多平方根,并且它可以节省大约5秒钟的时间。
cProfile
)对其进行分析吗? - nneonneorotation_matrix
函数被调用了262144次,所以有时间可以节省。而且无论它指向哪个部分,我仍然不知道它如何帮助我...但也许只是因为我还没有学会喜欢cProfile
... - deinonychusaur