1 #include "icam_view_sphere.h"
2 //:
3 // \file
4 #include "vpgl/vpgl_perspective_camera.h"
5 #include <vsph/vsph_camera_bounds.h>
6
icam_view_sphere(vgl_box_3d<double> bb,double radius)7 icam_view_sphere::icam_view_sphere(vgl_box_3d<double> bb, double radius)
8 : view_sphere_(nullptr), ICAM_LOCAL_MIN_THRESH_(100)
9 {
10 // create the view sphere
11 view_sphere_ = new vsph_view_sphere<vsph_view_point<icam_view_metadata> > (bb, radius);
12 }
13
create_view_points(double cap_angle,double view_angle,unsigned ni,unsigned nj)14 void icam_view_sphere::create_view_points(double cap_angle, double view_angle, unsigned ni, unsigned nj)
15 {
16 // create the view points
17 view_sphere_->add_uniform_views(cap_angle, view_angle,ni,nj);
18 }
19
20 //: returns the cameras of the view points, associated with the view point id
cameras(std::map<unsigned,vpgl_camera_double_sptr> & cameras)21 void icam_view_sphere::cameras(std::map<unsigned, vpgl_camera_double_sptr> &cameras)
22 {
23 auto it=view_sphere_->begin();
24 while (it != view_sphere_->end()) {
25 vsph_view_point<icam_view_metadata> vp = it->second;
26 unsigned id = it->first;
27 cameras[id] = vp.camera();
28 it++;
29 }
30 }
31
set_cameras(std::map<unsigned,vpgl_camera_double_sptr> const & cameras)32 void icam_view_sphere::set_cameras(std::map<unsigned, vpgl_camera_double_sptr> const &cameras)
33 {
34 auto it=view_sphere_->begin();
35 auto cam_it=cameras.begin();
36 while (it != view_sphere_->end() && cam_it != cameras.end()) {
37 vpgl_camera_double_sptr cam = cam_it->second;
38 it->second.set_camera(cam);
39 auto* pers_cam = static_cast<vpgl_perspective_camera<double>*>(cam.as_pointer());
40 vgl_homg_point_3d<double> center = pers_cam->camera_center();
41 vsph_spherical_coord coord;
42 vsph_sph_point_3d sp;
43 coord.spherical_coord(center, sp);
44 it->second.set_view_point(sp);
45 it++;
46 cam_it++;
47 }
48 }
49
50 //: sets the images and depth images, associated with the view point id
set_images(std::map<unsigned,std::string> & images,std::map<unsigned,std::string> & depth_images)51 void icam_view_sphere::set_images(std::map<unsigned, std::string>& images,
52 std::map<unsigned, std::string>& depth_images)
53 {
54 auto it_imgs=images.begin();
55 while (it_imgs != images.end()) {
56 unsigned uid = it_imgs->first;
57 if (images[uid].size()>0) {
58 // make sure that there is a corresponding depth image
59 if (depth_images.find(uid) != depth_images.end()) {
60 vsph_view_point<icam_view_metadata>* vp;
61 if (view_sphere_->view_point(uid, vp)) {
62 // get the camera
63 vpgl_camera_double_sptr camera=vp->camera();
64 auto* cam = dynamic_cast<vpgl_perspective_camera<double>*> (camera.as_pointer());
65 if (cam) {
66 icam_view_metadata* data = new icam_view_metadata(images[uid],depth_images[uid]);
67 vp->set_metadata(data);
68 }
69 }
70 }
71 else
72 std::cout << "icam_view_sphere::set_images -- ERROR! There is a missing depth image for image id=" << uid << std::endl;
73 }
74 it_imgs++;
75 }
76 }
77
register_image(vil_image_view<float> const & dest_img,icam_minimizer_params const & params)78 void icam_view_sphere::register_image(vil_image_view<float> const& dest_img,
79 icam_minimizer_params const& params)
80 {
81 // try to find the best camera at each view point and at the end we will
82 // have errors to compare on the view sphere
83 auto it=view_sphere_->begin();
84 unsigned index = 0;
85 while (it != view_sphere_->end()) {
86 vsph_view_point<icam_view_metadata> vp = it->second;
87 icam_view_metadata* data=vp.metadata();
88 if (data) {
89 vpgl_camera_double_sptr camera=vp.camera();
90 std::cout << "Evaluating viewpoint " << index << '\n';
91 data->register_image(dest_img, camera, params);
92 }
93 it++; index++;
94 }
95
96 std::vector<vsph_view_point<icam_view_metadata> > local_min;
97 find_local_minima(local_min);
98 #if 0
99 std::vector<vsph_view_point<icam_view_metadata> > local_min;
100 vsph_view_point<icam_view_metadata>* vp;
101 view_sphere_->view_point(85,vp);
102 vpgl_perspective_camera<double>* cam = (vpgl_perspective_camera<double>*)vp->camera().as_pointer();
103 std::cout << *cam;
104 local_min.push_back(*vp);
105 //vsph_view_point<icam_view_metadata>* vp;
106 view_sphere_->view_point(87,vp);
107 cam = (vpgl_perspective_camera<double>*)vp->camera().as_pointer();
108 std::cout << *cam;
109 local_min.push_back(*vp);
110 //vsph_view_point<icam_view_metadata>* vp;
111 view_sphere_->view_point(88,vp);
112 cam = (vpgl_perspective_camera<double>*)vp->camera().as_pointer();
113 std::cout << *cam;
114 local_min.push_back(*vp);
115 #endif
116 double cam_cost=1e99; // will become min cost, so initialise with high value
117 for (unsigned i=0; i<local_min.size(); i++) {
118 std::cout << "Local MINIMA " << i << "--" << local_min[i].view_point() << std::endl;
119 auto* gt_cam =
120 dynamic_cast<vpgl_perspective_camera<double>* >(ground_truth_cam_.as_pointer());
121 if (gt_cam) {
122 vpgl_perspective_camera<double>* cam = (vpgl_perspective_camera<double>*)local_min[i].camera().as_pointer();
123 vgl_rotation_3d<double> rel_rot;
124 vgl_vector_3d<double> rel_trans;
125 vsph_camera_bounds::relative_transf(*gt_cam, *cam,rel_rot,rel_trans);
126 std::cout <<"***************************************\n"
127 << "Rel Rot=" << rel_rot << '\n'
128 << "Rel trans=" << rel_trans << '\n'
129 <<"***************************************" << std::endl;
130 }
131 icam_view_metadata* md = local_min[i].metadata();
132 md->refine_camera(dest_img, local_min[i].camera(),params);
133 if (md->cost() < cam_cost) {
134 cam_cost = md->cost();
135 }
136 }
137 }
138
find_local_minima(std::vector<vsph_view_point<icam_view_metadata>> & local_minima)139 void icam_view_sphere::find_local_minima(std::vector<vsph_view_point<icam_view_metadata> >& local_minima)
140 {
141 // go through all the viewpoints to see if it is a local maxima
142 auto it=view_sphere_->begin();
143 while (it != view_sphere_->end()) {
144 vsph_view_point<icam_view_metadata> vp = it->second;
145 unsigned vp_uid = it->first;
146 if (!vp.metadata()) {
147 it++;
148 continue;
149 }
150 double cost=vp.metadata()->cost();
151
152 // find the closest neighbors' errors
153 std::vector<vsph_view_point<icam_view_metadata> > neighbors;
154 view_sphere_->find_neighbors(vp_uid, neighbors);
155 // compare the errors with the neighbors
156 bool smallest=true;
157 double smallest_diff=1e308;
158 for (auto vp : neighbors) {
159 icam_view_metadata* data = vp.metadata();
160 if (data) {
161 if (data->cost() < cost) {
162 smallest=false;
163 }
164 else {
165 double diff = data->cost()-cost;
166 if (smallest_diff > diff)
167 smallest_diff = diff;
168 }
169 }
170 }
171 if (smallest) { // && smallest_diff > ICAM_LOCAL_MIN_THRESH_
172 // the smallest should be really different, and much smaller than the neighborhood
173 std::cout << " Selected-->" << vp_uid << " how far?=" << smallest_diff << std::endl;
174 local_minima.push_back(vp);
175 }
176 it++;
177 }
178 }
179
camera_transf(vpgl_perspective_camera<double> const & cam)180 void icam_view_sphere::camera_transf(vpgl_perspective_camera<double> const& cam)
181 {
182 auto it=view_sphere_->begin();
183 while (it != view_sphere_->end()) {
184 vsph_view_point<icam_view_metadata> vp = it->second;
185 if (!vp.metadata()) {
186 it++;
187 continue;
188 }
189 unsigned vp_uid = it->first;
190 vpgl_perspective_camera<double>* vp_cam = static_cast<vpgl_perspective_camera<double>*>(vp.camera().as_pointer());
191 vgl_rotation_3d<double> rel_rot;
192 vgl_vector_3d<double> rel_trans;
193 vsph_camera_bounds::relative_transf(cam, *vp_cam,rel_rot,rel_trans);
194 std::cout <<"***************************************\n"
195 << "VIEW POINT " << vp_uid << '\n'
196 << "Rel Rot=" << rel_rot << '\n'
197 << "Rel trans=" << rel_trans << '\n'
198 <<"***************************************" << std::endl;
199 }
200 }
201
202 //: the mapped source image and actual destination image at a level
mapped_image(unsigned viewpoint_id,vil_image_view<float> const & source_img,vgl_rotation_3d<double> & rot,vgl_vector_3d<double> & trans,unsigned level,vil_image_view<float> & act_dest,vil_image_view<float> & mapped_dest,icam_minimizer_params const & params)203 void icam_view_sphere::mapped_image(unsigned viewpoint_id,
204 vil_image_view<float> const& source_img,
205 vgl_rotation_3d<double>& rot,
206 vgl_vector_3d<double>& trans,
207 unsigned level,
208 vil_image_view<float>& act_dest,
209 vil_image_view<float>& mapped_dest,
210 icam_minimizer_params const& params)
211 {
212 vsph_view_point<icam_view_metadata>* vp;
213 if (view_sphere_->view_point(viewpoint_id, vp)) {
214 icam_view_metadata* data=vp->metadata();
215 if (data) {
216 vpgl_perspective_camera<double>* vp_cam = static_cast<vpgl_perspective_camera<double>*>(vp->camera().as_pointer());
217 data->mapped_image(source_img, vp_cam, rot, trans, level, params, act_dest, mapped_dest);
218 }
219 }
220 }
221
b_read(vsl_b_istream & is)222 void icam_view_sphere::b_read(vsl_b_istream &is)
223 {
224 if (!is)
225 return;
226 short version;
227 vsl_b_read(is, version);
228 switch (version)
229 {
230 case 1:
231 {
232 vsph_view_sphere<vsph_view_point<icam_view_metadata> > view_sphere;
233 vsl_b_read(is, view_sphere);
234 if (view_sphere_)
235 *view_sphere_ = view_sphere;
236 else
237 view_sphere_=new vsph_view_sphere<vsph_view_point<icam_view_metadata> >(view_sphere);
238 }
239 default:
240 std::cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, icam_view_sphere&)\n"
241 << " Unknown version number "<< version << '\n';
242 is.is().clear(std::ios::badbit); // Set an unrecoverable IO error on stream
243 break;
244 }
245 }
246
b_write(vsl_b_ostream & os) const247 void icam_view_sphere::b_write(vsl_b_ostream &os) const
248 {
249 vsl_b_write(os, version());
250 vsl_b_write(os, *view_sphere_);
251 }
252
vsl_b_read(vsl_b_istream & is,icam_view_sphere & sp)253 void vsl_b_read(vsl_b_istream &is, icam_view_sphere &sp)
254 {
255 sp.b_read(is);
256 }
257
vsl_b_write(vsl_b_ostream & os,icam_view_sphere const & sp)258 void vsl_b_write(vsl_b_ostream &os, icam_view_sphere const& sp)
259 {
260 sp.b_write(os);
261 }
262
vsl_b_read(vsl_b_istream & is,icam_view_sphere * sp)263 void vsl_b_read(vsl_b_istream &is, icam_view_sphere* sp)
264 {
265 sp->b_read(is);
266 }
267
vsl_b_write(vsl_b_ostream & os,const icam_view_sphere * sp)268 void vsl_b_write(vsl_b_ostream &os, const icam_view_sphere* sp)
269 {
270 sp->b_write(os);
271 }
272