2012-07-13 18 views
5

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?

risposta

3

Penso affine_transformfa fanno traduzione --- c'è il parametro offset.

+0

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. –

+0

Affine non è rigido –

3

È possibile utilizzare lo scikit image? Se questo è il caso, potresti provare ad applicare un'omografia. Una cabina di omografia utilizzata per rappresentare contemporaneamente sia la traslazione che la rotazione attraverso una matrice 3x3. Puoi usare la funzione skimage.transform.fast_homography.

import numpy as np 
import scipy 
import skimage.transform 
im = scipy.misc.lena() 
H = np.asarray([[1, 0, 10], [0, 1, 20], [0, 0, 1]]) 
skimage.transform.fast_homography(im, H) 

La trasformazione ha richiesto circa 30 ms sul mio vecchio Core 2 Duo.

Circa omografia: http://en.wikipedia.org/wiki/Homography

+0

Bello, quasi esattamente quello che stavo cercando. L'unico lato negativo è che "fast_homography" sembra supportare solo l'interpolazione bilineare, ma la semplice "omografia" è bicubica ed è abbastanza veloce per i miei scopi. –