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