剛体変換を2D画像行列の大きなセットに適用したいとします。理想的には、平行移動と回転の両方を指定するアファイン変換行列を供給するだけで、これを一度に適用し、出力に対して3次スプライン補間を行うことができます。numpy/scipyでの高速2D剛体変換
残念ながらのscipy.ndimage.interpolation
は翻訳していないようです。私はshift
とrotate
の組み合わせを使用することができることを知っていますが、これは面倒であり、出力を複数回補間することに関係します。私もこのような一般的なgeometric_transformation
を使用してみました
:
import numpy as np
from scipy.ndimage.interpolation import geometric_transformation
# make the affine matrix
def maketmat(xshift,yshift,rotation,dimin=(0,0)):
# centre on the origin
in2orig = np.identity(3)
in2orig[:2,2] = -dimin[0]/2.,-dimin[1]/2.
# rotate about the origin
theta = np.deg2rad(rotation)
rotmat = np.identity(3)
rotmat[:2,:2] = [np.cos(theta),np.sin(theta)],[-np.sin(theta),np.cos(theta)]
# translate to new position
orig2out = np.identity(3)
orig2out[:2,2] = xshift,yshift
# the final affine matrix is just the product
tmat = np.dot(orig2out,np.dot(rotmat,in2orig))
# function that maps output space to input space
def out2in(outcoords,affinemat):
outcoords = np.asarray(outcoords)
outcoords = np.concatenate((outcoords,(1.,)))
incoords = np.dot(affinemat,outcoords)
incoords = tuple(incoords[0:2])
return incoords
def rbtransform(source,xshift,yshift,rotation,outdims):
# source --> target
forward = maketmat(xshift,yshift,rotation,source.shape)
# target --> source
backward = np.linalg.inv(forward)
# now we can use geometric_transform to do the interpolation etc.
tformed = geometric_transform(source,out2in,output_shape=outdims,extra_arguments=(backward,))
return tformed
をこれは動作しますが、それは、本質的にピクセル座標をループだので、それは、恐ろしく遅いです!これを行うには良い方法は何ですか?
ハ、あなたは非常に良い点を作る!私が投げたのは、私がランク3の行列を供給することを期待し、2つ以上の行を受け入れることを拒否したことでした。 'affine_transform'がNicholaの提案のように変換のための単一の行列を受け入れるならば、もっと簡単になると思います。 –
アフィンは剛性ではありません –