18

モバイルカメラプラットフォームから撮影した画像を修正する必要があるアプリケーションに取り組んでいます。プラットフォームはロール、ピッチ、ヨーの角度を測定します。この情報から何らかの変換を行うことで、画像が真上から撮影されたように見せたいと考えています。

言い換えれば、カメラの向きを変えて遠くから撮影した、地面に平らに置かれた完全な正方形を変換して、後で正方形が完全に対称になるようにしたいのです。

OpenCV(C++) と Matlab を使用してこれを実行しようとしましたが、これがどのように行われるかについて基本的なことが欠けているようです。

Matlab では、次のことを試しました。

%% Transform perspective
img = imread('my_favourite_image.jpg');
R = R_z(yaw_angle)*R_y(pitch_angle)*R_x(roll_angle);
tform = projective2d(R);   
outputImage = imwarp(img,tform);
figure(1), imshow(outputImage);

ここで、R_z/y/x は標準の回転行列 (度で実装) です。

一部のヨー回転では、すべて正常に機能します。

R = R_z(10)*R_y(0)*R_x(0);

結果は次のとおりです。

Z 画像軸を中心に 10 度回転した画像

X 軸または Y 軸を中心に同じ量だけ画像を回転させようとすると、次のような結果が得られます。

R = R_z(10)*R_y(0)*R_x(10);

X 画像軸を中心に 10 度回転した画像

ただし、10 度回転させて、ある巨大な数で割ると、問題なく見え始めます。しかし、繰り返しになりますが、これはまったく研究価値のない結果です。

R = R_z(10)*R_y(0)*R_x(10/1000);

X 画像軸を中心に 10/1000 度回転した画像

X 軸または Y 軸を中心に回転すると、変換がワイルドになる理由を誰かが理解するのを手伝ってくれませんか? 乱数やその他の手品で割らずにこれを解決する方法はありますか? これは、ある種のオイラー パラメータを使用して解決できる可能性がありますか? どんな助けでも大歓迎です!

更新: 完全なセットアップと測定

完全を期すために、完全なテスト コードと初期イメージ、およびプラットフォームのオイラー角が追加されています。

コード:

%% Transform perspective
function [] = main()
    img = imread('some_image.jpg');
    R = R_z(0)*R_y(0)*R_x(10);
    tform = projective2d(R);   
    outputImage = imwarp(img,tform);
    figure(1), imshow(outputImage);
end

%% Matrix for Yaw-rotation about the Z-axis
function [R] = R_z(psi)
    R = [cosd(psi) -sind(psi) 0;
         sind(psi)  cosd(psi) 0;
         0          0         1];
end

%% Matrix for Pitch-rotation about the Y-axis
function [R] = R_y(theta)
    R = [cosd(theta)    0   sind(theta);
         0              1   0          ;
         -sind(theta)   0   cosd(theta)     ];
end

%% Matrix for Roll-rotation about the X-axis
function [R] = R_x(phi)
    R = [1  0           0;
         0  cosd(phi)   -sind(phi);
         0  sind(phi)   cosd(phi)];
end

初期画像:

ここに画像の説明を入力

BODY 座標フレームでのカメラ プラットフォームの測定値:

Roll:     -10
Pitch:    -30
Yaw:      166 (angular deviation from north)

私が理解していることから、ヨー角は変換に直接関係していません。しかし、私はこれについて間違っているかもしれません。

追加情報:

セットアップが使用される環境には、参照として確実に使用できる線 (海の写真) が含まれていないことを指定したいと思います (通常、水平線は写真に写りません)。また、最初の画像の正方形は、変換が正しいかどうかを確認するための手段として使用されるだけであり、実際のシナリオにはありません。

4

4 に答える 4

8

それで、これが私がやったことです:実際に3D画像を扱っていない限り、写真の遠近法を修正することは2D操作であると考えました。これを念頭に置いて、変換行列の z 軸の値を 0 と 1 に置き換え、2D アフィン変換を画像に適用しました。

測定されたロール = -10 およびピッチ = -30 での初期画像 (最初の投稿を参照) の回転は、次の方法で行われました。

R_rotation = R_y(-60)*R_x(10); 
R_2d       = [   R_rot(1,1)  R_rot(1,2) 0; 
                 R_rot(2,1)  R_rot(2,2) 0;
                 0           0          1    ] 

