1 // \file
2 //
3 // \version 1.0
4 // \author Gaston Araguas UTN Cordoba, Argentina
5 // \date 3 March, 2008
6
7 #include "vgui/vgui.h"
8 #include "vgui/vgui_easy2D_tableau.h"
9 #include "vgui/vgui_viewer2D_tableau.h"
10 #include "vgui/vgui_shell_tableau.h"
11 #include "vgl/vgl_homg_point_2d.h"
12 #include <vgl/algo/vgl_h_matrix_2d.h>
13 #include <vgl/algo/vgl_h_matrix_2d_compute_linear.h>
14 #include "vnl/vnl_math.h"
15
16 int
main(int argc,char ** argv)17 main(int argc, char ** argv)
18 {
19 vgui::init(argc, argv);
20 std::vector<vgl_homg_point_2d<double>> pointsA;
21 std::vector<vgl_homg_point_2d<double>> pointsB;
22
23 // Use an easy2D tableau which allows us to draw 2D objects:
24 vgui_easy2D_tableau_new easy2D("Homography between two point sets");
25 easy2D->set_foreground(0, 1, 0);
26 easy2D->set_point_radius(5);
27
28 // set A
29 vgl_homg_point_2d<double> const p1(100, 200, 1);
30 vgl_homg_point_2d<double> const p2(200, 200, 1);
31 vgl_homg_point_2d<double> const p3(300, 300, 1);
32 vgl_homg_point_2d<double> const p4(300, 100, 1);
33 pointsA.push_back(p1);
34 pointsA.push_back(p2);
35 pointsA.push_back(p3);
36 pointsA.push_back(p4);
37 easy2D->add_point(float(p1.x()), float(p1.y()));
38 easy2D->add_point(float(p2.x()), float(p2.y()));
39 easy2D->add_point(float(p3.x()), float(p3.y()));
40 easy2D->add_point(float(p4.x()), float(p4.y()));
41
42 // connect all points with lines
43 easy2D->set_foreground(1, 0, 0);
44 easy2D->set_line_width(1);
45 easy2D->add_line(float(p1.x()), float(p1.y()), float(p2.x()), float(p2.y()));
46 easy2D->add_line(float(p2.x()), float(p2.y()), float(p3.x()), float(p3.y()));
47 easy2D->add_line(float(p3.x()), float(p3.y()), float(p4.x()), float(p4.y()));
48 easy2D->add_line(float(p4.x()), float(p4.y()), float(p1.x()), float(p1.y()));
49
50 // draw a line from (0,0) to the center of gravity of set A
51 vgl_homg_point_2d<double> centre_pointA(
52 centre(pointsA).x() / centre(pointsA).w(), centre(pointsA).y() / centre(pointsA).w(), 1.0);
53 easy2D->set_foreground(1, 1, 0);
54 easy2D->set_point_radius(5);
55 easy2D->add_point(float(centre_pointA.x()), float(centre_pointA.y()));
56 easy2D->set_foreground(0, 0, 1);
57 easy2D->set_line_width(3);
58 easy2D->add_line(0, 0, float(centre_pointA.x()), float(centre_pointA.y()));
59
60 // rotation and translation
61 double angle = -vnl_math::pi_over_180 * 20;
62 vgl_h_matrix_2d<double> H;
63 H.set_identity().set_translation(100.0, 20.0).set_rotation(angle);
64
65 // apply the rotation and translation to set A, obtain set B
66 easy2D->set_foreground(0, 1, 0);
67 easy2D->set_point_radius(5);
68 vgl_homg_point_2d<double> tr_p1 = H * p1;
69 vgl_homg_point_2d<double> tr_p2 = H * p2;
70 vgl_homg_point_2d<double> tr_p3 = H * p3;
71 vgl_homg_point_2d<double> tr_p4 = H * p4;
72 pointsB.push_back(tr_p1);
73 pointsB.push_back(tr_p2);
74 pointsB.push_back(tr_p3);
75 pointsB.push_back(tr_p4);
76 easy2D->add_point(float(tr_p1.x()), float(tr_p1.y()));
77 easy2D->add_point(float(tr_p2.x()), float(tr_p2.y()));
78 easy2D->add_point(float(tr_p3.x()), float(tr_p3.y()));
79 easy2D->add_point(float(tr_p4.x()), float(tr_p4.y()));
80
81 // connect all points with lines
82 easy2D->set_foreground(1, 0, 0);
83 easy2D->set_line_width(1);
84 easy2D->add_line(float(tr_p1.x()), float(tr_p1.y()), float(tr_p2.x()), float(tr_p2.y()));
85 easy2D->add_line(float(tr_p2.x()), float(tr_p2.y()), float(tr_p3.x()), float(tr_p3.y()));
86 easy2D->add_line(float(tr_p3.x()), float(tr_p3.y()), float(tr_p4.x()), float(tr_p4.y()));
87 easy2D->add_line(float(tr_p4.x()), float(tr_p4.y()), float(tr_p1.x()), float(tr_p1.y()));
88
89 // compute the homography between set A and set B
90 vgl_h_matrix_2d_compute_linear hcl;
91 vgl_h_matrix_2d<double> H_comp = hcl.compute(pointsA, pointsB);
92
93 // translate and rotate the centre of gravity of set A using the computed homography H_comp
94 vgl_homg_point_2d<double> centre_pointB = H_comp * centre_pointA;
95 centre_pointB.set(centre_pointB.x() / centre_pointB.w(), centre_pointB.y() / centre_pointB.w(), 1.0);
96
97 // draw a line from (0,0) to transformed centre of gravity of set A, i.e. centre of gravity of set B
98 easy2D->set_foreground(1, 1, 0);
99 easy2D->set_point_radius(5);
100 easy2D->add_point(float(centre_pointB.x() / centre_pointB.w()), float(centre_pointB.y() / centre_pointB.w()));
101 easy2D->set_foreground(0, 1, 0);
102 easy2D->set_line_width(3);
103 easy2D->add_line(0, 0, float(centre_pointB.x()), float(centre_pointB.y()));
104
105 vgui_viewer2D_tableau_new viewer(easy2D);
106 vgui_shell_tableau_new shell(viewer);
107 return vgui::run(shell, 512, 512);
108 }
109