2012-07-13 7 views
5

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?

Odpowiedz

3

myślę affine_transformrobi zrobić tłumaczenie --- istnieje parametr offset.

+0

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

+0

Affine nie jest sztywny –

3

Czy można korzystać z scikit image? W takim przypadku możesz spróbować zastosować homografię. Kabina do homografii służyła jednocześnie do tłumaczenia i rotacji za pomocą macierzy 3x3. Możesz użyć funkcji 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) 

Transformacja zajęła około 30 ms na moim starym Core 2 Duo.

O homography: http://en.wikipedia.org/wiki/Homography

+0

Ładnie, prawie dokładnie to, czego szukałem. Jedynym minusem jest to, że 'fast_homography' tylko wydaje się wspierać interpolację bilinear, ale zwykła' homography' ma charakter bikubiczny i jest wystarczająco szybka dla moich celów. –

Powiązane problemy