2012-07-13 5 views
5

剛体変換を2D画像行列の大きなセットに適用したいとします。理想的には、平行移動と回転の両方を指定するアファイン変換行列を供給するだけで、これを一度に適用し、出力に対して3次スプライン補間を行うことができます。numpy/scipyでの高速2D剛体変換

残念ながらのscipy.ndimage.interpolationは翻訳していないようです。私はshiftrotateの組み合わせを使用することができることを知っていますが、これは面倒であり、出力を複数回補間することに関係します。私もこのような一般的な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

私はaffine_transformoffsetパラメータがあります---翻訳をやるんだと思います。

+0

ハ、あなたは非常に良い点を作る!私が投げたのは、私がランク3の行列を供給することを期待し、2つ以上の行を受け入れることを拒否したことでした。 'affine_transform'がNicholaの提案のように変換のための単一の行列を受け入れるならば、もっと簡単になると思います。 –

+0

アフィンは剛性ではありません –

3

scikit imageを使用できますか? この場合、ホモグラフィを適用することができます。ホモグラフィキャブを使用して、並行移動と回転の両方を同時に3x3マトリックスで表現しました。 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) 

私の古いCore 2 Duoでは、変換に約30msかかりました。ホモグラフィについて

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

+0

ニース、ほぼ正確に私が探していたもの。唯一の欠点は、 'fast_homography'は双線形補間をサポートするように見えますが、単純なホモグラフィはバイキュービックであり、私の目的には十分に速いということです。 –

関連する問題