我有一組從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繪製在此屏幕,它是如預期。
- 我使用與上面的代碼相同的變換將模型繪製到屏幕上。
這是發生了什麼,當我運行它:
綠色是投射到屏幕上的標記跟蹤檢測到的標記。 紅色是基於「基本」標記的模型中的標記角。
的模型是如下:
實驗: 1. 0是基本標記,這一個工作,因爲從基底變換是相同
- 1是基準標記。這是不正確的。
與解決,這將是很大的任何幫助表示讚賞