00001
00002 #include "bmvv_cal_manager.h"
00003
00004
00005
00006
00007 #include <vcl_iostream.h>
00008 #include <vil/vil_image_view.h>
00009 #include <vil/vil_load.h>
00010 #include <vil/vil_save.h>
00011 #include <vil/vil_math.h>
00012 #include <vil/vil_new.h>
00013 #include <vnl/vnl_matrix_fixed.h>
00014 #include <vgl/algo/vgl_h_matrix_2d.h>
00015 #include <vgl/algo/vgl_p_matrix.h>
00016 #include <vgui/vgui.h>
00017 #include <vgui/vgui_key.h>
00018 #include <vgui/vgui_style.h>
00019 #include <vgui/vgui_macro.h>
00020 #include <vgui/vgui_dialog.h>
00021 #include <vgui/vgui_image_tableau.h>
00022 #include <vgui/vgui_viewer2D_tableau.h>
00023 #include <vgui/vgui_shell_tableau.h>
00024 #include <vgui/vgui_range_map_params.h>
00025 #include <vgui/vgui_projection_inspector.h>
00026 #include <bgui/bgui_image_tableau.h>
00027 #include <bgui/bgui_range_adjuster_tableau.h>
00028 #include <bgui/bgui_vsol_soview2D.h>
00029 #include <bgui/bgui_vtol2D_tableau.h>
00030 #include <bgui/bgui_picker_tableau.h>
00031 #include <brip/brip_vil_float_ops.h>
00032 #include <brct/brct_algos.h>
00033 #include <vsol/vsol_point_2d.h>
00034 #include <vsol/vsol_point_3d.h>
00035 #include <vsol/vsol_polygon_2d.h>
00036 #include <vsol/vsol_polygon_3d.h>
00037 #include <vpgl/vpgl_proj_camera.h>
00038 #include <vpgl/algo/vpgl_camera_compute.h>
00039 #include <vpgl/algo/vpgl_optimize_camera.h>
00040
00041 bmvv_cal_manager *bmvv_cal_manager::instance_ = 0;
00042
00043
00044
00045
00046 bmvv_cal_manager *bmvv_cal_manager::instance()
00047 {
00048 if (!instance_)
00049 {
00050 instance_ = new bmvv_cal_manager();
00051 instance_->init();
00052 }
00053 return bmvv_cal_manager::instance_;
00054 }
00055
00056
00057
00058
00059 bmvv_cal_manager::
00060 bmvv_cal_manager() : vgui_wrapper_tableau(), cam_(vgl_p_matrix<double>()),
00061 prev_cam_(vgl_p_matrix<double>())
00062 {
00063 corrs_.resize(0);
00064 corrs_valid_.resize(0);
00065 proj_image_pts_.resize(0);
00066 corr_sovs_.resize(0);
00067 }
00068
00069 bmvv_cal_manager::~bmvv_cal_manager()
00070 {
00071 delete instance_;
00072 }
00073
00074
00075
00076
00077
00078 void bmvv_cal_manager::init()
00079 {
00080 itab_ = bgui_image_tableau_new();
00081 btab_ = bgui_vtol2D_tableau_new(itab_);
00082 ptab_ = bgui_picker_tableau_new(btab_);
00083 vgui_viewer2D_tableau_sptr vtab = vgui_viewer2D_tableau_new(ptab_);
00084 vgui_shell_tableau_sptr shell = vgui_shell_tableau_new(vtab);
00085 this->add_child(shell);
00086 height_ = 0.0;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 bool bmvv_cal_manager::handle(const vgui_event &e)
00096 {
00097 vgui_projection_inspector proj;
00098 if (e.type == vgui_KEY_PRESS)
00099 {
00100 if (btab_)
00101 if (e.key == 'u')
00102 {
00103 btab_->deselect_all();
00104 return true;
00105 }
00106 }
00107 return this->child.handle(e);
00108 }
00109
00110
00111
00112
00113 void bmvv_cal_manager::quit()
00114 {
00115 vgui::quit();
00116 }
00117
00118
00119
00120
00121 void bmvv_cal_manager::load_image_file(vcl_string image_filename, bool )
00122 {
00123
00124 img_ = vil_load_image_resource(image_filename.c_str());
00125 if (!img_)
00126 {
00127 vcl_cout << "Null image resource - couldn't load from "
00128 << image_filename << '\n';
00129 return;
00130 }
00131 vgui_range_map_params_sptr rmps = range_params(img_);
00132 if (itab_)
00133 {
00134 itab_->set_image_resource(img_, rmps);
00135 return;
00136 }
00137 vcl_cout << "In bmvv_cal_manager::load_image_file() - null tableau\n";
00138 }
00139
00140 void bmvv_cal_manager::add_image(vil_image_resource_sptr const& image,
00141 vgui_range_map_params_sptr rmps,
00142 bool greyscale)
00143 {
00144 if (greyscale)
00145 {
00146 #if 0// do nothing right now
00147 vil1_memory_image_of<unsigned char> temp1 =
00148 brip_vil1_float_ops::convert_to_grey(image);
00149 img_ = temp1;
00150 #endif
00151 }
00152 else
00153 img_ = image;
00154
00155 if (itab_)
00156 {
00157 itab_->set_image_resource(img_, rmps);
00158 itab_->post_redraw();
00159 return;
00160 }
00161 vcl_cout << "In bmvv_cal_manager::load_image() - null tableau\n";
00162 }
00163
00164
00165
00166
00167 void bmvv_cal_manager::load_image()
00168 {
00169 static bool greyscale = false;
00170 vgui_dialog load_image_dlg("Load Image");
00171 static vcl_string image_filename = "";
00172 static vcl_string ext = "*.*";
00173 load_image_dlg.file("Image Filename:", ext, image_filename);
00174 load_image_dlg.checkbox("greyscale ", greyscale);
00175 if (!load_image_dlg.ask())
00176 return;
00177 vil_image_resource_sptr temp = vil_load_image_resource(image_filename.c_str());
00178 vgui_range_map_params_sptr rmps = range_params(temp);
00179 this->add_image(temp, rmps, greyscale);
00180 }
00181
00182 void bmvv_cal_manager::save_image()
00183 {
00184 vgui_dialog file_dialog("Save Image");
00185 static vcl_string image_file;
00186 static vcl_string ext = "tif";
00187 static vcl_string type = "tiff";
00188 static bool byte = false;
00189 file_dialog.file("Image Filename:", ext, image_file);
00190 file_dialog.field("Image Format: ", type);
00191 file_dialog.checkbox("Convert to byte image", byte);
00192 if (!file_dialog.ask())
00193 return;
00194 vil_image_resource_sptr img = itab_->get_image_resource();
00195 if (!img)
00196 {
00197 vcl_cerr << "Null image in bmvv_cal_manager::save_image\n";
00198 return;
00199 }
00200 vil_image_resource_sptr save_image = img;
00201 if (byte)
00202 {
00203 vil_image_view<unsigned char> byte_view = brip_vil_float_ops::convert_to_byte(img);
00204 save_image = vil_new_image_resource_of_view(byte_view);
00205 }
00206 if (!vil_save_image_resource(save_image, image_file.c_str(), type.c_str() ))
00207 vcl_cerr << "bmvv_cal_manager::save_image operation failed\n";
00208 }
00209
00210 void bmvv_cal_manager::adjust_contrast()
00211 {
00212 if (!itab_)
00213 return;
00214 bgui_range_adjuster_tableau_sptr h= bgui_range_adjuster_tableau_new(itab_);
00215 h->set_hardware(true);
00216 h->update();
00217 vgui_viewer2D_tableau_sptr v = vgui_viewer2D_tableau_new(h);
00218 vgui_shell_tableau_sptr s = vgui_shell_tableau_new(v);
00219
00220 vgui_dialog contrast("Histogram Range Adjuster");
00221 contrast.inline_tableau(s, 280, 200);
00222 if (!contrast.ask())
00223 return;
00224 }
00225
00226
00227
00228
00229 void bmvv_cal_manager::clear_display()
00230 {
00231 if (btab_)
00232 btab_->clear_all();
00233 else
00234 vcl_cout << "In bmvv_cal_manager::clear_display() - null tableau\n";
00235 }
00236
00237
00238
00239
00240 void bmvv_cal_manager::clear_selected()
00241 {
00242 if (btab_)
00243 btab_->clear_all();
00244 }
00245
00246 void bmvv_cal_manager::draw_corr_point(const float x, const float y)
00247 {
00248 if (!btab_)
00249 return;
00250 btab_->set_point_radius(5.0f);
00251 btab_->set_foreground(0.0f, 1.0f, 0.0f);
00252 btab_->add_point(x, y);
00253 btab_->post_redraw();
00254 }
00255
00256
00257
00258 vgui_range_map_params_sptr bmvv_cal_manager::
00259 range_params(vil_image_resource_sptr const& image)
00260 {
00261 float gamma = 1.0;
00262 bool invert = false;
00263 bool gl_map = false;
00264 bool cache = true;
00265 unsigned min = 0, max = 255;
00266 if (image->pixel_format()==VIL_PIXEL_FORMAT_BYTE)
00267 {
00268 vil_image_view<unsigned char> temp = image->get_view();
00269 unsigned char vmin=0, vmax=255;
00270 vil_math_value_range<unsigned char>(temp, vmin, vmax);
00271 min = static_cast<unsigned>(vmin);
00272 max = static_cast<unsigned>(vmax);
00273 return new vgui_range_map_params(min, max, gamma, invert,
00274 gl_map, cache);
00275 }
00276 if (image->pixel_format()==VIL_PIXEL_FORMAT_UINT_16)
00277 {
00278 vil_image_view<unsigned short> temp = image->get_view();
00279 unsigned short vmin=0, vmax=60000;
00280 vil_math_value_range<unsigned short>(temp, vmin, vmax);
00281 min = static_cast<unsigned>(vmin);
00282 max = static_cast<unsigned>(vmax);
00283 gl_map = true;
00284 return new vgui_range_map_params(min, max, gamma, invert,
00285 gl_map, cache);
00286 }
00287 vcl_cout << "Image pixel format not handled\n";
00288 return new vgui_range_map_params(0, 255, gamma, invert,
00289 gl_map, cache);
00290 }
00291
00292 void bmvv_cal_manager::set_range_params()
00293 {
00294 if (!itab_||!itab_->get_image_resource())
00295 return;
00296 static double min = 0.0, max = 255;
00297 static float gamma = 1.0;
00298 static bool invert = false;
00299 static bool gl_map = false;
00300 static bool cache = false;
00301 vgui_dialog range_dlg("Set Range Map Params");
00302 range_dlg.field("Range min:", min);
00303 range_dlg.field("Range max:", max);
00304 range_dlg.field("Gamma:", gamma);
00305 range_dlg.checkbox("Invert:", invert);
00306 range_dlg.checkbox("Use GL Mapping", gl_map);
00307 range_dlg.checkbox("Cache Pixels", cache);
00308 if (!range_dlg.ask())
00309 return;
00310 vil_image_resource_sptr img = itab_->get_image_resource();
00311 unsigned n_components = img->nplanes();
00312 vgui_range_map_params_sptr rmps;
00313 if (n_components == 1)
00314 rmps= new vgui_range_map_params(min, max, gamma, invert,
00315 gl_map, cache);
00316 else if (n_components == 3)
00317 rmps = new vgui_range_map_params(min, max, min, max, min, max,
00318 gamma, gamma, gamma, invert,
00319 gl_map, cache);
00320 else
00321 rmps = 0;
00322 itab_->set_mapping(rmps);
00323 }
00324
00325 void bmvv_cal_manager::load_image_and_camera()
00326 {
00327 static bool greyscale = false;
00328 static vcl_string cam_file = "";
00329 static vcl_string cam_ext = "*.cam";
00330 static vcl_string image_file = "";
00331 static vcl_string ext = "*.*";
00332 vgui_dialog image_cam_dlg("Read Image and Cam");
00333 image_cam_dlg.file("Image Filename:", ext, image_file);
00334 image_cam_dlg.file("Camera File", cam_ext, cam_file);
00335 image_cam_dlg.checkbox("greyscale ", greyscale);
00336 if (!image_cam_dlg.ask())
00337 return;
00338 vil_image_resource_sptr temp = vil_load_image_resource(image_file.c_str());
00339 vgui_range_map_params_sptr rmps = range_params(temp);
00340 this->add_image(temp, rmps, greyscale);
00341 vcl_ifstream cam_istr(cam_file.c_str());
00342 cam_istr >> cam_;
00343 vcl_cout << "Read Camera " << cam_ << '\n';
00344 this->project_world();
00345 }
00346
00347 void bmvv_cal_manager::load_corrs()
00348 {
00349 vgui_dialog corr_dlg("Load Correspondences");
00350 static vcl_string corr_file = "";
00351 static vcl_string corr_ext = "*.cm";
00352 corr_dlg.file("Correspondence File", corr_ext, corr_file);
00353 if (!corr_dlg.ask())
00354 return;
00355 vcl_ifstream corr_istr(corr_file.c_str());
00356 this->clear_correspondences();
00357 world_.clear();
00358 world_.resize(0);
00359 if (!brct_algos::read_target_corrs(corr_istr, corrs_valid_, corrs_, world_))
00360 {
00361 vcl_cout << "Failed to read correspondences\n";
00362 return ;
00363 }
00364 if (!btab_)
00365 return;
00366 btab_->clear_all();
00367 this->project_world();
00368
00369 }
00370
00371 void bmvv_cal_manager::save_corrs()
00372 {
00373 vgui_dialog corr_dlg("Save Correspondences");
00374 static vcl_string corr_file = "";
00375 static vcl_string corr_ext = "*.cm";
00376 corr_dlg.file("Correspondence File", corr_ext, corr_file);
00377 if (!corr_dlg.ask())
00378 return;
00379 vcl_ofstream corr_ostr(corr_file.c_str());
00380 if (!brct_algos::write_corrs(corr_ostr, corrs_valid_, corrs_, world_))
00381 {
00382 vcl_cout << "Failed to write correspondences\n";
00383 return ;
00384 }
00385 }
00386
00387 void bmvv_cal_manager::save_camera()
00388 {
00389 vgui_dialog cam_dlg("Save Camera");
00390 static vcl_string cam_file = "";
00391 static vcl_string cam_ext = "*.cam";
00392 static bool target = false;
00393 cam_dlg.file("Camera File", cam_ext, cam_file);
00394 cam_dlg.checkbox("Target?", target);
00395 if (!cam_dlg.ask())
00396 return;
00397 vcl_ofstream cam_ostr(cam_file.c_str());
00398 if (!cam_ostr)
00399 {
00400 vcl_cout << "Bad camera file\n";
00401 return;
00402 }
00403 if (!target) {
00404 cam_ostr << cam_;
00405 cam_ostr.close();
00406 return;
00407 }
00408 brct_algos::write_target_camera(cam_ostr, cam_.get_matrix());
00409 }
00410
00411 void bmvv_cal_manager::set_identity_camera()
00412 {
00413 vnl_matrix_fixed<double,3,4> M;
00414 M[0][0] = 1.0; M[0][1] = 0.0; M[0][2] = 0.0; M[0][3] = 0.0;
00415 M[1][0] = 0.0; M[1][1] = 1.0; M[1][2] = 0.0; M[1][3] = 0.0;
00416 M[2][0] = 0.0; M[2][1] = 0.0; M[2][2] = 0.0; M[2][3] = 1.0;
00417 cam_ = vgl_p_matrix<double>(M);
00418 }
00419
00420 void bmvv_cal_manager::load_world()
00421 {
00422 vgui_dialog world_dlg("Load World Points3D");
00423 static vcl_string world_file = "";
00424 static vcl_string world_ext = "*.wd";
00425 world_dlg.file("World Point File", world_ext, world_file);
00426 if (!world_dlg.ask())
00427 return;
00428 vcl_ifstream world_istr(world_file.c_str());
00429 this->clear_correspondences();
00430 this->clear_world();
00431 if (!brct_algos::read_world(world_istr, world_, polys_, indexed_face_set_))
00432 {
00433 vcl_cout << "Failed to read world\n";
00434 return ;
00435 }
00436
00437 if (!btab_)
00438 return;
00439 btab_->clear();
00440
00441 int n = world_.size();
00442 corrs_.resize(n, vgl_point_2d<double>(0,0));
00443 corr_sovs_.resize(n, (vgui_soview2D_point*)0);
00444 corrs_valid_.resize(n, false);
00445 this->project_world();
00446 }
00447
00448 void bmvv_cal_manager::save_world()
00449 {
00450 vgui_dialog world_dlg("Save World");
00451 static vcl_string world_file = "";
00452 static vcl_string world_ext = "*.wd";
00453 world_dlg.file("World File", world_ext, world_file);
00454 if (!world_dlg.ask())
00455 return;
00456 vcl_ofstream world_ostr(world_file.c_str());
00457 brct_algos::write_world(world_ostr, world_, indexed_face_set_);
00458 }
00459
00460 void bmvv_cal_manager::save_world_ply2()
00461 {
00462 vgui_dialog world_dlg("Save World Ply2");
00463 static vcl_string world_file = "";
00464 static vcl_string world_ext = "*.ply2";
00465 world_dlg.file("Ply2 File", world_ext, world_file);
00466 if (!world_dlg.ask())
00467 return;
00468 vcl_ofstream world_ostr(world_file.c_str());
00469 brct_algos::write_world_ply2(world_ostr, world_, indexed_face_set_);
00470 }
00471
00472 bool bmvv_cal_manager::draw_correspondences()
00473 {
00474 if (!btab_)
00475 return false;
00476 btab_->set_point_radius(5.0f);
00477 btab_->set_foreground(0.0f, 1.0f, 1.0f);
00478 unsigned i = 0;
00479 for (vcl_vector<vgl_point_2d<double> >::iterator pit = corrs_.begin();
00480 pit != corrs_.end(); ++pit, ++i)
00481 if (corrs_valid_[i])
00482 corr_sovs_.push_back(btab_->add_point((*pit).x(), (*pit).y()));
00483 else
00484 corr_sovs_.push_back((vgui_soview2D_point*)0);
00485 btab_->post_redraw();
00486 return true;
00487 }
00488
00489 void bmvv_cal_manager::read_world_ply2()
00490 {
00491 vgui_dialog world_dlg("Read World Ply2");
00492 static vcl_string world_file = "";
00493 static vcl_string world_ext = "*.ply2";
00494 world_dlg.file("Ply2 File", world_ext, world_file);
00495 if (!world_dlg.ask())
00496 return;
00497 vcl_ifstream world_istr(world_file.c_str());
00498 brct_algos::read_world_ply2(world_istr, world_, polys_, indexed_face_set_);
00499 this->project_world();
00500 }
00501
00502 void bmvv_cal_manager::clear_correspondences()
00503 {
00504 if (!btab_)
00505 return;
00506 btab_->clear_all();
00507 corrs_.clear();
00508 corr_sovs_.clear();
00509 corrs_valid_.clear();
00510 corrs_.resize(0);
00511 corrs_valid_.resize(0);
00512 corr_sovs_.resize(0);
00513 }
00514
00515 bool bmvv_cal_manager::draw_projected_world_points()
00516 {
00517 if (!btab_)
00518 return false;
00519 int i = 0;
00520 point_3d_map_.clear();
00521 btab_->set_point_radius(5.0f);
00522 btab_->set_foreground(1.0f, 1.0f, 0.2f);
00523 for (vcl_vector<vgl_point_2d<double> >::iterator pit = proj_image_pts_.begin();
00524 pit != proj_image_pts_.end(); pit++, ++i)
00525 {
00526 vgui_soview2D_point* sov = btab_->add_point((*pit).x(), (*pit).y());
00527 int id = sov->get_id();
00528 point_3d_map_[id]=i;
00529 }
00530 btab_->post_redraw();
00531 return true;
00532 }
00533
00534
00535 int bmvv_cal_manager::get_selected_proj_world_pt(vgl_point_2d<double>& pt)
00536 {
00537 if (!btab_)
00538 return -1;
00539 vcl_vector<unsigned> ids = btab_->get_selected();
00540
00541 int n = ids.size();
00542 if (!n)
00543 {
00544 vcl_cout << "Nothing selected\n";
00545 return -1;
00546 }
00547 unsigned int i = point_3d_map_[ids[n-1]];
00548 if (i<proj_image_pts_.size())
00549 {
00550 pt = proj_image_pts_[i];
00551 return i;
00552 }
00553 vcl_cout << "Bogus correspondence\n";
00554 return -1;
00555 }
00556
00557 void bmvv_cal_manager::pick_correspondence()
00558 {
00559 if (!world_.size())
00560 {
00561 vcl_cout << "Can't pick correspondence - null 3D world\n";
00562 return;
00563 }
00564 vgl_point_2d<double> pt;
00565 int id = this->get_selected_proj_world_pt(pt);
00566 if (id<0)
00567 return;
00568 vcl_cout << "Projected world point " << pt << '\n';
00569 if (!ptab_)
00570 {
00571 vcl_cout << "Can't pick correspondence - null picker tableau\n";
00572 return;
00573 }
00574 ptab_->set_color(0.0f, 1.0f, 1.0f);
00575 ptab_->set_line_width(3.0f);
00576 float x, y;
00577 ptab_->anchored_pick_point(pt.x(), pt.y(), &x, &y);
00578 corrs_[id].set(x, y);
00579 corrs_valid_[id]=true;
00580 ptab_->set_color();
00581 ptab_->set_line_width();
00582
00583 if (!btab_)
00584 return;
00585 btab_->set_foreground(0.0f, 1.0f, 1.0f);
00586 btab_->set_point_radius(5.0);
00587 if (!corr_sovs_[id])
00588 corr_sovs_[id]=btab_->add_point(x, y);
00589 else {
00590 corr_sovs_[id]->x = x;
00591 corr_sovs_[id]->y = y;
00592 }
00593 btab_->post_redraw();
00594 }
00595
00596 void bmvv_cal_manager::remove_correspondence()
00597 {
00598 if (!world_.size())
00599 {
00600 vcl_cout << "Can't remove correspondence - null 3D world\n";
00601 return;
00602 }
00603 vgl_point_2d<double> pt;
00604 int id = this->get_selected_proj_world_pt(pt);
00605 if (id<0)
00606 return;
00607 corrs_[id].set(0, 0);
00608 corrs_valid_[id]=false;
00609 corr_sovs_[id]=(vgui_soview2D_point*)0;
00610 if (!btab_)
00611 {
00612 vcl_cout << "Correspondence removal aborted in progress- null btab\n";
00613 return;
00614 }
00615 this->project_world();
00616
00617 }
00618
00619 void bmvv_cal_manager::pick_vertical()
00620 {
00621 ptab_->set_color(0.0f, 1.0f, 0.0f);
00622 ptab_->set_line_width(3.0f);
00623 float x1, y1,x2, y2;
00624 ptab_->pick_line(&x1, &y1, &x2, &y2);
00625 vgl_point_2d<double> p1(x1, y1), p2(x2,y2);
00626 vgl_line_segment_2d<double> vertical(p1, p2);
00627 verticals_.push_back(vertical);
00628 ptab_->set_color();
00629 ptab_->set_line_width();
00630 if (!btab_)
00631 return;
00632 btab_->set_foreground(0.0f, 1.0f, 0.0f);
00633 btab_->add_line(x1,y1,x2,y2);
00634 btab_->post_redraw();
00635 }
00636
00637 void bmvv_cal_manager::project_world()
00638 {
00639 if (!btab_)
00640 {
00641 vcl_cout << "Can't project world - null btab\n";
00642 return;
00643 }
00644 btab_->clear_all();
00645 brct_algos::project(world_, cam_, proj_image_pts_);
00646 this->draw_projected_world_points();
00647 this->draw_polygons_3d(false, 0.0f, 1.0f, 0.0f);
00648 this->draw_correspondences();
00649 }
00650
00651 namespace
00652 {
00653
00654
00655 void flip_camera(vpgl_perspective_camera<double> &camera,
00656 const vcl_vector< vgl_homg_point_3d<double> >& world_hpts)
00657 {
00658 vgl_vector_3d<double> centroid(0.0, 0.0, 0.0);
00659 unsigned int num_behind = 0;
00660 for (unsigned i = 0; i<world_hpts.size(); ++i){
00661 if (camera.is_behind_camera(world_hpts[i])){
00662 vgl_point_3d<double> p(world_hpts[i]);
00663 centroid += vgl_vector_3d<double>(p.x(),p.y(),p.z());
00664 ++num_behind;
00665 }
00666 }
00667 centroid /= num_behind;
00668
00669 vgl_point_3d<double> C = camera.get_camera_center();
00670 vcl_cout << "initial center: "<< C<<vcl_endl;
00671 C += 2*(vgl_point_3d<double>(centroid.x(),centroid.y(),centroid.z())-C);
00672 camera.set_camera_center(C);
00673 vcl_cout << "new center: " <<C<<vcl_endl;
00674 }
00675
00676 };
00677
00678 void bmvv_cal_manager::solve_camera()
00679 {
00680 static bool planar = false;
00681 static bool deg_planar = false;
00682 static bool optimize = true;
00683 static bool restore = false;
00684 vgui_dialog read_homg_dlg("Solve Camera");
00685 read_homg_dlg.checkbox("Planar Camera Only? ", planar);
00686 read_homg_dlg.checkbox("Mostly Planar Camera? ", deg_planar);
00687 read_homg_dlg.checkbox("Optimize? ", optimize);
00688 read_homg_dlg.checkbox("Restore Previous Camera? ", restore);
00689 if (!read_homg_dlg.ask())
00690 return;
00691 if (restore)
00692 {
00693 cam_=prev_cam_;
00694 return;
00695 }
00696
00697 if (planar || deg_planar)
00698 {
00699 vcl_vector<double> image_y;
00700 vcl_vector< vgl_point_2d<double> > zero_Z_image_corr;
00701 vcl_vector< vgl_point_3d<double> > zero_Z_pts;
00702 vcl_vector< vgl_point_3d<double> > non_zero_Z_pts;
00703 unsigned int n = world_.size();
00704 for (unsigned i = 0; i<n; i++)
00705 {
00706 if (!corrs_valid_[i])
00707 continue;
00708 if (vcl_fabs(world_[i].z()) < 0.01)
00709 {
00710 zero_Z_pts.push_back(world_[i]);
00711 zero_Z_image_corr.push_back(corrs_[i]);
00712 }
00713 else
00714 {
00715 image_y.push_back(corrs_[i].y());
00716 non_zero_Z_pts.push_back(world_[i]);
00717 }
00718 }
00719 vgl_h_matrix_2d<double> H;
00720 if (!brct_algos::homography(zero_Z_pts, zero_Z_image_corr, H, optimize))
00721 {
00722 vcl_cout << "Linear SVD solve for homography failed\n";
00723 return;
00724 }
00725
00726 prev_cam_ = cam_;
00727 if (!planar)
00728 cam_= brct_algos::p_from_h(H,image_y, non_zero_Z_pts);
00729 else
00730 cam_= brct_algos::p_from_h(H);
00731 }
00732 else
00733 {
00734 vcl_vector< vgl_homg_point_2d<double> > image_hpts;
00735 vcl_vector< vgl_homg_point_3d<double> > world_hpts;
00736 unsigned int n = world_.size();
00737 for (unsigned i = 0; i<n; i++)
00738 {
00739 if (!corrs_valid_[i])
00740 continue;
00741 image_hpts.push_back(vgl_homg_point_2d<double>(corrs_[i]));
00742 world_hpts.push_back(vgl_homg_point_3d<double>(world_[i]));
00743 }
00744 vpgl_proj_camera<double> camera;
00745 vpgl_proj_camera_compute::compute(image_hpts,world_hpts,camera);
00746 prev_cam_ = cam_;
00747 cam_ = vgl_p_matrix<double>(camera.get_matrix());
00748
00749 vpgl_perspective_camera<double> p_camera;
00750 if (optimize && vpgl_perspective_decomposition(camera.get_matrix(),p_camera)){
00751 vcl_vector< vgl_point_2d<double> > image_pts;
00752 unsigned int num_behind = 0;
00753 for (unsigned i = 0; i<image_hpts.size(); i++){
00754 if (p_camera.is_behind_camera(world_hpts[i]))
00755 ++num_behind;
00756 image_pts.push_back(image_hpts[i]);
00757 }
00758 if (num_behind > world_hpts.size()/2){
00759 vcl_cout << "Majority of points behind camera, flipping" << vcl_endl;
00760 flip_camera(p_camera, world_hpts);
00761 }
00762 p_camera = vpgl_optimize_camera::opt_orient_pos_cal(p_camera, world_hpts, image_pts);
00763 cam_ = vgl_p_matrix<double>(p_camera.get_matrix());
00764 }
00765 }
00766
00767 if (!btab_)
00768 return;
00769 btab_->clear_all();
00770 this->project_world();
00771
00772 }
00773
00774
00775 void bmvv_cal_manager::
00776 draw_vsol_points(const int cam, vcl_vector<vsol_point_2d_sptr> const & points,
00777 bool clear, const float r, const float g, const float b)
00778 {
00779 if (!btab_)
00780 {
00781 vcl_cout << "In bmvv_cal_manager::draw_vsol_points(..) -"
00782 << " null btol tableau for pane " << cam << vcl_endl;
00783 return;
00784 }
00785 if (clear)
00786 btab_->clear_all();
00787 vgui_style_sptr style = vgui_style::new_style(r, g, b, 3, 0);
00788 for (vcl_vector<vsol_point_2d_sptr>::const_iterator pit = points.begin();
00789 pit != points.end(); pit++)
00790 btab_->add_vsol_point_2d(*pit, style);
00791 }
00792
00793 void bmvv_cal_manager::
00794 draw_vsol_point(const int cam, vsol_point_2d_sptr const & point,
00795 bool clear, const float r, const float g, const float b)
00796 {
00797 if (!btab_)
00798 {
00799 vcl_cout << "In bmvv_cal_manager::draw_vsol_point(..) -"
00800 << " null btol tableau for pane " << cam << vcl_endl;
00801 return;
00802 }
00803 if (clear)
00804 btab_->clear_all();
00805 vgui_style_sptr style = vgui_style::new_style(r, g, b, 3, 0);
00806 btab_->add_vsol_point_2d(point,style);
00807 }
00808
00809
00810 void bmvv_cal_manager::compute_ransac_homography()
00811 {
00812 vgui_dialog read_homg_dlg("Read Correspondence File");
00813 static vcl_string corr_filename = "";
00814 static vcl_string corr_ext = "*.cm";
00815 static vcl_string cam_filename = "";
00816 static vcl_string cam_ext = "*.cam";
00817 static bool show_projected_points = true;
00818 static bool optimize = true;
00819 vcl_vector<vcl_string> choices;
00820 static int choice=0;
00821 choices.push_back("Linear SVD");
00822 choices.push_back("RANSAC");
00823 choices.push_back("MUSE");
00824 read_homg_dlg.file("TargetJr correspondence file", corr_ext, corr_filename);
00825 read_homg_dlg.file("TargetJr camera file", cam_ext, cam_filename);
00826 read_homg_dlg.checkbox("Show Projected Points ",show_projected_points);
00827 read_homg_dlg.choice("Homography Algo.", choices, choice);
00828 read_homg_dlg.checkbox("Optimize? ", optimize);
00829 if (!read_homg_dlg.ask())
00830 return;
00831 if (corr_filename == ""||cam_filename == "")
00832 {
00833 vcl_cout << "Need a file name\n";
00834 return;
00835 }
00836
00837 this->clear_display();
00838 vcl_ifstream istr(corr_filename.c_str());
00839 vcl_ofstream ostr(cam_filename.c_str());
00840 vcl_string target_file = cam_filename + "-target";
00841 vcl_ofstream ostr_tar(target_file.c_str());
00842 vcl_vector<bool> valid;
00843 vcl_vector<vgl_point_2d<double> > image_points;
00844 vcl_vector<vgl_point_3d<double> > world_points;
00845 if (!brct_algos::read_target_corrs(istr, valid, image_points, world_points))
00846 {
00847 vcl_cout << "Failed to read correspondences\n";
00848 return;
00849 }
00850 bool show = show_projected_points;
00851
00852 vgl_h_matrix_2d<double> H;
00853 switch (choice)
00854 {
00855 case 0:
00856 if (!brct_algos::homography(world_points, image_points, H, optimize))
00857 show = false;
00858 break;
00859 case 1:
00860 if (!brct_algos::homography_ransac(world_points, image_points, H, optimize))
00861 show = false;
00862 break;
00863 case 2:
00864 if (!brct_algos::homography_muse(world_points, image_points, H, optimize))
00865 show = false;
00866 break;
00867 }
00868 vcl_vector<vgl_point_2d<double> > proj_image_points;
00869 vgl_p_matrix<double> P = brct_algos::p_from_h(H);
00870 brct_algos::project(world_points, P, proj_image_points);
00871
00872 if (!btab_)
00873 return;
00874 vgui_style_sptr r_style = vgui_style::new_style(1.0, 0.0, 0.0, 5, 0);
00875 vgui_style_sptr g_style = vgui_style::new_style(0.0, 1.0, 0.0, 5, 0);
00876 for (unsigned int i = 0; i<world_points.size(); i++)
00877 {
00878 vgl_point_2d<double> ip = image_points[i];
00879 vgl_point_2d<double> pip = proj_image_points[i];
00880 vsol_point_2d_sptr vip = new vsol_point_2d(ip.x(),ip.y());
00881 vsol_point_2d_sptr vpip = new vsol_point_2d(pip.x(),pip.y());
00882 vcl_cout << ip << " == " << pip << vcl_endl;
00883 btab_->add_vsol_point_2d(vip,r_style);
00884 if (show) btab_->add_vsol_point_2d(vpip,g_style);
00885 }
00886 btab_->post_redraw();
00887
00888
00889 ostr << P;
00890
00891 brct_algos::write_target_camera(ostr_tar, P.get_matrix());
00892 }
00893
00894
00895 void bmvv_cal_manager::map_image_to_world()
00896 {
00897 vil_image_resource_sptr img = itab_->get_image_resource();
00898 if (!img)
00899 return;
00900 vil_image_resource_sptr world_image =
00901 brct_algos::map_image_to_world(img, cam_);
00902 if (world_image)
00903 {
00904 vgui_range_map_params_sptr rmps = range_params(world_image);
00905 this->add_image(world_image, rmps);
00906 }
00907 }
00908
00909 void bmvv_cal_manager::save_constraints()
00910 {
00911 vgui_dialog cnst_dlg("Save Constraints");
00912 static vcl_string con_file = "";
00913 static vcl_string con_ext = "*.con";
00914 cnst_dlg.file("Constraint File", con_ext, con_file);
00915 if (!cnst_dlg.ask())
00916 return;
00917 vcl_ofstream con_ostr(con_file.c_str());
00918 if (!con_ostr)
00919 {
00920 vcl_cout << "Bad constraint file\n";
00921 return;
00922 }
00923 if (!brct_algos::save_constraint_file(corrs_, corrs_valid_, world_, verticals_, con_ostr))
00924 {
00925 vcl_cout << "Couldn't save constraints\n";
00926 return;
00927 }
00928 }
00929
00930
00931
00932 void bmvv_cal_manager::add_poly_vertices_to_world_pts(vsol_polygon_3d_sptr const& poly)
00933 {
00934 unsigned nv = poly->size();
00935 vcl_vector<unsigned> vert_indices(nv);
00936 for (unsigned i = 0; i<nv; ++i)
00937 {
00938 vsol_point_3d_sptr v3d = poly->vertex(i);
00939 vgl_point_3d<double> p(v3d->x(), v3d->y(), v3d->z());
00940 world_.push_back(p);
00941 vert_indices[i]=world_.size()-1;
00942 }
00943 indexed_face_set_.push_back(vert_indices);
00944 }
00945
00946
00947 void bmvv_cal_manager::confirm_polygon()
00948 {
00949 if (!new_poly_)
00950 return;
00951 add_poly_vertices_to_world_pts(new_poly_);
00952 polys_.push_back(new_poly_);
00953 this->project_world();
00954 }
00955
00956 void bmvv_cal_manager::pick_polygon()
00957 {
00958 vsol_polygon_2d_sptr poly;
00959 ptab_->pick_polygon(poly);
00960 new_poly_ = brct_algos::back_project(poly, cam_, height_);
00961 this->draw_vsol_polygon_3d(new_poly_, false, 1.0f, 0.0f, 1.0f);
00962 btab_->post_redraw();
00963 }
00964
00965 void bmvv_cal_manager::draw_vsol_polygon_3d(