这是我第一次尝试在 numpy 中使用 strides,与在不同过滤器上的简单迭代相比,它确实提高了速度,但它仍然很慢(感觉至少有一两件事是完全冗余或低效的) .
所以我的问题是:是否有更好的方法来执行此操作或对我的代码进行调整以使其显着更快?
该算法对每个像素执行 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 秒,而莉娜毕竟是一个很小的图像。
编辑:
我得到了更改rot_filters.std(1)
为rot_filters.var(1)
以保存相当多的平方根的建议,并且它以 5 秒的顺序剃掉了一些东西。