Chcę zastosować transformacje ciała sztywnego do dużego zestawu macierzy obrazów 2D. Idealnie chciałbym móc dostarczyć matrycę transformacji afinicznej, określającą zarówno translację, jak i obrót, zastosować to za jednym zamachem, a następnie wykonać interpolację splajnu sześciennego na wyjściu.Szybkie transformacje ciała sztywnego 2D w numpy/scipy
Niestety wydaje się, że affine_transform
w scipy.ndimage.interpolation
nie wykonuje tłumaczenia. Wiem, że mógłbym użyć kombinacji shift
i rotate
, ale jest to trochę nieporządne i polega na wielokrotnym interpolowaniu wyniku.
Ja również próbowałem przy użyciu rodzajowego geometric_transformation
takiego:
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
To działa, ale to strasznie powolny, ponieważ jest zasadniczo zapętlenie nad współrzędnych pikselowych! Jaki jest dobry sposób na zrobienie tego?
Hah, robisz bardzo dobry punkt! To, co mnie rzuciło, to to, że spodziewałem się dostarczyć matrycę 3 i odmówił przyjęcia więcej niż dwóch rzędów. Myślę, że byłoby znacznie prostsze, gdyby "affine_transform" zaakceptowało pojedynczą matrycę do transformacji, jak w sugestii Nicholi. –
Affine nie jest sztywny –