计算将矩形转换为2D中的另一个四边形的矩阵 [英] Computing a matrix which transfroms a quadrangle to another quadrangle in 2D

查看:738
本文介绍了计算将矩形转换为2D中的另一个四边形的矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下图中,目标是计算将点a1a2a3a4转换为其对应物b1b2b3b4的单应性矩阵H.
即:

  [b1 b2 b3 b4] = H * [a1 a2 a3 a4] 

你建议什么方法是计算H(3x3)的最佳方法。 a1 ... b4是在均匀坐标系(即[a1_x a1_y 1]',...)中表示的2D中的点。
EDIT
对于这些类型的问题,我们使用SVD,所以我想看看这可以简单地在Matlab中完成。



EDIT



这是我最初尝试使用svd = Q / P)。请考虑给定示例的以下代码

  px = [0 1 1 0]; %a square 
py = [1 1 0 0];

qx = [18 18 80 80]; %a随机四边形
qy = [ - 20 20 60 -60];
if(DEBUG)
fill(px,py,'r');
fill(qx,qy,'r');
end

Q = [qx; qy; ones(size(qx))];
P = [px; py; ones(size(px))];
H = Q / P;
H * PQ
答案:
-0.0000 0 0 0 0
-20.0000 20.0000 -20.0000 20.0000 0.0000
-0.0000 0 0 0 -0.0000

我期望答案是空矩阵,但它不是!这就是为什么我在StackOverflow问这个问题。
现在,我们都知道这是一个射影变换不是显而易见的欧氏。但是,很好知道在一般护理中是否只使用4个点来计算这样的矩阵是可能的。



解决方案

使用您张贴的资料:

  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) MATLAB在图像处理工具箱中有一个CP2TFORM函数,这个函数可以使用一个函数。这里是应用于所示图像的示例:

 %#读插图图像
img = imread //i.stack.imgur.com/ZvaZK.png');
img = imcomplement(im2bw(img));

%#拆分为两个相等大小的映像
imgs {1} = img(:,fix(1:end / 2));
imgs {2} = img(:,fix(end / 2:end-1));

%#从两个图像中提取四个角点A和B
C = cell(1,2);
for i = 1:2
%#一些处理
I = imfill(imgs {i},'holes');
I = bwareaopen(imclearborder(I),200);
I = imfilter(im2double(I),fspecial('gaussian'));

%#找到4个角落
C {i} = corner(I,4);

%#以一致的方式(逆时针)排序角度
idx = convhull(C {i}(:, 1),C {i}(:, 2)
C {i} = C {i}(idx(1:end-1),:);
end

%#显示带有检测到的角的两个图像
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' ',...
'FontSize',18,'Horiz','left','Vert','bottom')
end

检测到角落,现在我们可以获得空间变换:

 %#两个点
[A,B] = deal(C {:});

%#使用CP2TFORM投影变换
T = cp2tform(A,B,'projective');

%#3x3同质矩阵
H = T.tdata.T;
Hinv = T.tdata.Tinv;

%#将A中的点对齐到B
X = tformfwd(T,A(:,1),A(:,2));

%#显示转换结果
line(X([1:end 1],1),X([1:end 1],2),'color' ','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



我们可以自己确认计算:

 %#点必须在同源坐标(x,y,w)
>> Z = [A 1(大小(A,1),1)] * H;
>> Z = bsxfun(@rdivide,Z,Z(:,end))%#除以w
Z =
152 57 1
219 191 1
62 240 1
92 109 1

映射到B中的点:

 %#最大错误
>> max(max(abs(Z(:,1:2)-B)))
ans =
8.5265e-14


In the figure below the goal is to compute the homography matrix H which transforms the points a1 a2 a3 a4 to their counterparts b1 b2 b3 b4. That is:

[b1 b2 b3 b4] = H * [a1 a2 a3 a4]

What way would you suggest to be the best way to calculate H(3x3). a1...b4 are points in 2D which are represented in homogeneous coordinate systems ( that is [a1_x a1_y 1]', ...). EDIT: For these types of problems we use SVD, So i would like to see how this can be simply done in Matlab.

EDIT:

Here is how I initially tried to solve it using svd (H=Q/P) in Maltlab. Cosider the following code for the given example

px=[0 1 1 0];  % a square
py=[1 1 0 0];

qx=[18 18 80 80];    % a random quadrangle
qy=[-20 20 60 -60];
if (DEBUG)
  fill(px,py,'r');
  fill(qx,qy,'r');
end

Q=[qx;qy;ones(size(qx))];
P=[px;py;ones(size(px))];
H=Q/P;
H*P-Q
answer:
   -0.0000         0         0         0         0
  -20.0000   20.0000  -20.0000   20.0000    0.0000
   -0.0000         0         0         0   -0.0000

I am expecting the answer to be a null matrix but it is not!... and that's why I asked this question in StackOverflow. Now, we all know it is a projective transformation not obviously Euclidean. However, it is good to know if in general care calculating such matrix using only 4 points is possible.

解决方案

Using the data you posted:

P = [px(:) py(:)];
Q = [qx(:) qy(:)];

Compute the transformation:

H = Q/P;

apply the transformation:

Q2 = H*P;

Compare the results:

err = Q2-Q

output:

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

which is zeros for all intents and purposes..


EDIT:

So as you pointed out in the comments, the above method will not compute the 3x3 homography matrix. It simply solves the system of equations with as many equations as points provided:

H * A = B   -->   H = B*inv(A)   -->   H = B/A (mrdivide)

Otherwise, MATLAB has the CP2TFORM function in the image processing toolbox. Here is an example applied to the image shown:

%# 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

With the corners detected, now we can obtain the spatial transformation:

%# 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)

The result:

>> 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

We can confirm the calculation ourselves:

%# 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

which maps to the points in B:

%# maximum error
>> max(max( abs(Z(:,1:2)-B) ))
ans =
   8.5265e-14

这篇关于计算将矩形转换为2D中的另一个四边形的矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