1 #include "breg3d_init_ekf_camera_optimizer_planar_process.h"
2 
3 #include <brdb/brdb_value.h>
4 #include <bprb/bprb_parameters.h>
5 
6 #include "vil/vil_image_view_base.h"
7 #include "vil/vil_image_view.h"
8 #include "vil/vil_convert.h"
9 #include "vpgl/vpgl_camera.h"
10 #include "vpgl/vpgl_perspective_camera.h"
11 #include "vgl/vgl_plane_3d.h"
12 
13 #include <bvxm/bvxm_voxel_world.h>
14 
15 #include <breg3d/breg3d_ekf_camera_optimizer_state.h>
16 #include <breg3d/breg3d_homography_generator.h>
17 #include <breg3d/breg3d_lm_direct_homography_generator.h>
18 
breg3d_init_ekf_camera_optimizer_planar_process()19 breg3d_init_ekf_camera_optimizer_planar_process::breg3d_init_ekf_camera_optimizer_planar_process()
20 {
21   // process takes 4 inputs:
22   //input[0]: The first estimated camera (should be of type vgpl_perspective_camera)
23   //input[1]: The first frame
24   //input[2]: The second frame
25   //input[3]: The voxel world
26   input_data_.resize(4,brdb_value_sptr(nullptr));
27   input_types_.resize(4);
28   input_types_[0] = "vpgl_camera_double_sptr";
29   input_types_[1] = "vil_image_view_base_sptr";
30   input_types_[2] = "vil_image_view_base_sptr";
31   input_types_[3] = "bvxm_voxel_world_sptr";
32 
33   // process has 6 outputs:
34   // output[0]: The initial state estimate for the kalman filter
35   // output[1]: The second camera's estimated position
36   // outputs[2-5]: The plane parameters a,b,c,d  (ax + by + cz + d = 0)
37   output_data_.resize(6,brdb_value_sptr(nullptr));
38   output_types_.resize(6);
39   output_types_[0] = "breg3d_ekf_camera_optimizer_state";
40   output_types_[1] = "vpgl_camera_double_sptr";
41   output_types_[2] = "double";
42   output_types_[3] = "double";
43   output_types_[4] = "double";
44   output_types_[5] = "double";
45 
46   // parameters
47   // default corresponds to roughly 1 degree std deviation
48   if (!parameters()->add("Translation Scale Factor", "translation_scale", 0.005))
49     std::cerr << "ERROR: Adding parameters in " << __FILE__ << '\n';
50 
51   // default corresponds to roughly 1 degree std deviation
52   if (!parameters()->add("Rotation Measurement Variance", "rotation_measurement_variance", 3e-4))
53     std::cerr << "ERROR: Adding parameters in " << __FILE__ << '\n';
54 
55   // default corresponds to roughly 0.5 meter std deviation
56   if (!parameters()->add("Position Measurement Variance", "position_measurement_variance", 0.25))
57     std::cerr << "ERROR: Adding parameters in " << __FILE__ << '\n';
58 }
59 
60 
execute()61 bool breg3d_init_ekf_camera_optimizer_planar_process::execute()
62 {
63   // Sanity check
64   if (!this->verify_inputs())
65     return false;
66 
67   auto* input0 =
68     static_cast<brdb_value_t<vpgl_camera_double_sptr>* >(input_data_[0].ptr());
69 
70   auto* input1 =
71     static_cast<brdb_value_t<vil_image_view_base_sptr>* >(input_data_[1].ptr());
72 
73   auto* input2 =
74     static_cast<brdb_value_t<vil_image_view_base_sptr>* >(input_data_[2].ptr());
75 
76   auto* input3 =
77     static_cast<brdb_value_t<bvxm_voxel_world_sptr>* >(input_data_[3].ptr());
78 
79   // get first camera
80   vpgl_perspective_camera<double> *cam0;
81   if (!(cam0 = dynamic_cast<vpgl_perspective_camera<double>*>(input0->value().ptr()))) {
82        std::cerr << "error: process expects camera to be a vpgl_perspective_camera.\n";
83       return false;
84   }
85 
86   // get first and second images
87   vil_image_view_base_sptr img0 = input1->value();
88   vil_image_view_base_sptr img1 = input2->value();
89   // get voxel world
90   bvxm_voxel_world_sptr vox_world = input3->value();
91 
92   // get parameters
93   double rot_var=0.0, pos_var=0.0, t_scale=0.0; // dummy initialisations to avoid compiler warnings
94   if (!parameters()->get_value(std::string("position_measurement_variance"), rot_var)) {
95     std::cout << "breg3d_init_ekf_camera_optimizer_planar_process::execute() -- problem in retrieving parameter rotation_variance\n";
96     return false;
97   }
98   if (!parameters()->get_value(std::string("position_measurement_variance"), pos_var)) {
99     std::cout << "breg3d_init_ekf_camera_optimizer_planar_process::execute() -- problem in retrieving parameter position_variance\n";
100     return false;
101   }
102 
103   if (!parameters()->get_value(std::string("translation_scale"), t_scale)) {
104     std::cout << "breg3d_init_ekf_camera_optimizer_planar_process::execute() -- problem in retrieving parameter translation_scale\n";
105     return false;
106   }
107 
108   // compute homography from img0 to img1
109   breg3d_homography_generator *h_gen = new breg3d_lm_direct_homography_generator();
110   float dummy = 0.0f;
111   vil_image_view_base_sptr img0_float_sptr = vil_convert_cast(dummy,img0);
112   vil_image_view_base_sptr img1_float_sptr = vil_convert_cast(dummy,img1);
113   auto* img0_float = dynamic_cast<vil_image_view<float>*>(img0_float_sptr.ptr());
114   auto* img1_float = dynamic_cast<vil_image_view<float>*>(img1_float_sptr.ptr());
115 
116   h_gen->set_image0(img0_float);
117   h_gen->set_image1(img1_float);
118   ihog_transform_2d H = h_gen->compute_homography();
119 
120   std::cout << "H =\n" << H.get_matrix() << std::endl;
121 
122   // TEMP
123   auto *cam1 = new vpgl_perspective_camera<double>(cam0->get_calibration(),cam0->get_camera_center(),cam0->get_rotation());
124 
125   // compute position of plane and camera1
126   vgl_plane_3d<double> plane_est = vox_world->fit_plane();
127 
128   std::cout << "plane est = " << plane_est << std::endl;
129 
130   breg3d_ekf_camera_optimizer_state init_state(t_scale,cam0->camera_center(),cam0->get_rotation(),pos_var,rot_var);
131 
132   //store output
133   // initial state
134   brdb_value_sptr output0 =
135     new brdb_value_t<breg3d_ekf_camera_optimizer_state>(init_state);
136   output_data_[0] = output0;
137 
138   // camera1 estimate
139   brdb_value_sptr output1 =
140     new brdb_value_t<vpgl_camera_double_sptr>(cam1);
141   output_data_[1] = output1;
142 
143   // plane estimate
144   brdb_value_sptr output2 =
145     new brdb_value_t<double>(plane_est.a());
146   output_data_[2] = output2;
147   brdb_value_sptr output3 =
148     new brdb_value_t<double>(plane_est.b());
149   output_data_[3] = output3;
150   brdb_value_sptr output4 =
151     new brdb_value_t<double>(plane_est.c());
152   output_data_[4] = output4;
153   brdb_value_sptr output5 =
154     new brdb_value_t<double>(plane_est.d());
155   output_data_[5] = output5;
156 
157   return true;
158 }
159