Matlab 将单应性应用于一组点(不是图像)

Matlab applying homography to an set of points (not an image)

我想做的是将给定的单应性应用于一组点 (x,y)(而不是将其应用于图像的通常用例。)

我将单应性存储为 3x3 维矩阵:

H =
    1.06  -0.56  77.55
   -0.02   0.74  28.34
    0.02  -0.01   1.00

我有一套要点。例如:

pts = [x1,y1 ; x2,y2 ; x3,y3 ;x4,y4 ; ...];

如何将 H 应用到 pts

我知道将它应用于图像非常简单,例如:

img = imread('pathtofile\file.png');
tform = projective2d(H); 
img2 = imwarp(img, tform);  

但是点列表是否有等同于 imwrap 的东西?

使用 projective2d class 中的 transformPointsForward 函数。但是,请注意,您指定的单应性假定您将单应性与输入点预乘。这是显而易见的,因为最后一列看起来像翻译向量。也就是说,给定矩阵 H 和点矩阵 P,其中每个 是增广形式的一个点,其中第三行的值为1、可以通过以下方式实现点的翘曲:

out = H * P;

您最终将获得扭曲点 - 每列一个点。注意坐标是齐次的形式,所以你必须取第三个坐标,将每列中对应的第一个和第二个值除以它们的第三个坐标。

out(1,:) = out(1,:) ./ out(3,:);
out(2,:) = out(2,:) ./ out(3,:);
out = out(1:2,:);

但是,使用 transformPointsForward 假设您正在 post-乘以 矩阵,因此您必须转置单应矩阵。这是由于 MATLAB 的列优先偏好,因此单应矩阵的系数按列优先顺序读出。但是,您可以保留点矩阵不变。

因此,当您指定单应性 H 时,您必须先 转置 它,然后再创建 projective2d 实例。完成后,您可以使用 transformPointsForward.

tform = projective2d(H.');
out = transformPointsForward(tform, pts);

函数的第一个输入是您创建的投影变换,第二个输入是点矩阵 - 每行一个。输出将是一个与 pts 大小相同的矩阵,但每一行都是给定 tform.

每个输入点的转换版本

但是,如果您想弄清楚这是如何在幕后完成的,那么您可以在没有 transformPointsForward 的情况下自己实现同样的事情。这是通过首先转置 pts,用 ones 的行向量增加它,乘以 H 然后将结果转置为相同大小来完成的。但是,您应该注意这些扭曲坐标是齐次形式的,因此您必须按照我们之前指定的方式进行除法:

pts_aug = [pts.'; ones(1, size(pts, 1))];
out = (H * pts_aug).';
out = bsxfun(@rdivide, out(:,1:2), out(:,3));

第一行执行增强,第二行执行扭曲,最后第三行执行我们谈到的除法。我决定使用 bsxfun 在一行中进行除法。但是在 MATLAB R2016b 及以后的版本中,我们可以利用广播:

out = out(:,1:2) ./ out(:,3);    

作为一个简单的例子,让我们在 MATLAB 中定义您的 H,然后让我们定义一堆随机点:

H =[1.06  -0.56  77.55; -0.02   0.74  28.34; 0.02  -0.01   1.00];
rng(123);
pts = randi(20, 4, 2);

我们将 H 定义为单应性,我为随机生成器播种,以便生成四个 2D 随机点,其中预期的最大值为 20。一行是一个点,就像您在问题中指定的那样。现在让我们确保此行为在两种方法之间是一致的:

% Method #1
tform = projective2d(H.');
out = transformPointsForward(tform, pts);

% Method #2
pts_aug = [pts.'; ones(1, size(pts, 1))];
out2 = (H * pts_aug).';
out2 = bsxfun(@rdivide, out2(:,1:2), out2(:,3));

outout2 是输出扭曲点,显示它们我们得到:

>> format long g
>> out

out =

          74.3274336283186          34.6548672566372
          76.5728155339806          33.8640776699029
          79.6111111111111          47.8222222222222
          74.9363636363636          34.9636363636364

>> out2

out2 =

          74.3274336283186          34.6548672566372
          76.5728155339806          33.8640776699029
          79.6111111111111          47.8222222222222
          74.9363636363636          34.9636363636364