これは、カメラがシーンの上に配置され、真下を向く仮想カメラ方向へのカメラ プラットフォームの回転を意味します。上記のマトリックスでロールとピッチに使用されている値に注意してください。

さらに、プラットフォームの見出しに合わせて画像を回転させると、z 軸を中心とした回転が追加され、次のようになります。

R_rotation = R_y(-60)*R_x(10)*R_z(some_heading); 
R_2d       = [   R_rot(1,1)  R_rot(1,2) 0; 
                 R_rot(2,1)  R_rot(2,2) 0;
                 0           0          1    ] 

これは実際の画像を変更しないことに注意してください - 回転するだけです。

その結果、Y 軸と X 軸を中心に回転した最初の画像は次のようになります。

ここに画像の説明を入力

上記のように、この変換を行うための完全なコードは次のとおりです。

% Load image
img = imread('initial_image.jpg'); 

% Full rotation matrix. Z-axis included, but not used.
R_rot = R_y(-60)*R_x(10)*R_z(0); 

% Strip the values related to the Z-axis from R_rot
R_2d  = [   R_rot(1,1)  R_rot(1,2) 0; 
            R_rot(2,1)  R_rot(2,2) 0;
            0           0          1    ]; 

% Generate transformation matrix, and warp (matlab syntax)
tform = affine2d(R_2d);
outputImage = imwarp(img,tform);

% Display image
figure(1), imshow(outputImage);



%*** Rotation Matrix Functions ***%

%% Matrix for Yaw-rotation about the Z-axis
function [R] = R_z(psi)
    R = [cosd(psi) -sind(psi) 0;
         sind(psi)  cosd(psi) 0;
         0          0         1];
end

%% Matrix for Pitch-rotation about the Y-axis
function [R] = R_y(theta)
    R = [cosd(theta)    0   sind(theta);
         0              1   0          ;
         -sind(theta)   0   cosd(theta)     ];
end

%% Matrix for Roll-rotation about the X-axis
function [R] = R_x(phi)
    R = [1  0           0;
         0  cosd(phi)   -sind(phi);
         0  sind(phi)   cosd(phi)];
end

サポートしていただきありがとうございます。これが誰かの役に立てば幸いです。

于 2013-12-09T11:39:10.233 に答える
2

ホモグラフィを推定する必要があります。市販の Matlab ソリューションについては、http://www.robots.ox.ac.uk/~vgg/hzbook/code/ の関数vgg_H_from_x_lin.mを参照してください

理論については、 http://szeliski.org/Book/またはhttp://programmingcomputervision.com/downloads/ProgrammingComputerVision_CCdraft.pdfの第 3 章で無料で入手できるコンピューター ビジョンの教科書を参照してください。

于 2013-12-09T11:46:15.777 に答える
2

カメラのパラメーターを誤解しているため、私の答えが正しくない可能性がありますが、ヨー/ピッチ/ロールがオブジェクトの位置に関連しているかどうか疑問に思っていました。一般的な回転の式を使用しました。コードは以下のとおりです (回転関数R_xR_y、およびR_zはあなたのものからコピーされたもので、ここには貼り付けませんでした)

close all
file='http://i.stack.imgur.com/m5e01.jpg'; % original image
I=imread(file);

R_rot = R_x(-10)*R_y(-30)*R_z(166);
R_rot = inv(R_rot);

R_2d  = [   R_rot(1,1)  R_rot(1,2) 0; 
            R_rot(2,1)  R_rot(2,2) 0;
            0           0          1    ]; 


T = maketform('affine',R_2d);

transformedI = imtransform(I,T);
        figure, imshow(I), figure, imshow(transformedI)

結果:

ここに画像の説明を入力

これは、頭の中で「正しい」配置を取得するために回転操作が必要であることを示しています (ただし、カメラの頭の中の正しい位置はおそらく必要ありません)。に変更R_rot = inv(R_rot);するR_rot = inv(R_rot)*R_x(-5)*R_y(25)*R_z(180);と、次のようになりました。

ここに画像の説明を入力

あなたが望むもののように見えます。ありがとう。

于 2013-12-09T16:06:56.210 に答える