我要做的是将给定的单应性应用于一组点(x,y)(而不是将其应用于图像的通常用例。)
我将单应性存储为3x3维矩阵:
H =
1.06 -0.56 77.55
-0.02 0.74 28.34
0.02 -0.01 1.00
我有一套积分。 E.g:
pts = [x1,y1 ; x2,y2 ; x3,y3 ;x4,y4 ; ...];
如何将H
应用于pts
?
我知道将它应用于图像非常简单:
img = imread('pathtofile\file.png');
tform = projective2d(H);
img2 = imwarp(img, tform);
但点名单是否等同于imwrap
?
答案 0 :(得分:3)
使用projective2d
类transformPointsForward
部分的https://stackoverflow.com/a/33738730/8342943功能。但是,请注意,您指定的单应性假定您将单应性与输入点预乘。这很明显,因为最后一列看起来像翻译矢量。也就是说,给定矩阵H
和点P
矩阵,其中每个列是增强形式中的一个点,其中第三行的值为1,可以通过以下方式实现积分的翘曲:
out = H * P;
你最终会获得扭曲点 - 每列一点。请注意,坐标是齐次形式,因此您必须采用第三个坐标并将每列中相应的第一个和第二个值除以第三个坐标。
out(1,:) = out(1,:) ./ out(3,:);
out(2,:) = out(2,:) ./ out(3,:);
out = out(1:2,:);
但是,使用transformPointsForward
假定您使用矩阵后乘,因此您必须转置单应矩阵。这是由于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));
out
和out2
是输出扭曲点,并显示它们:
>> 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