2012-06-02 23 views
0

我有一組從0-5索引的方形標記。這些標記由其父項和一組旋轉(x,y,z)的偏移表示。父母是另一個標記(0-5)。例如,我可以將標記0作爲根標記,1是具有偏移量(x:10,y:0,z:5)和旋轉(x:0.5,y:0.1,z:0)的0的子元素, 2是1的孩子,3是0的孩子,依此類推。從任何找到的標記中投影出已知的真實現實標記位置

要從基本標記中找到標記的相對3D位置,只需鏈接由偏移和旋轉形成的變換矩陣。

該過程的第二步是從相機視圖中檢測這些標記。我使用了與ARToolkit相似的ALVAR標記跟蹤器。我正在使用一個封裝器,它將允許我訪問XNA矩陣格式中每個檢測到的標記的相機變換矩陣(這通過封裝從OpenGL格式進行了更正)。

我想測試檢測到的標記模型與我定義的模型匹配的準確程度。爲此,我選擇其中一個檢測到的標記作爲「基本」標記,並從中定義出標記模型。

使用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++; 
      } 
     } 
} 

現在對於每個標記的每個角,我們根據「基準」標記在屏幕上找到預期的二維投影位置。

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繪製在此屏幕,它是如預期。
  • 我使用與上面的代碼相同的變換將模型繪製到屏幕上。

這是發生了什麼,當我運行它:

綠色是投射到屏幕上的標記跟蹤檢測到的標記。 紅色是基於「基本」標記的模型中的標記角。

的模型是如下: enter image description here

實驗: 1. 0是基本標記,這一個工作,因爲從基底變換是相同

enter image description here

  • 1是基準標記。這是不正確的。
  • 與解決,這將是很大的任何幫助表示讚賞

    enter image description here

    回答

    0

    這是一個長鏡頭..但根據我在你的解釋中讀到的內容,你首先檢測到標記#1,然後檢測到標記#2,等等......我假設,如果沿途無法識別標記,那麼也會使前一個標記無效。在現實中,紙張 - >標記#1不能被正確識別,因爲下一個標記#2不在標記#1的右邊,所以兩者都是無效的。 正如我所說這是一個遠射,但..你怎麼試着順時針旋轉你的紙90deg?