0

0 ~ 5 のインデックスが付けられた一連の正方形マーカーがあります。これらのマーカーは、親からのオフセットと一連の回転 (x、y、z) によって表されます。親は別のマーカー (0-5) です。たとえば、マーカー 0 をルート マーカーとして、1 を 0 の子としてオフセット (x:10,y:0,z:5) と回転 (x:0.5,y:0.1,z:0) で指定できます。 2 は 1 の子、3 は 0 の子などです。

ベース マーカーからマーカーの相対的な 3D 位置を見つけるには、オフセットと回転から形成された変換行列をチェーンするだけです。

プロセスの 2 番目のステップは、カメラ ビューからこれらのマーカーを検出することです。ARToolkit に似た ALVAR マーカー トラッカーを使用してこれを行いました。XNAマトリックス形式で検出された各マーカーのカメラ変換マトリックスにアクセスできるラッパーを使用しています(これは、ラッパーを介してOpenGL形式から修正されます)。

検出されたマーカー モデルが、定義したモデルとどの程度一致するかをテストしたいと考えています。これを行うには、検出されたマーカーの 1 つを「ベース」マーカーとして選択し、これから定義されたマーカー モデルを再投影します。

XNA を使用したコードは次のとおりです。

最初に、0 (ルート) マーカーからの「ベース」マーカーの相対的な変換を見つけます。

Matrix globalTransformToPerform=Matrix.Identity;

//Find the markerIDTOBAse on
int mibo = 0;
foreach (Bone b in model.bones)
{
   foreach (Marker m in b.markers)
   {
       if (mibo != markerIDToBaseOn)
       {
           mibo++;
           continue;
        }
        else
        {
           //Chain Marker transform
           Matrix markerTransform =
                             Matrix.CreateRotationZ(m.z) *
                             Matrix.CreateRotationX(m.x) *
                             Matrix.CreateRotationY(m.y) *
                             Matrix.CreateTranslation(m.offset);

            //Add bone transform
            markerTransform *= Matrix.CreateRotationZ(MathHelper.ToRadians(b.z)) *
                             Matrix.CreateRotationX(MathHelper.ToRadians(b.x)) *
                             Matrix.CreateRotationY(MathHelper.ToRadians(b.y)) *
                             Matrix.CreateTranslation(b.Offset);

            //Chain parents transforms
            Bone parent = b.parent;
            while (parent != null)
            {
                 Matrix parentLocalTransform = Matrix.CreateRotationZ(MathHelper.ToRadians(parent.z)) *
                                               Matrix.CreateRotationX(MathHelper.ToRadians(parent.x)) *
                                               Matrix.CreateRotationY(MathHelper.ToRadians(parent.y)) *
                                               Matrix.CreateTranslation(parent.Offset);

                 markerTransform *= parentLocalTransform;

                 parent = parent.parent;
            }
                 globalTransformToPerform = markerTransform;
                 mibo++;
          }
       }
 }

ここで、各マーカーの各コーナーについて、「ベース」マーカーに基づいて、画面上で予想される 2D 投影位置を見つけます。

 foreach (Bone b in model.bones)
 {
    foreach (Marker m in b.markers)
    {
        //foreach of the corners...
        for (int i = 0; i < 4; i++)
        {

            Matrix cornerTransform = Matrix.CreateTranslation(Global.cornerModel[i]);

            //Chain Marker transform
             Matrix markerTransform = cornerTransform *
                                      Matrix.CreateRotationZ(m.z) *
                                      Matrix.CreateRotationX(m.x) *
                                      Matrix.CreateRotationY(m.y) *
                                      Matrix.CreateTranslation(m.offset);

            //Add bone transform
            markerTransform *= Matrix.CreateRotationZ(MathHelper.ToRadians(b.z)) *
                               Matrix.CreateRotationX(MathHelper.ToRadians(b.x)) *
                               Matrix.CreateRotationY(MathHelper.ToRadians(b.y)) *
                               Matrix.CreateTranslation(b.Offset);

            //Chain parents transforms
            Bone parent = b.parent;
            while (parent != null)
            {
                  Matrix parentLocalTransform = Matrix.CreateRotationZ(MathHelper.ToRadians(parent.z))*        Matrix.CreateRotationX(MathHelper.ToRadians(parent.x))     *
                                                Matrix.CreateRotationY(MathHelper.ToRadians(parent.y)) *
                                                Matrix.CreateTranslation(parent.Offset);

                   markerTransform *= parentLocalTransform;

                   parent = parent.parent;
             }

             //Find 3D position
             Vector3 location = (markerTransform).Translation;

             //Now project
             Vector3 v = viewPort.Project(location * scalingFactor, projectionMatrix, Matrix.CreateLookAt(new Vector3(0, 0, 3), Vector3.Zero, Vector3.Up), worldTransform*globalTransformToPerform);
              Vector2 res = new Vector2(v.X, v.Y);

              //Store result
              cornersToRet.Add(res);
         }

      }
  }

問題は、マーカーが期待どおりに表示されないことです。私が試したこと:

  • ラッパーは正しく動作します。これはテスト済みです
  • モデルは正しいです。XNA を使用してこれを画面に描画しましたが、期待どおりです。
  • 上記のコードと同じ変換を使用して、モデルを画面に描画しました。

これを実行すると、次のようになります。

緑は、スクリーンに投影されたマーカー トラッカーによって検出されたマーカーです。赤は、「ベース」マーカーに基づくモデルのマーカー コーナーです。

モデルは以下です。 ここに画像の説明を入力

実験: 1. 0 はベース マーカーです。これは、ベースからの変換が同じであるため機能します。

ここに画像の説明を入力

  1. 1 はベース マーカーです。これは正しくありません。

これを解決するための助けがあれば大歓迎です

ここに画像の説明を入力

4

1 に答える 1

0

これはロングショットです..しかし、私があなたの説明で読んだことによると、最初にマーカー#1を検出し、次にマーカー#2などを検出します...途中でマーカーを識別できなかった場合、前のマーカーも。実際には、紙 -> 次のマーカー #2 がマーカー #1 の右側にないため、マーカー #1 を正しく識別できず、両方が無効になります。私が言ったように、これはロングショットですが.. 紙を時計回りに 90 度回転させてみてはどうでしょうか?

于 2012-06-04T04:59:43.587 に答える