1

基本的なMatrixを使用し、OpenCVを使用するだけで、キャリブレーションなしで画像修正を試みています。これまでに行ったこと:

  1. SURF および FLANN Descriptor Matcher を使用して 2 つの画像間の一致を見つける

    List good_match = getGoodMatch(img1,img2); --> 完了、結果は良好です

  2. img1 と img2 のマッチング ポイントを取得する

  3. 8 マッチ ポイント (Calib3D.FM_8PPoint) を使用して基本行列を取得する Mat F = getFundamentalMatrix(matchesKeyPoint1,matchesKeyPoint2,good_match)
  4. StereorectufyUncalibrated OpenCV を使用してホモグラフィ 3x3 行列を取得する

StereoRectifyUncalibrated からホモグラフィ マトリックス H1 と H2 を取得したので、そのホモグラフィ マトリックスを使用して実際の画像を修正するにはどうすればよいですか?? Fundamental Matrix と Homography Matrix に価値があることを知る方法はありますか?? これまでのところ、SURF Image Matching はうまく機能しています。結果を改善するための提案はありますか??

ありがとう...

4

1 に答える 1

4

画像を修正する

2D点の対応X<->X'のセットが与えられると、ホモグラフィ行列の変換はX' = H Xで与えられるHです。ここでXとX'は同次ベクトルであり、これは3DベクトルX'とHを意味します。 Xは等しい必要はありませんが、ゼロ以外のスケール係数で大きさが異なる場合があります。

つまり、基本的に私たちがやりたいのは、画像内のすべてのピクセルにホモグラフィ行列を掛けることです。また、 「空の」ピクセルのない滑らかな画像が得られるように、変換されたピクセル間に何らかの補間を適用したいと思います。幸い、このような関数はOpenCVに存在します:cvWarpPerspective

この関数(OpenCV 2.0の場合)には、次の4つのパラメーターが必要です。

  • const CvArr * src-ソース画像、つまり修正したい画像。
  • CvArr * dst-宛先画像、つまり修正後の結果。この画像は、ソース画像と同じタイプの画像である必要があります。また、サイズは、修正された画像に合うようにする必要があります(次の段落を参照)。
  • const CvMat * mapMatrix-3X3ホモグラフィ行列。
  • intフラグ-補間メソッド(たとえばCV_INTER_LINEAR)とフラグCV_WARP_FILL_OUTLIERSおよびCV_WARP_INVERSE_MAPの組み合わせ。

cornersデスティネーション画像のサイズを決定するには、ソース画像のホモグラフィマトリックスの変換を適用し、変換されたポイントを使用してサイズを決定します。左上隅の変換は次のようになります。

CvMat* point = cvCreateMat(3, 1, CV_64FC1);
CvMat* pointTransform = cvCreateMat(3, 1, CV_64FC1);

cvmSet(point, 0, 0, 0); // The x coordinate of the top left corner is 0.
cvmSet(point, 1, 0, 0); // The y coordinate of the top left corner is 0.
cvmSet(point, 2, 0, 1.0);

// Perform the homography transformation
cvMatMul(homography, point, pointTransform);

// Get the transformed corner's x and y coordinates.
double x = cvmGet(pointTransform, 0, 0) / cvmGet(pointTransform, 2, 0); // Divide by the scale factor s.
double y = cvmGet(pointTransform, 1, 0) / cvmGet(pointTransform, 2, 0); // Divide by the scale factor s.

// Release memory
cvReleaseMat(&point);
cvReleaseMat(&pointTransform);

次に注意する必要があるのは、たとえば、ピクセル(0、0)がピクセル(-5、-10)に変換される可能性があることです。ホモグラフィマトリックスを適用してから画像を表示しようとすると、正しく表示されません。これを回避するために行う必要があるのは、修正された画像の新しいコーナーの位置に基づいて、3x3の変換行列を計算することです。コーナーは、修正された画像を上下左右にシフトする必要があるピクセル数の情報を提供します。

次に、この変換行列を見つかったホモグラフィ行列と組み合わせて使用​​して、次のように最終的な変換行列を計算できます。

// transformMat:
// [ 1 0 x ]
// [ 0 1 y ]
// [ 0 0 1 ]
// homography: Your homography matrix H1 or H2
// finalMatrix: the resulting matrix you will use in cvWarpPerspective.
// Compute the final transformation matrix based on homography matrix H1
// which can be used to rectify your first image.
cvMatMul(transformMat, H1, finalMatrix);

これで、cvWarpPerspectiveを使用して画像を変換できます。

cvWarpPerspective(image, rectifiedImage, finalMatrix, 
CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS);

最初の画像にホモグラフィ行列H1を使用し、2番目の画像にホモグラフィ行列H2を使用していることに注意してください。

基本行列とホモグラフィ行列は良い値を持っていますか?

さらに、質問に答えて、基本行列Fとホモグラフィ行列H1およびH2が適切な値を持っているかどうかを確認します。基本行列Fは、対応する点の任意のペアX <->X'の条件を満たす必要があります。

X'F X =0。

同様に、行列H1の場合、次の条件を満たす必要があります。

X'cross H1 X = 0、ここで'cross'は外積です

結果を改善する

結果をさらに改善するには、次のことができます。

  • 別の記述子を使用して、2つの画像間の一致を見つけます。たとえば、SIFTDAISYを参照してください。
  • RANSACまたはLMSアルゴリズムを使用して、2つの画像間の8点を超える対応を検索し、外れ値をフィルター処理します(cvFindFundamentalMatrixのオプションCV_FM_RANSACおよびCV_FM_LMEDSを参照)。
于 2012-04-15T14:18:35.273 に答える