Desidero applicare le trasformazioni del corpo rigido a un ampio insieme di matrici di immagini 2D. Idealmente, mi piacerebbe essere in grado di fornire solo una matrice di trasformazione affine che specifica sia la traduzione che la rotazione, applicarla in un colpo solo, quindi eseguire l'interpolazione con spline cubiche sull'output.Trasformazioni corpo rigido 2D rapide in numpy/scipy
Purtroppo sembra che affine_transform
in scipy.ndimage.interpolation
non faccia la traduzione. So che potrei usare una combinazione di shift
e rotate
, ma questo è un po 'disordinato e implica l'interpolazione dell'output più volte.
Ho anche provato ad utilizzare il generico geometric_transformation
in questo modo:
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
Questo funziona, ma è terribilmente lento, dal momento che è essenzialmente un ciclo su coordinate pixel! Qual è un buon modo per farlo?
Hah, sei un ottimo punto! Quello che mi ha gettato è che mi aspettavo di fornire una matrice di grado 3 e si è rifiutato di accettare più di due righe. Penso che sarebbe molto più semplice se 'affine_transform' accettasse una singola matrice per la trasformazione, come nel suggerimento di Nichola. –
Affine non è rigido –