投稿したデータを使用して:
P = [px(:) py(:)];
Q = [qx(:) qy(:)];
変換を計算します。
H = Q/P;
変換を適用します。
Q2 = H*P;
結果を比較します。
err = Q2-Q
出力:
err =
7.1054e-15 7.1054e-15
-3.5527e-15 -3.5527e-15
-1.4211e-14 -2.1316e-14
1.4211e-14 1.4211e-14
これは、すべての意図と目的でゼロです..
編集:
コメントで指摘したように、上記の方法は 3x3 ホモグラフィ行列を計算しません。与えられた点と同じ数の方程式で連立方程式を単純に解きます。
H * A = B --> H = B*inv(A) --> H = B/A (mrdivide)
それ以外の場合、MATLAB のイメージ処理ツールボックスには CP2TFORM 関数があります。表示されている画像に適用された例を次に示します。
%# read illustration image
img = imread('http://i.stack.imgur.com/ZvaZK.png');
img = imcomplement(im2bw(img));
%# split into two equal-sized images
imgs{1} = img(:,fix(1:end/2));
imgs{2} = img(:,fix(end/2:end-1));
%# extract the four corner points A and B from both images
C = cell(1,2);
for i=1:2
%# some processing
I = imfill(imgs{i}, 'holes');
I = bwareaopen(imclearborder(I),200);
I = imfilter(im2double(I), fspecial('gaussian'));
%# find 4 corners
C{i} = corner(I, 4);
%# sort corners in a consistent way (counter-clockwise)
idx = convhull(C{i}(:,1), C{i}(:,2));
C{i} = C{i}(idx(1:end-1),:);
end
%# show the two images with the detected corners
figure
for i=1:2
subplot(1,2,i), imshow(imgs{i})
line(C{i}(:,1), C{i}(:,2), 'Color','r', 'Marker','*', 'LineStyle','none')
text(C{i}(:,1), C{i}(:,2), num2str((1:4)'), 'Color','r', ...
'FontSize',18, 'Horiz','left', 'Vert','bottom')
end
コーナーが検出されたので、空間変換を取得できます。
%# two sets of points
[A,B] = deal(C{:});
%# infer projective transformation using CP2TFORM
T = cp2tform(A, B, 'projective');
%# 3x3 Homography matrix
H = T.tdata.T;
Hinv = T.tdata.Tinv;
%# align points in A into B
X = tformfwd(T, A(:,1), A(:,2));
%# show result of transformation
line(X([1:end 1],1), X([1:end 1],2), 'Color','g', 'LineWidth',2)
結果:
>> H = T.tdata.T
H =
0.74311 -0.055998 0.0062438
0.44989 -1.0567 -0.0035331
-293.31 62.704 -1.1742
>> Hinv = T.tdata.Tinv
Hinv =
-1.924 -0.42859 -0.0089411
-2.0585 -1.2615 -0.0071501
370.68 39.695 1
計算を自分で確認できます。
%# points must be in Homogenous coordinates (x,y,w)
>> Z = [A ones(size(A,1),1)] * H;
>> Z = bsxfun(@rdivide, Z, Z(:,end)) %# divide by w
Z =
152 57 1
219 191 1
62 240 1
92 109 1
これは B の点にマッピングされます。
%# maximum error
>> max(max( abs(Z(:,1:2)-B) ))
ans =
8.5265e-14