ホモグラフィ変換のやり方

40 ビュー (過去 30 日間)
大貴 木戸
大貴 木戸 2022 年 2 月 8 日
コメント済み: 大貴 木戸 2022 年 2 月 10 日
マトラボでのホモグラフィ変換のやり方を教えてほしいです.現在,斜め方向から撮影した画像を,ホモグラフィ変換を用いて真上から見たような俯瞰画像に変換したいと思っています.
変換前の斜めから見た画像の4点(左上,右上,右下,左下)のpixel値の座標と,変換後の目指している俯瞰画像の4点のpixel値の座標はわかっていて,ホモグラフィ行列も求めています.このホモグラフィ行列を斜めから見た画像に適用する方法が分かりません.どなたか分かる方教えていただけないでしょうか.
ちなみに,変換前の座標はそれぞれ左下,左上,右上,右下の順で(910.774,965.829),(639,229,865.667),(949.414,462.938),(1091.16,637.62)で,変換後の座標が(527.402,833.139),(509.453,290.694),(1247,334.963),(1260.57,772.22)です.
また,ホモグラフィ行列は[0.0207 -0.7512 892.1442
0.4271 0.3142 -399.4835
-0.000462 -0.00023555 1]
となっています.よろしくお願いします.
追記:解決いたしました.回答ありがとうございました.本当に助かりました.

採用された回答

Hernia Baby
Hernia Baby 2022 年 2 月 10 日
おそらく行列が間違っています
適当な画像でやってみます
I = imresize(rgb2gray(imread('chacha_sq.jpeg')),[250 250]);
% imshow(I)
I_ref = imref2d(size(I));
% 適当に作った行列
T = [0.0207 -0.7512 0.0008921442;
0.4271 0.3142 -0.0003994835;
-0.000462 -0.00023555 1];
% 今回の行列
T2 = [0.0207 -0.7512 892.1442;
0.4271 0.3142 -399.4835;
-0.000462 -0.00023555 1];
tform = projective2d(T);
[cb_translated,~] = imwarp(I,tform);
tform2 = projective2d(T2);
[cb_translated2,~] = imwarp(I,tform2);
tiledlayout(2,2);
nexttile
imshow(I);
nexttile
imshow(cb_translated);
nexttile
imshow(cb_translated2);
ここから件の行列で変換するとどうなっているか見てみます
cb_translated2
cb_translated2 = uint8 0
size(cb_translated2)
ans = 1×2
1 1
上記のように黒色一枚のものになっているということは、誤りの可能性が高いです。
最後の列が大きすぎる気もします。確認してみてください。
-------------
四隅の投影の場合、こんなのもあります。
ご参考にどうぞ。
  2 件のコメント
Hernia Baby
Hernia Baby 2022 年 2 月 10 日
イメージしやすいように画像を適当に切り取りました。
座標はどうやって見つけたかというと、getptsを使いました。
255×255の画像になるようにしています。
clc,clear,close all;
I = imread("sample1.png");
imshow(I)
x = ([74 214 201 266])';
y = ([242 82 270 153])';
movingpoints = [x y];
Fixedpoints = [0 0; 0 255; 255 0; 255 255];
tform = fitgeotrans(movingpoints, Fixedpoints, 'Projective');
RA = imref2d([size(I,1) size(I,2)], [1 size(I,2)], [1 size(I,1)]);
[out,r] = imwarp(I, tform, 'OutputView', RA);
out = imcrop(out,[1 1 254 254]);
imshow(out);
axis off;
大貴 木戸
大貴 木戸 2022 年 2 月 10 日
回答ありがとうございます.
おかげさまで,無事に解決いたしました.わかりやすい説明本当にありがとうございました.

サインインしてコメントする。

その他の回答 (1 件)

Shunichi Kusano
Shunichi Kusano 2022 年 2 月 9 日
image processing toolboxをお持ちでしたらimwarp関数を使えば簡単に済みます。
自作する場合、まず作成された変換行列を使って、XY座標を変換。変換した座標でinterp2で内挿、という手順です。
なんとなくのコードを書いておきます。検証してないので抜け漏れあるかもしれません。適宜出てくる変数を見つつ、確認しながらお使いください。
sz = size(img,1:2); % 変換したい画像の縦横のピクセル数を取得
[x_org,y_org] = meshgrid(1:sz(2),1:sz(1)); % 画像の各ピクセルに対するX座標、Y座標
new_coords = [x_org(:) y_org(:) ones(numel(x_org),1)] * H; % 変換行列Hでx_orgとy_orgを変換(MATLABは右からかけることに注意してください)
x_new_row = new_coords(:,1);
y_new_row = new_coords(:,2);
% 500x500で新しい座標を定義(等間隔にするためmeshgridを使う)
[x_new,y_new] = meshgrid(linspace(min(x_new_row),max(x_new_row),500),linspace(min(y_new_row),max(y_new_row),500));
img_new = interp2(x_new_row,y_new_row,img(:),x_new,y_new); % 内挿して等間隔な座標での値を計算(3チャンネルの場合はチャンネルごとに)
  3 件のコメント
Shunichi Kusano
Shunichi Kusano 2022 年 2 月 10 日
imwarpで、OutputViewプロパティを指定する必要があるかと思います。変換した画像の大きさや範囲を指定するためです。documentにもありますとおり、imref2dというオブジェクトを定義して、指定します。OutputViewを使ったimwarpについては、下記のサンプルが参考になるかもしれません。
大貴 木戸
大貴 木戸 2022 年 2 月 10 日
回答ありがとうございます.サンプルを参考にプログラムを作ってみました.
cb = imread('hoseigray.jpg');
imshow(cb)
cb_ref = imref2d(size(cb))
T = [0.0207 -0.7512 892.1442;
0.4271 0.3142 -399.4835;
-0.000462 -0.00023555 1]
tform = projective2d(T);
[cb_translated,cb_translated_ref] = imwarp(cb,tform);
cb_translated_ref = cb_ref;
cb_translated_ref.XWorldLimits(2) = cb_translated_ref.XWorldLimits(2)+20;
cb_translated_ref.YWorldLimits(2) = cb_translated_ref.YWorldLimits(2)+20;
[cb_translated,cb_translated_ref] = imwarp(cb,tform,'OutputView',cb_translated_ref);
figure, subplot(1,2,1);
imshow(cb,cb_ref);
subplot(1,2,2);
imshow(cb_translated,cb_translated_ref)
実行すると,
このように,黒い画像が出力されてしまいました.
これはもうホモグラフィ行列が間違っているのでしょうか.
何度もすみません.よろしくお願いします.

サインインしてコメントする。

カテゴリ

Help Center および File Exchange幾何学的変換とイメージ レジストレーション についてさらに検索

製品


リリース

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!