4

回転-並進行列 [RT] (3x4) があります。

[RT] で説明されている回転変換を実行する関数が opencv にありますか?

4

1 に答える 1

9

この質問に対する多くの解決策は、隠れた仮定をしていると思います。この問題について私がどのように考えているかを簡単にまとめてみます (これまで何度も考えなければなりませんでした)。2 つの画像間のワーピングは、ホモグラフィと呼ばれる 3x3 マトリックスによって達成される 2 次元プロセスです。あなたが持っているのは、3次元で変換を定義する3x4マトリックスです。画像を 3 次元空間の平面として扱うことで、2 つの間で変換できます。トリックは、イメージ プレーンのワールド空間での初期位置を決定することです。次に、その位置を変換し、カメラの組み込み行列を使用して新しいイメージ プレーンに投影できます。

最初のステップは、最初の画像がワールド空間のどこにあるかを決定することです。これは、最初の R および T 行列が指定するものと同じである必要はないことに注意してください。それらはワールド座標にあります。これは、そのワールドによって作成されたイメージについて話しているもので、イメージ内のすべてのオブジェクトが平面に平らにされています。ここでの最も簡単な決定は、イメージを z 軸上の固定変位で回転なしに設定することです。この時点から、回転はないと仮定します。一般的なケースを見たい場合は、それを提供できますが、少し複雑です。

次に、3D 空間で 2 つの画像間の変換を定義します。同じ原点に対して両方の変換があるため、[A] から [B] への変換は、[A] から原点への変換と同じであり、その後に原点から [B] への変換が続きます。あなたはそれを得ることができます

transform = [B]*inverse([A])

概念的には、最初の画像を取得し、そのピクセルを 3D 空間の画像の幾何学的解釈に投影し、上記の変換によってそれらのピクセルを 3D 空間に変換し、新しい 2D 画像に投影し直す必要があります。あなたのカメラマトリックス。これらの手順は、単一の 3x3 マトリックスに結合する必要があります。

cv::Matx33f convert_3x4_to_3x3(cv::Matx34f pose, cv::Matx33f camera_mat, float zpos)
{   
//converted condenses the 3x4 matrix which transforms a point in world space 
//to a 3x3 matrix which transforms a point in world space.  Instead of 
//multiplying pose by a 4x1 3d homogeneous vector, by specifying that the
//incoming 3d vectors will ALWAYS have a z coordinate of zpos, one can instead 
//multiply converted by a homogeneous 2d vector and get the same output for x and y.

cv::Matx33f converted(pose(0,0),pose(0,1),pose(0,2)*zpos+pose(0,3),
                      pose(1,0),pose(1,1),pose(1,2)*zpos+pose(1,3),
                      pose(2,0),pose(2,1),pose(2,2)*zpos+pose(2,3));

//This matrix will take a homogeneous 2d coordinate and "projects" it onto a 
//flat plane at zpos.  The x and y components of the incoming homogeneous 2d 
//coordinate will be correct, the z component is dropped.  
cv::Matx33f projected(1,0,0,
                      0,1,0,
                      0,0,zpos);
projected = projected*camera_mat.inv();

//now we have the pieces.  A matrix which can take an incoming 2d point, and 
//convert it into a pseudo 3d point (x and y correspond to 3d, z is unused) 
//and a matrix which can take our pseudo 3d point and transform it correctly.  
//Now we just need to turn our transformed pseudo 3d point back into a 2d point 
//in our new image, to do that simply multiply by the camera matrix.

return camera_mat*converted*projected;
}

これはおそらくあなたが探していたよりも複雑な答えですが、あなたが何を求めているのかを理解してくれることを願っています. これは非常に紛らわしい可能性があり、私はその一部を簡単に説明しましたが、お気軽に説明を求めてください. 最初の画像が回転せずに表示されるという前提なしでソリューションが機能する必要がある場合は、私に知らせてください。必要以上に複雑にしたくありませんでした。

于 2012-10-28T03:23:09.853 に答える