0

一連の未知のパラメーターを使用して、3d 空間内の正方形マーカーのセット間の違いを最小限に抑えようとしています。

これらの正方形マーカーのモデル セット (3 次元の位置と回転で表される) があり、最適化の最後に観察された正方形マーカーのセットと一致する必要があります。

未知のパラメーターのセットを最適化するためにレーベンバーグ・マルカートを使用して います。これらのパラメーターは、観測された 3D マーカーの位置と (多かれ少なかれ) 一致するまで、モデルの 3D マーカーの位置と回転を変更します。

観測された 3D マーカーは、コンピューター ビジョン マーカー検出アルゴリズムから取得されます。各フレームに表示されるマーカーの ID と、各マーカーのカメラからの変換 ( Coplanar pos を使用) を提供します。各「フレーム」は、マーカーの合計セットの中で少数のマーカーしか見ることができず、変換にも不正確さがあります。

私は最小化関数を構築する方法を考え、相対回転を比較して、LM 最適化の各反復における回転間の差を最小化しようと考えました。

基本的に:

        foreach (Marker m1 in markers)
        {
            foreach (Marker m2 in markers)
            {
                Vector3 eulerRotation = getRotation(m1, m2);
                ObservedMarker observed1 = getMatchingObserved(m1);
                ObservedMarker observed2 = getMatchingObserved(m2);
                Vector3 eulerRotationObserved = getRotation(observed1, observed2);

                double diffX = Math.Abs(eulerRotation.X - eulerRotationObserved.X);
                double diffY = Math.Abs(eulerRotation.Y - eulerRotationObserved.Y);
                double diffZ = Math.Abs(eulerRotation.Z - eulerRotationObserved.Z);
            }
        }

ここで、diffX、diffY、diffZ は最小化する値です。

私は角度を計算するために以下を使用しています:

Vector3 axis = Vector3.Cross(getNormal(m1), getNormal(m2));
axis.Normalize();
double angle = Math.Acos(Vector3.Dot(getNormal(m1), getNormal(m2)));
Vector3 modelRotation = calculateEulerAngle(axis, angle);

getNormal(Marker m) は、正方形のマーカーがある平面の法線を計算します。

私はここで何か間違ったことをしていると確信しています。これをすべて LM オプティマイザー (私はALGLibを使用しています) に投入しても何も起こらないようです。1 回の反復を経て、不明なパラメーター (最初はすべて 0) を変更せずに終了します。

最小化しようとしている関数に何か問題があると考えています。計算された角度 (3 行目) が NaN を返すことがあるようです (現在、このケースを diffX、diffY、diffZ を 0 として返すように設定しています)。上記のようにオイラー角を比較することは有効ですか?

どんな助けでも大歓迎です。

さらに詳しい情報:

  • プログラムは C# で書かれており、XNA も使用しています。
  • モデル マーカーは、3D 座標の 4 つのコーナーで表されます
  • すべてのモデル マーカーは同じ座標空間にあります。
  • 観測されたマーカーは、カメラ座標空間でのカメラ位置からの平行移動としての 4 つのコーナーです。
  • m1 マーカーと m2 マーカーが同じマーカー ID である場合、または m1 または m2 のいずれかが観測されない場合、すべての差分を 0 (違いなし) に設定します。
4

2 に答える 2

1

最初はタイプミスかと思いましたが、自分も過去に似たようなケースを経験していたので、バグかもしれないと気付きました。

diffY と diffZ を次のようにすべきではありません:

double diffY = Math.Abs(eulerRotation.Y - eulerRotationObserved.Y);
double diffZ = Math.Abs(eulerRotation.Z - eulerRotationObserved.Z);

これをコメントとして投稿するのに十分な評判がないため、回答として投稿します!

于 2012-05-23T19:06:25.037 に答える
0

これで運がいいですか?すべてのマーカーの組み合わせですべての差分の「合計」を最小限に抑えたいと仮定するのは正しいですか? LM を使用したい場合は使用しないでくださいMath.Abs

1 つの代替手段は、目的関数を手動で定式化し、別のオプティマイザーを使用することです。私は最近、導関数を計算する必要さえない 2 つの非線形オプティマイザを C# に移植しました。

  • COBYLA2は非線形制約をサポートしますが、より多くの反復が必要です。
  • BOBYQAは、可変境界制約に制限されていますが、かなり効率的な反復スキームを提供します。
于 2012-06-14T15:04:58.790 に答える