Skip to content

Commit 1609b7f

Browse files
committed
test, doc a perspective projection
1 parent cc6ec0a commit 1609b7f

2 files changed

Lines changed: 17 additions & 9 deletions

File tree

lib/PDL/Transform.pd

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3888,9 +3888,17 @@ can continuously warp an image plane so that C<ncoords + 2> arbitrarily chosen
38883888
points exactly map to the same number of other arbitrarily chosen points. They
38893889
have the property that straight lines remain straight after transformation.
38903890

3891+
=for example
3892+
3893+
# perspective projection 3D -> 2D
3894+
$t_proj = t_projective(
3895+
src => pdl('1 1 1; -1 1 1; -1 -1 1; 1 -1 1; 2 2 2; -2 -2 2'),
3896+
dst => pdl('0 1000; 1000 1000; 1000 0; 0 0; 0 1000; 1000 0'),
3897+
);
3898+
38913899
You can specify your projective transformation directly in homogeneous
38923900
coordinates, or (as of 2.104, not just in 2 dimensions) as a set
3893-
of C<ncoords + 2> unique points that
3901+
of unique points that
38943902
are mapped one to the other by the transformation.
38953903

38963904
Projective transforms are quasi-linear because they are most easily
@@ -3936,8 +3944,7 @@ For example, specifying
39363944
maps the origin and the point (0,1) to themselves, the point (5,9)
39373945
to (5,8), and the point (9,4) to (9,3).
39383946

3939-
Added in 2.104. Works on any number of dimensions, the same for
3940-
C<src> and C<dst> (a homography).
3947+
Added in 2.104. Works on any number of dimensions.
39413948

39423949
=item p, point, points, Points
39433950

@@ -4007,9 +4014,7 @@ sub solve_DLT {
40074014
my ($A, $T_src, $T_dst) = @_;
40084015
my ($U, $S, $V) = svd($A, 1); # full SVD
40094016
my $P_norm = $V->slice(-1)->reshape(map $_->dim(0), $T_src, $T_dst); # reshape smallest singular value vector
4010-
my $P = $T_dst->inv x $P_norm x $T_src; # Denormalize
4011-
my $div_value = $P->slice(($T_dst->dim(0)-1) x 2); # scaling for numerical stability
4012-
$P / $div_value;
4017+
$T_dst->inv x $P_norm x $T_src; # Denormalize
40134018
}
40144019

40154020
sub t_projective {

t/transform.t

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,12 @@ use Test::Exception;
3838
3939
my $t_points = pdl('[0 0; 1 0] [1 0; 2 1] [0 1; -1 3] [1 1; 0 4]'); # xy,io,npoints
4040
my $t_proj = t_projective(p=>$t_points);
41-
is_pdl $t_proj->{params}{matrix}, my $exp_proj = pdl('1 -2 1; 1 3 0; 0 0 1');
4241
is_pdl +(my $p_in = pdl('0.5 0; 1 0.5; 0.5 1; 0 0.5'))->apply($t_proj), my $p_out = pdl('1.5 0.5; 1 2.5; -0.5 3.5; 0 1.5'), 't_projective works';
4342
is_pdl $p_out->invert($t_proj), $p_in, 't_projective inv';
4443
$t_proj = t_projective(
4544
src => my $src2 = $t_points->slice(",(0)"),
4645
dst => my $dst2 = $t_points->slice(",(1)"),
4746
);
48-
is_pdl $t_proj->{params}{matrix}, $exp_proj;
4947
my ($A_2) = PDL::Transform::construct_DLT($src2, $dst2);
5048
is_pdl $A_2, pdl('
5149
-1 -1 1 0 0 0 0.365966 0.365966 -0.365966;
@@ -60,7 +58,12 @@ use Test::Exception;
6058
$t_proj = t_projective(
6159
m => pdl('-500 0 500 0; 0 500 500 0; 0 0 1 0'),
6260
);
63-
is_pdl $t_proj->apply(my $in32 = pdl('0 -1 -1; 4 2 -10')), my $out32 = pdl('500 1000; 700 400'), 'project 3->2 with matrix';
61+
is_pdl $t_proj->apply(my $in32 = pdl('0 -1 -1; 4 2 -10')), my $out32 = pdl('500 1000; 700 400'), 'project perspective 3->2 with matrix';
62+
$t_proj = t_projective(
63+
src => my $src32perspective = pdl('1 1 1; -1 1 1; -1 -1 1; 1 -1 1; 2 2 2; -2 -2 2'),
64+
dst => my $dst32perspective = pdl('0 1000; 1000 1000; 1000 0; 0 0; 0 1000; 1000 0'),
65+
);
66+
is_pdl $t_proj->apply($in32), $out32, 'project perspective 3->2 with src/dst';
6467
$t_proj = t_projective(
6568
src => my $src3 = pdl('0 0 0; 1 0 0; 0 1 0; 1 1 0; 0 0 1'),
6669
dst => my $dst3 = pdl('1 0 0; 2 1 0; -1 3 0; 0 4 0; 1 0 1'),

0 commit comments

Comments
 (0)