1

私の目標は、既知の四角形 (たとえば、800 x 600 の画面) から斜め/回転した四角形に遠近座標を転送することです。そうするために、私はこれを見つけました。これは非常に役に立ちました:キャプチャされた座標を画面座標に変換する

問題の解決策は他にもあると思います。1四角形から三角形を作成し、まだ解決できなかった数学関数を適用します。OR 式 A=USVt から得られる H マトリックスを使用します。上記のリンクで説明されているように、正しい H マトリックスを取得すると、任意の座標を非常に簡単に転送できるため、これは良さそうです。だから私はそれのために行くと思った!

苦労した後、私はmatlabでそれを行うことができました(上記のリンクをテストしました)、それはうまくいきました:)しかし、今はobjective-Cで?!

(A=USVt) の A で始まる以下のコードを書きました。H マトリックスに到達するための次の最初のステップである Vt を計算するには、matlab [USV]=SVD(A); と同様の関数を使用する必要があります。関数。だから私はここで見つけました:これを行うためにMATLABの組み込みLAPACK / BLASルーチンを呼び出すと、accelerator.hフレームワークを含めることができ、C-LAPACKの同等のdgesvd_(...)を使用できます。

ところで、キャプチャされた座標を画面座標に変換するのと同じ座標を使用して、テストをより簡単にします。

解決済み 私が抱えていた問題は、多次元配列 A が計算され、1 次元配列に変換される方法でした。Lapacks の入力は常に 1 次元であるためです:)

配列 A の計算方法も含めました。WP = Webcam および SC = 800*600 画面。

    float   WP[4][3];
WP[0][0] = 98;
WP[0][1] = 86;
WP[0][2] = 1;
WP[1][0] = 119;
WP[1][1] = 416;
WP[1][2] = 1;
WP[2][0] = 583;
WP[2][1] = 80;
WP[2][2] = 1;
WP[3][0] = 569;
WP[3][1] = 409;
WP[3][2] = 1;


float   SC[4][3];
SC[0][0] = 0;
SC[0][1] = 0;
SC[0][2] = 1;
SC[1][0] = 799;
SC[1][1] = 0;
SC[1][2] = 1;
SC[2][0] = 0;
SC[2][1] = 599;
SC[2][2] = 1;
SC[3][0] = 799;
SC[3][1] = 599;
SC[3][2] = 1;

float A[9][8];
int i=0;
int j=0;
float X[3], x, y;
for (i=0; i<4; i++) {
    X[0] = WP[i][0];
    X[1] = WP[i][1];
    X[2] = WP[i][2];
    x = SC[i][0]; y = SC[i][1];

    A[0][j] = 0;    A[1][j] = 0;         A[2][j] = 0;         A[3][j] = -X[0];  A[4][j] = -X[1];
    A[5][j] = -1;   A[6][j] = y*X[0];    A[7][j] = y*X[1];    A[8][j] = y;
    j++;
    A[0][j] = X[0]; A[1][j] = X[1];      A[2][j] = 1;         A[3][j] = 0;      A[4][j] = 0;
    A[5][j] = 0;    A[6][j] = (-x)*X[0]; A[7][j] = (-x)*X[1]; A[8][j] = (-x);
    j++;
}

int m = 8;
int n = 9;
int p = (m < n ? m : n);

double B[m*n];

//Recalculate multidimentional A to one-dimentional array B for LAPACK
int k = 0;
for (i=0; i<n; i++) {
    for (j=0; j<m; j++) {
        B[k]=A[i][j];
        // NSLog(@"%f", A[i][j]);
        k++;
    }
}

double U[m*m];
double VT[n*n];
double S[p * 1];

int info=0;
double work[5*m];
int lwork = 5*m;
//do the actual computation
dgesvd_("N","A", &m, &n, B, &m, S, U, &m, VT, &n, work, &lwork, &info);

for (int i=0; i<(n*n); i++) {
    NSLog(@"%f", VT[i]);
}

// NEXT STEP IN MATLAB, have to still translate this to C-language
// H = transpose(reshape(V(:,end),[3 3]));
// H = H/H(3,3);

次に、matlab で Vt の最後の列を取得し、それを 3x3 行列に再形成します。これをHになるように転置します。

0.0001
0.0099
-0.8647
0.0054
-0.0003
-0.5021
-0.0000
-0.0000
 0.0045
Vt_reshaped = reshape(V(:,end),[3 3]);
H = transpose(Vt_reshaped)

解決しました!!

4

1 に答える 1

1

解決しました!私が抱えていた問題は、多次元配列 A を計算して 1 次元配列に変換する方法でした。Lapacks の入力は常に 1 次元であるためです:)

作業コードで質問を編集しました。

Objective-C で動作するコードを楽しんでください。ARCを使用した最初のMACのXcode 4.4プロジェクトで使用しました!

于 2012-08-10T09:57:36.453 に答える