2013-05-19 14 views
10

対応する画像の動きに基づいて新しいカメラの位置を計算しようとしています。 ピンホールカメラモデルに準拠しています。対応する画像からのカメラの動き

実際、私は有益な結果を得ていないので、私は手順を説明し、誰かが私を助けることを願っています。

対応する画像の特徴をSIFTで一致させ、OpenCVのFlannBasedMatcherと一致させ、OpenCVのfindFundamentalMat(メソッドRANSAC)で基本行列を計算します。

は、その後、私はカメラ内部行列(K)で基本行列を計算します。

Mat E = K.t() * F * K; 

私は特異値分解と回転と平行移動に不可欠なマトリックス分解:その後、私は試す

SVD decomp = SVD(E); 
Matx33d W(0,-1,0, 
      1,0,0, 
      0,0,1); 
Matx33d Wt(0,1,0, 
      -1,0,0, 
      0,0,1); 
R1 = decomp.u * Mat(W) * decomp.vt; 
R2 = decomp.u * Mat(Wt) * decomp.vt; 
t1 = decomp.u.col(2); //u3 
t2 = -decomp.u.col(2); //u3 

を三角測量によって正しい解を見つける。 (この部分はhttp://www.morethantechnical.com/2012/01/04/simple-triangulation-with-opencv-from-harley-zisserman-w-code/ですので、正しいと思います)。 new_pos & old_posは、ベクトル(3×)である

new_pos = old_pos + -R.t()*t; 

は、R回転行列(3×3)とは平行移動ベクトル(3×)をT:

新しい位置

を次いで計算されます。

残念ながら私は有用な結果を得ていないので、誰かが間違っている可能性があります。ここで

は、いくつかの結果(念のため、誰かがそれらのいずれかは間違いなく間違っていることを確認することができます)、次のとおりです。

x' * F * x = 0 

場合は、あなたのポイントの対応をチェックする必要があり、すべての

F = [8.093827077399547e-07, 1.102681999632987e-06, -0.0007939604310854831; 
    1.29246107737264e-06, 1.492629957878578e-06, -0.001211264339006535; 
    -0.001052930954975217, -0.001278667878010564, 1] 

K = [150, 0, 300; 
    0, 150, 400; 
    0, 0, 1] 

E = [0.01821111092414898, 0.02481034499174221, -0.01651092283654529; 
    0.02908037424088439, 0.03358417405226801, -0.03397110489649674; 
    -0.04396975675562629, -0.05262169424538553, 0.04904210357279387] 

t = [0.2970648246214448; 0.7352053067682792; 0.6092828956013705] 

R = [0.2048034356172475, 0.4709818957303019, -0.858039396912323; 
    -0.8690270040802598, -0.3158728880490416, -0.3808101689488421; 
    -0.4503860776474556, 0.8236506374002566, 0.3446041331317597] 
+1

計算にもう1つ間違いがあります。 'SVD decomp = SVD(E);'はOKですが、新しい 'newE = U * diag(1,1,0)* Vt'を計算しなければならず、' SVD decomp2 = SVD(newE) ; '。興味深いのは – who9vy

+0

です。私はそれについては決して読んでいない。だからdecomp2でRとtを計算するのですか? btw:詳細なお返事ありがとうございます。私はすべてのことをチェックしなければならず、できるだけ早く反応します。 – 3x14159265

+0

はい、decomp2でRとtを計算する必要があります。詳細な説明はここ(pp 257-260)http://www.robots.ox.ac.uk/~vgg/hzbook/hzbook2/HZepipolar.pdf – who9vy

答えて

10

まずx'およびx。これはもちろん、RANSACを用いた基本行列推定のインライアにとっての唯一のケースであるはずである。

はその後、あなたがK'は、第2の画像の固有のカメラ行列であり、x'は、第2の画像の点でこの

xn = inv(K) * x 
xn' = inv(K') * x' 

ような正規化画像座標(NCC)にあなたの点対応を変換しなければなりません。あなたの場合はK = K'だと思います。

