1 // This is brl/bpro/core/vpgl_pro/processes/vpgl_convert_to_generic_camera_process.cxx
2 #include <iostream>
3 #include <bprb/bprb_func_process.h>
4 //:
5 // \file
6 // \brief A process to convert perspective camera to rational camera.
7
8 #ifdef _MSC_VER
9 # include "vcl_msvc_warnings.h"
10 #endif
11 #include "vpgl/vpgl_generic_camera.h"
12 #include <vpgl/algo/vpgl_camera_compute.h>
13 #include <vpgl/algo/vpgl_camera_convert.h>
14
15
16 //: Init function
vpgl_convert_to_generic_camera_process_cons(bprb_func_process & pro)17 bool vpgl_convert_to_generic_camera_process_cons(bprb_func_process& pro)
18 {
19 //this process takes 4 inputs and has 3 outputs:
20 // 0) abstract camera
21 // 1) ni (# image columns)
22 // 2) nj (# image rows)
23 // 3) level (the pyramid scale)
24 std::vector<std::string> input_types;
25 input_types.emplace_back("vpgl_camera_double_sptr");
26 input_types.emplace_back("unsigned"); // ni
27 input_types.emplace_back("unsigned"); // nj
28 input_types.emplace_back("unsigned"); // level, e.g. camera needs to be scaled or not, pass the ni-nj of the original image
29 bool ok = pro.set_input_types(input_types);
30
31 // in case the 4th input is not set
32 brdb_value_sptr idx = new brdb_value_t<unsigned>(0);
33 pro.set_input(3, idx);
34
35 if (!ok) return ok;
36
37 std::vector<std::string> output_types;
38 output_types.emplace_back("vpgl_camera_double_sptr"); // label image
39 output_types.emplace_back("unsigned");
40 output_types.emplace_back("unsigned");
41 return pro.set_output_types(output_types);
42 }
43
44 //: Execute the process
vpgl_convert_to_generic_camera_process(bprb_func_process & pro)45 bool vpgl_convert_to_generic_camera_process(bprb_func_process& pro)
46 {
47 if (pro.n_inputs()!= 4) {
48 std::cout << "vpgl_convert_to_generic_camera_process: The number of inputs should be 4" << std::endl;
49 return false;
50 }
51 // get the inputs
52 vpgl_camera_double_sptr camera = pro.get_input<vpgl_camera_double_sptr>(0);
53 if (!camera) {
54 std::cout<<"Null camera input\n"<<std::endl;
55 return false;
56 }
57 auto ni = pro.get_input<unsigned>(1), nj = pro.get_input<unsigned>(2);
58 auto level = pro.get_input<unsigned>(3);
59 vpgl_generic_camera<double> gcam;
60
61 if (!vpgl_generic_camera_convert::convert(camera, (int)ni, (int)nj, gcam, level)) {
62 std::cout<<"camera conversion failed\n"<<std::endl;
63 return false;
64 }
65 vpgl_camera_double_sptr out = new vpgl_generic_camera<double>(gcam);
66 pro.set_output_val<vpgl_camera_double_sptr>(0, out);
67 pro.set_output_val<unsigned>(1,gcam.cols());
68 pro.set_output_val<unsigned>(2,gcam.rows());
69 return true;
70 }
71
72 //: Init function
vpgl_convert_to_generic_camera_w_margin_process_cons(bprb_func_process & pro)73 bool vpgl_convert_to_generic_camera_w_margin_process_cons(bprb_func_process& pro)
74 {
75 std::vector<std::string> input_types;
76 input_types.emplace_back("vpgl_camera_double_sptr");
77 input_types.emplace_back("unsigned");// ni
78 input_types.emplace_back("unsigned");// nj
79 input_types.emplace_back("unsigned"); // level, e.g. camera needs to be scaled or not, pass the ni-nj of the original image
80 input_types.emplace_back("int"); // margin, e.g. to create a wider expected image
81 bool ok = pro.set_input_types(input_types);
82
83 // in case the 5th input is not set
84 brdb_value_sptr idx = new brdb_value_t<unsigned>(0);
85 pro.set_input(3, idx);
86
87 if (!ok) return ok;
88
89 std::vector<std::string> output_types;
90 output_types.emplace_back("vpgl_camera_double_sptr"); // label image
91 output_types.emplace_back("unsigned");
92 output_types.emplace_back("unsigned");
93 output_types.emplace_back("vpgl_camera_double_sptr");
94 return pro.set_output_types(output_types);
95 }
96
97 //: Execute the process
vpgl_convert_to_generic_camera_w_margin_process(bprb_func_process & pro)98 bool vpgl_convert_to_generic_camera_w_margin_process(bprb_func_process& pro)
99 {
100 if (pro.n_inputs()!= 5) {
101 std::cout << "vpgl_convert_to_generic_camera_w_margin_process: The number of inputs should be 5" << std::endl;
102 return false;
103 }
104 // get the inputs
105 vpgl_camera_double_sptr camera = pro.get_input<vpgl_camera_double_sptr>(0);
106 if (!camera) {
107 std::cout<<"Null camera input\n"<<std::endl;
108 return false;
109 }
110 auto ni = pro.get_input<unsigned>(1), nj = pro.get_input<unsigned>(2);
111 auto level = pro.get_input<unsigned>(3);
112 int margin = pro.get_input<int>(4);
113 vpgl_generic_camera<double> gcam;
114
115 auto *cam = dynamic_cast<vpgl_perspective_camera<double>*>(camera.as_pointer());
116 if (!cam) {
117 std::cout<<"Input camera is not perspective, not implemented for other camera types!\n";
118 return false;
119 }
120
121 if (!vpgl_generic_camera_convert::convert_with_margin(*cam,(int)ni,(int)nj,gcam,margin,level)) {
122 std::cout<<"camera conversion failed\n"<<std::endl;
123 return false;
124 }
125 //: adjust the calibration matrix
126 auto* ncam =
127 new vpgl_perspective_camera<double>(*cam);
128
129 vnl_matrix_fixed<double, 3, 3> T(0.0);
130 T[0][0] = 1.0; T[1][1] = 1.0; T[2][2] = 1.0;
131 T[0][2] = margin; T[1][2] = margin;
132
133 vnl_matrix_fixed<double,3,3> M = cam->get_calibration().get_matrix();
134 M = T*M;
135 vpgl_calibration_matrix<double> K(M);
136 ncam->set_calibration(K);
137
138 vpgl_camera_double_sptr out = new vpgl_generic_camera<double>(gcam);
139 pro.set_output_val<vpgl_camera_double_sptr>(0, out);
140 pro.set_output_val<unsigned>(1,gcam.cols());
141 pro.set_output_val<unsigned>(2,gcam.rows());
142 pro.set_output_val<vpgl_camera_double_sptr>(3,ncam);
143 return true;
144 }
145
146
147 //: Init function
vpgl_write_generic_camera_process_cons(bprb_func_process & pro)148 bool vpgl_write_generic_camera_process_cons(bprb_func_process& pro)
149 {
150 std::vector<std::string> input_types;
151 input_types.emplace_back("vpgl_camera_double_sptr");
152 input_types.emplace_back("vcl_string"); // name of output vrml file
153 input_types.emplace_back("unsigned"); // name of output vrml file
154 bool ok = pro.set_input_types(input_types);
155
156 if (!ok) return ok;
157
158 std::vector<std::string> output_types;
159 return pro.set_output_types(output_types);
160 }
161
162 //: Execute the process
vpgl_write_generic_camera_process(bprb_func_process & pro)163 bool vpgl_write_generic_camera_process(bprb_func_process& pro)
164 {
165 if (pro.n_inputs()!= 3) {
166 std::cout << "vpgl_write_generic_camera_process: The number of inputs should be 2" << std::endl;
167 return false;
168 }
169 // get the inputs
170 vpgl_camera_double_sptr camera = pro.get_input<vpgl_camera_double_sptr>(0);
171 if (!camera) {
172 std::cout<<"Null camera input\n"<<std::endl;
173 return false;
174 }
175 std::string out_name = pro.get_input<std::string>(1);
176 auto level = pro.get_input<unsigned>(2);
177
178 auto* gcam = dynamic_cast<vpgl_generic_camera<double>* >(camera.ptr());
179
180 std::ofstream ofs(out_name.c_str());
181 ofs << "#VRML V2.0 utf8\n";
182 gcam->print_to_vrml(level, ofs);
183 ofs.close();
184
185 return true;
186 }
187
188 //: fetch the ray origin and direction for a given image pixel
vpgl_get_generic_camera_ray_process_cons(bprb_func_process & pro)189 bool vpgl_get_generic_camera_ray_process_cons(bprb_func_process& pro)
190 {
191 std::vector<std::string> input_types;
192 input_types.emplace_back("vpgl_camera_double_sptr");
193 input_types.emplace_back("unsigned"); // u
194 input_types.emplace_back("unsigned"); // v
195 bool ok = pro.set_input_types(input_types);
196
197 if (!ok) return ok;
198
199 std::vector<std::string> output_types;
200 output_types.emplace_back("double"); // ray origin x
201 output_types.emplace_back("double"); // ray origin y
202 output_types.emplace_back("double"); // ray origin z
203 output_types.emplace_back("double"); // ray direction x
204 output_types.emplace_back("double"); // ray direction y
205 output_types.emplace_back("double"); // ray direction z
206 return pro.set_output_types(output_types);
207 }
208
209 //: Execute the process
vpgl_get_generic_camera_ray_process(bprb_func_process & pro)210 bool vpgl_get_generic_camera_ray_process(bprb_func_process& pro)
211 {
212 if (pro.n_inputs()!= 3) {
213 std::cout << "vpgl_get_generic_camera_ray_process: The number of inputs should be 3" << std::endl;
214 return false;
215 }
216 // get the inputs
217 vpgl_camera_double_sptr camera = pro.get_input<vpgl_camera_double_sptr>(0);
218 if (!camera) {
219 std::cout<<"Null camera input\n"<<std::endl;
220 return false;
221 }
222
223 auto u = pro.get_input<unsigned>(1);
224 auto v = pro.get_input<unsigned>(2);
225
226 auto* gcam = dynamic_cast<vpgl_generic_camera<double>* >(camera.ptr());
227 vgl_ray_3d<double> ray = gcam->ray(u, v);
228
229 pro.set_output_val<double>(0, ray.origin().x());
230 pro.set_output_val<double>(1, ray.origin().y());
231 pro.set_output_val<double>(2, ray.origin().z());
232 pro.set_output_val<double>(3, ray.direction().x());
233 pro.set_output_val<double>(4, ray.direction().y());
234 pro.set_output_val<double>(5, ray.direction().z());
235 return true;
236 }
237