これは、numpyでストライドを使用する最初の試みであり、さまざまなフィルターでの単純な反復と比較して速度が向上しましたが、それでもかなり遅いです(完全に冗長または非効率的なものが少なくとも1つまたは2つあるように感じます) 。
だから私の質問は:これを実行するより良い方法や、コードを大幅に高速化するための微調整はありますか?
アルゴリズムは、ピクセルごとに9つの異なるフィルターのローカル評価を実行し、標準偏差が最も小さいフィルターを選択します(画像分析で説明されているように、Nagau and 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)
するという提案があり、5秒のオーダーで何かを削りました。rot_filters.var(1)