4

2D 画像の既知の 2 点間の 3D 距離を mm 単位で抽出しようとしています。シーン内のマーカーに対するカメラ座標を取得するために、正方形の AR マーカーを使用しています。ポイントは、これらのマーカーの角です。

以下に例を示します。

ここに画像の説明を入力

コードは C# で記述されており、XNA を使用しています。CoPlanar POSIT に AForge.net を使用しています。距離を計算するために実行する手順は次のとおりです。

1.画面の角をマークします。コーナーは 2D ベクトル形式で表され、画像の中心は (0,0) です。上が Y 方向の正、右が X 方向の正です。

2. AForge.net Co-Planar POSIT アルゴリズムを使用して、各マーカーのポーズを取得します。

    float focalLength = 640; //Needed for POSIT
    float halfCornerSize = 50; //Represents 1/2 an edge i.e. 50mm
    AVector[] modelPoints = new AVector3[]
    {
         new AVector3( -halfCornerSize, 0,  halfCornerSize ),
         new AVector3(  halfCornerSize, 0,  halfCornerSize ),
         new AVector3(  halfCornerSize, 0, -halfCornerSize ),
         new AVector3( -halfCornerSize, 0, -halfCornerSize ),
    };
    CoplanarPosit coPosit = new CoplanarPosit(modelPoints, focalLength);
    coPosit.EstimatePose(cornersToEstimate, out marker1Rot, out marker1Trans);

3. XNA 回転/平行移動マトリックスに変換します (AForge は OpenGL マトリックス形式を使用します)。

    float yaw, pitch, roll;
    marker1Rot.ExtractYawPitchRoll(out yaw, out pitch, out roll);

    Matrix xnaRot = Matrix.CreateFromYawPitchRoll(-yaw, -pitch, roll);
    Matrix xnaTranslation = Matrix.CreateTranslation(marker1Trans.X, marker1Trans.Y, -marker1Trans.Z);
    Matrix transform = xnaRot * xnaTranslation;

4.コーナーの 3D 座標を見つけます。

    //Model corner points
    cornerModel = new Vector3[]
    {
        new Vector3(halfCornerSize,0,-halfCornerSize),
        new Vector3(-halfCornerSize,0,-halfCornerSize),

        new Vector3(halfCornerSize,0,halfCornerSize),
        new Vector3(-halfCornerSize,0,halfCornerSize)
    };

    Matrix markerTransform =  Matrix.CreateTranslation(cornerModel[i].X, cornerModel[i].Y, cornerModel[i].Z);
    cornerPositions3d1[i] = (markerTransform * transform).Translation;

    //DEBUG: project corner onto screen - represented by brown dots
    Vector3 t3 = viewPort.Project(markerTransform.Translation, projectionMatrix, viewMatrix, transform);
    cornersProjected1[i].X = t3.X; cornersProjected1[i].Y = t3.Y;

5.マーカーの 2 つのコーナー間の 3D 距離を見てください。これは 100mm を表します。この 3D 距離を 100 mm に変換するために必要な倍率を求めます。(私は実際に平均倍率を取得します):

    for (int i = 0; i < 4; i++)
    {
        //Distance scale;
        distanceScale1 += (halfCornerSize * 2) / Vector3.Distance(cornerPositions3d1[i], cornerPositions3d1[(i + 1) % 4]);
    }
    distanceScale1 /= 4;

6.最後に、関連するコーナー間の 3D 距離を見つけ、倍率を掛けて距離を mm で取得します。

    for(int i = 0; i < 4; i++)
    {
       distance[i] = Vector3.Distance(cornerPositions3d1[i], cornerPositions3d2[i]) * scalingFactor;
    }

得られた距離は決して正確ではありません。距離を簡単に計算できるように、まな板を使用しました。上の画像は、コーナー 1 (赤から紫) の距離を 147mm (予想 150mm) と計算しました。下の画像は 188mm (予想 200mm) を示しています。

ここに画像の説明を入力

また、同じマーカーのエッジを共有するマーカー コーナー間の距離を測定する場合、得られる 3D 距離が決して同じではないという事実も懸念されます。私が気付いたもう 1 つの点は、茶色の点が色付きの点と完全に一致していないように見えることです。色付きの点は、CoPlanar 位置への入力として使用される座標です。茶色の点は、POSIT を介して計算されたマーカーの中心から計算された位置です。

ここで何が間違っているのか誰にも分かりますか? 私はそれを理解しようとして髪を引っ張っています。コードは非常に単純である必要があります。コードで明らかな間違いを犯したとは思いません。私は数学が苦手なので、基本的な数学のどこが間違っているのか指摘してください...

4

2 に答える 2

1

あなたの質問では、多くのブラックボックスを使用しています。二段目の焦点距離は?ステップ 3 で ypr を実行するのはなぜですか? どのように校正しますか?よくわからないライブラリは使わずに最初からやり直すことをお勧めします。

ステップ 1: カメラ モデルを作成します。エラーを理解し、予測を作成します。必要に応じて、レンズの歪みに 2D フィルターを適用します。これは難しいかもしれません。

ステップ 2: レンズの歪みを除去した後、2D でマーカーを見つけます。エラーを理解し、中心を取得していることを確認してください。多分複数のフレームにわたって。

ステップ 3: 3D への投影を解除します。1 と 2 の後、これは簡単なはずです。

ステップ 4: ???

ステップ 5: 利益を得る! (3Dで距離を測定し、エラーを知ってください)

于 2012-05-30T07:01:00.273 に答える
0

画像の違いから視差距離を取得できるように、3D写真(一連の距離からの2枚の写真)が必要だと思います

于 2013-05-07T15:57:50.560 に答える