モバイルカメラプラットフォームから撮影した画像を修正する必要があるアプリケーションに取り組んでいます。プラットフォームはロール、ピッチ、ヨーの角度を測定します。この情報から何らかの変換を行うことで、画像が真上から撮影されたように見せたいと考えています。
言い換えれば、カメラの向きを変えて遠くから撮影した、地面に平らに置かれた完全な正方形を変換して、後で正方形が完全に対称になるようにしたいのです。
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);
結果は次のとおりです。
X 軸または Y 軸を中心に同じ量だけ画像を回転させようとすると、次のような結果が得られます。
R = R_z(10)*R_y(0)*R_x(10);
ただし、10 度回転させて、ある巨大な数で割ると、問題なく見え始めます。しかし、繰り返しになりますが、これはまったく研究価値のない結果です。
R = R_z(10)*R_y(0)*R_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)
私が理解していることから、ヨー角は変換に直接関係していません。しかし、私はこれについて間違っているかもしれません。
追加情報:
セットアップが使用される環境には、参照として確実に使用できる線 (海の写真) が含まれていないことを指定したいと思います (通常、水平線は写真に写りません)。また、最初の画像の正方形は、変換が正しいかどうかを確認するための手段として使用されるだけであり、実際のシナリオにはありません。