これらのNCCでは、説明したように必須マトリックスを分解できます。正規化されたカメラ座標を三角測量し、三角測量ポイントの深さを確認します。しかし、文章の中では、正確な回転と平行移動を得るには1点で十分だと言います。私の経験から、あるポイントはRANSACの後でさえも外れ値になる可能性があるので、いくつかの点をチェックする必要があります。

必須行列を分解する前に、必ずE=U*diag(1,1,0)*Vtを確認してください。この条件は、投影行列の4つの可能な選択肢に対して正しい結果を得るために必要です。

正しい回転と平行移動が得られたら、すべての点の対応(RANSACによる基本行列推定のインライア)を三角形分割できます。次に、reprojection errorを計算する必要があります。まず、あなたはXが計算(均質)の3D位置である。この

xp = K * P * X 
xp' = K' * P' * X 

のような再投影位置を計算します。 PおよびP'は、3x4投影行列です。投影行列Pは、通常、同一性によって与えられる。 P' = [R, t]は、最初の3つの列と行の回転行列と4番目の列の平行移動によって与えられるので、Pは3x4行列です。これは、3D位置をhomogeneous coordinates、つまり3x1の代わりに4x1ベクトルに変換した場合にのみ機能します。次にxpxp'は、対応する点の(再投影された)2次元位置を表す同次座標です。

私は

new_pos = old_pos + -R.t()*t; 

は、まず、あなただけold_posを翻訳し、あなたがそれを回転させず、第二に、あなたは間違ったベクトルでそれを翻訳するので間違っていると思います。上記の正しい方法が与えられています。

再投影されたポイントを計算した後、再投影の誤差を計算することができます。同次座標で作業しているので、それらを正規化する必要があります(xp = xp/xp(2)、最後の座標で除算)。これは、誤差が大きい場合には、このような2^10のように、あなたの本質的なカメラキャリブレーションしたり、回転/翻訳が(おそらく両方)間違ってい

error = (x(0)-xp(0))^2 + (x(1)-xp(1))^2 

で与えられます。座標系によっては、投影行列を逆転させることができます。そのため、3x4行列を反転することはできません(擬似逆行列なしで)ので、それらを同次座標に変換する必要があります。したがって、第4の行[0 0 0 1]を加算し、逆行列を計算し、第4の行を除去する。

再送エラーがもう1つあります。一般に、再投影誤差は、(各画像内の)元の点の対応と再投影された位置との間の二乗された距離です。両方の点の間のユークリッド距離を求めるために平方根をとることができます。

+0

は 'x '* F * x = 0'の式です実際にはまったく正確に0ですか? 1,12345 * e^-14のような値はまだまだ良いですか? NCC計算の前にすべてのアウトライアーを捨てることができますか? – 3x14159265

+0

私はあなたが記述したものを試し、投影行列で終わった。再投影誤差は<10^2です。しかし、私が得られないことは、ワールド座標系でカメラの位置を移動する方法です。カメラがどの方向(x、y、z)に移動したかを計算したい。私はこれが 'new_pos = old_pos + -R.t()* t;'によって行われたと考えました。あなたはそれが間違っていると言っていたので、投影行列を使ってどうすればいいのか分かりますか? – 3x14159265

+2

1台のカメラは '(0、0、0)'にあり、もう1台は 't'にあります。さらに、第2のカメラは「R」だけ回転される。 「R」と「t」からなる行列「P」(射影行列と呼ばれる)は、恒等行列で表される座標系から各3D点「p」を「P」で表される座標系に変換する剛体変換である。変換は 'newp = P * p'によって行われ、ここで' P'は3x4または4x4行列であり、 'p'は均質3D点、すなわち4ベクトルです。一般に、 'p'の最後の要素は1に等しい。 – who9vy

0

カメラの位置を更新するには、まず変換を更新してから回転行列を更新する必要があります。 t_refとR_REFは、お使いのカメラの状態、Rとtです

t_ref += lambda * (R_ref * t); 
R_ref = R * R_ref; 

は、計算されたカメラの回転と平行移動新しく、ラムダはスケールファクタです。

関連する問題