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

조회 수: 37 (최근 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 CenterFile Exchange에서 Read, Write, and Modify Image에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!