00001 #include "brct_plane_sweeper.h"
00002
00003
00004 #include <vcl_fstream.h>
00005 #include <vcl_cmath.h>
00006 #include <vbl/vbl_array_2d.h>
00007 #include <vnl/vnl_numeric_traits.h>
00008 #include <vnl/vnl_matrix_fixed.h>
00009 #include <vgl/vgl_homg_point_2d.h>
00010 #include <vgl/vgl_point_2d.h>
00011 #include <vsol/vsol_box_2d.h>
00012 #include <vsol/vsol_point_2d.h>
00013 #include <vsol/vsol_point_3d.h>
00014 #include <bbas/bsol/bsol_algs.h>
00015 #include <sdet/sdet_harris_detector.h>
00016 #include <brip/brip_vil1_float_ops.h>
00017 #include <brct/brct_algos.h>
00018
00019 brct_plane_sweeper::brct_plane_sweeper(brct_plane_sweeper_params const& sp)
00020 : brct_plane_sweeper_params(sp), n_planes_(0), n_cams_(0), del_(1.f),
00021 to_cam_(0), pindx_(192,256,vsol_box_2d_sptr(0))
00022 {
00023 }
00024
00025 brct_plane_sweeper::~brct_plane_sweeper()
00026 {
00027 }
00028
00029 static vgl_h_matrix_2d<double> translation_h(const double tx, const double ty)
00030 {
00031 vnl_matrix_fixed<double,3, 3> M;
00032 M.fill(0.0);
00033 M[0][0]=1.0; M[0][2]=tx;
00034 M[1][1]=1.0; M[1][2]=ty;
00035 M[2][2]=1.0;
00036 vgl_h_matrix_2d<double> H(M);
00037 return H;
00038 }
00039
00040
00041 static vgl_h_matrix_2d<double> normalize_h(vgl_h_matrix_2d<double> const& H)
00042 {
00043 vnl_matrix_fixed<double,3, 3> M = H.get_matrix();
00044 double s = M[2][2];
00045 if (vcl_fabs(s)<1e-06)
00046 {
00047 vcl_cout << "In brct_plane_sweeper - singular homography\n";
00048 return H;
00049 }
00050 for (int r = 0; r<3; r++)
00051 for (int c = 0; c<3; c++)
00052 M[r][c]/=s;
00053 vgl_h_matrix_2d<double> Hn(M);
00054 return Hn;
00055 }
00056
00057 static vgl_h_matrix_2d<double> translate_h(vgl_h_matrix_2d<double> const& H,
00058 const double tx, const double ty)
00059 {
00060 vnl_matrix_fixed<double,3, 3> M = H.get_matrix(), Mt;
00061 Mt.fill(0.0);
00062 Mt[0][0]=1; Mt[1][1]=1; Mt[2][2]=1;
00063 Mt[0][2] = tx;
00064 Mt[1][2] = ty;
00065 vgl_h_matrix_2d<double> Ht(Mt*M);
00066 return Ht;
00067 }
00068
00069 vcl_vector<vsol_point_2d_sptr> brct_plane_sweeper::
00070 project_corners(vgl_h_matrix_2d<double> const & H,
00071 vcl_vector<vsol_point_2d_sptr> const& corners)
00072 {
00073 vcl_vector<vsol_point_2d_sptr> out;
00074 for (vcl_vector<vsol_point_2d_sptr>::const_iterator pit = corners.begin();
00075 pit != corners.end(); pit++)
00076 {
00077 vgl_homg_point_2d<double> p((*pit)->x(), (*pit)->y()), hp;
00078 hp = H(p);
00079 vgl_point_2d<double> np(hp);
00080 vsol_point_2d_sptr temp = new vsol_point_2d(np);
00081 out.push_back(temp);
00082 }
00083 return out;
00084 }
00085
00086 bool brct_plane_sweeper::read_homographies(vcl_string const& homography_file)
00087 {
00088 vcl_ifstream is(homography_file.c_str());
00089 if (!is)
00090 {
00091 vcl_cout << "In brct_plane_calibrator::write_homographies -"
00092 << " could not open file " << homography_file << '\n';
00093 return false;
00094 }
00095 vcl_string s;
00096 is >> s;
00097 if (!(s=="N_PLANES:"))
00098 {
00099 vcl_cout << "Parse error\n";
00100 return false;
00101 }
00102 is >> n_planes_;
00103 is >> s;
00104 if (!(s=="N_CAMS:"))
00105 {
00106 vcl_cout << "Parse error\n";
00107 return false;
00108 }
00109 is >> n_cams_;
00110
00111 z_.resize(n_planes_);
00112 homographies_.resize(n_planes_);
00113 for (int i=0; i<n_planes_; i++)
00114 homographies_[i].resize(n_cams_);
00115 images_.resize(n_cams_);
00116 smooth_images_.resize(n_cams_);
00117 harris_corners_.resize(n_cams_);
00118
00119 int p = 0, c =0;
00120 double z=0;
00121 vnl_matrix_fixed<double, 3, 3> M;
00122 for (int plane = 0; plane < n_planes_; plane++)
00123 for (int cam = 0; cam < n_cams_; cam++)
00124 {
00125 is >> s;
00126 if (!(s=="PLANE:"))
00127 {
00128 vcl_cout << "Parse error\n";
00129 return false;
00130 }
00131 is >> p;
00132 is >> s;
00133 if (!(s=="Z:"))
00134 {
00135 vcl_cout << "Parse error\n";
00136 return false;
00137 }
00138 is >> z;
00139 z_[plane]=z;
00140 is >> s;
00141 if (!(s=="CAM:"))
00142 {
00143 vcl_cout << "Parse error\n";
00144 return false;
00145 }
00146 is >> c;
00147 is >> M;
00148 vgl_h_matrix_2d<double> H(M);
00149 vgl_h_matrix_2d<double> Hn = normalize_h(H);
00150 homographies_[plane][cam]=Hn;
00151 }
00152 homographies_valid_=true;
00153 return true;
00154 }
00155
00156 bool brct_plane_sweeper::set_image(const int cam, vil1_image const& image)
00157 {
00158 if (cam>=n_cams_)
00159 {
00160 vcl_cout << "In brct_plane_sweeper::set_image - "
00161 << " cam index out of bounds\n";
00162 return false;
00163 }
00164 if (!image)
00165 {
00166 vcl_cout << "In brct_plane_sweeper::set_image - "
00167 << " null image\n";
00168 return false;
00169 }
00170 images_[cam]=image;
00171 vil1_memory_image_of<float> flt_image =
00172 brip_vil1_float_ops::convert_to_float(image);
00173 vil1_memory_image_of<float> smooth =
00174 brip_vil1_float_ops::gaussian(flt_image, corr_sigma_);
00175 smooth_images_[cam]=smooth;
00176 return true;
00177 }
00178
00179
00180
00181 void brct_plane_sweeper::
00182 homographies_at_z(double z, vcl_vector<vgl_h_matrix_2d<double> >& homgs)
00183 {
00184 if (!homographies_valid_)
00185 return;
00186
00187 double zc = z_[1];
00188 if (!zc)
00189 return;
00190 homgs.clear();
00191 double f = z/zc;
00192 for (int cam = 0; cam<n_cams_; cam++)
00193 {
00194 vgl_h_matrix_2d<double> H0 = homographies_[0][cam];
00195 vgl_h_matrix_2d<double> H1 = homographies_[1][cam];
00196 vnl_matrix_fixed<double,3, 3> M0 = H0.get_matrix();
00197 vnl_matrix_fixed<double,3, 3> M1 = H1.get_matrix();
00198 vnl_matrix_fixed<double,3, 3> M;
00199
00200
00201 for (int r = 0; r<3; r++)
00202 for (int c =0; c<2; c++)
00203 M[r][c] = 0.5*(M0[r][c] + M1[r][c]);
00204
00205 for (int r = 0; r<3; r++)
00206 M[r][2] = f*(M1[r][2]-M0[r][2]) + M0[r][2];
00207 vgl_h_matrix_2d<double> H(M);
00208 homgs.push_back(H);
00209 }
00210 }
00211
00212
00213 vil1_memory_image_of<unsigned char>
00214 brct_plane_sweeper::project_image_to_plane(const int plane,
00215 const int cam)
00216 {
00217 vil1_memory_image_of<unsigned char> out;
00218 if (!homographies_valid_)
00219 {
00220 vcl_cout << "In brct_plane_sweeper::project_image_to_plane -"
00221 << " homographies not loaded yet\n";
00222 return out;
00223 }
00224 vgl_h_matrix_2d<double> H = homographies_[plane][cam];
00225 vgl_h_matrix_2d<double> Hinv = H.get_inverse();
00226 vil1_memory_image_of<float> image =smooth_images_[cam], temp;
00227 brip_vil1_float_ops::homography(image, Hinv, temp);
00228 out = brip_vil1_float_ops::convert_to_byte(temp, 0, 255);
00229 return out;
00230 }
00231
00232 static vsol_box_2d_sptr box_from_image(vil1_memory_image_of<float> const& img)
00233 {
00234 int w = img.width();
00235 int h = img.height();
00236 vsol_box_2d_sptr box = new vsol_box_2d();
00237 box->add_point(0,0);
00238 box->add_point(w,h);
00239 return box;
00240 }
00241
00242 bool brct_plane_sweeper::
00243 overlapping_box(vcl_vector<vgl_h_matrix_2d<double> > const& homgs,
00244 vsol_box_2d_sptr & box)
00245 {
00246 vsol_box_2d_sptr intersection = new vsol_box_2d();
00247 double maxd = vnl_numeric_traits<double>::maxval;
00248 intersection->add_point(-maxd, -maxd);
00249 intersection->add_point(+maxd, +maxd);
00250
00251 for (int cam =0; cam<n_cams_; cam++)
00252 {
00253 vgl_h_matrix_2d<double> H = homgs[cam];
00254 vgl_h_matrix_2d<double> Hinv = H.get_inverse();
00255 vil1_memory_image_of<float> image =smooth_images_[cam];
00256 vsol_box_2d_sptr b = box_from_image(image);
00257 vsol_box_2d_sptr Hinv_b;
00258 if (!bsol_algs::homography(b, Hinv, Hinv_b))
00259 return false;
00260 if (!bsol_algs::intersection(Hinv_b, intersection, intersection))
00261 return false;
00262 }
00263 box = intersection;
00264 return true;
00265 }
00266
00267 bool brct_plane_sweeper::
00268 overlapping_projections(vcl_vector<vgl_h_matrix_2d<double> > const& homgs,
00269 vcl_vector<vil1_memory_image_of<float> >& imgs,
00270 double& tx, double& ty)
00271 {
00272 if (!n_cams_)
00273 {
00274 vcl_cout << "In brct_plane_sweeper::overlapping_projections(.._)-"
00275 << " no cameras\n";
00276 return false;
00277 }
00278 imgs.clear();
00279
00280 vsol_box_2d_sptr intersection;
00281 if (!this->overlapping_box(homgs, intersection))
00282 {
00283 vcl_cout << "In brct_plane_sweeper::overlapping_projections(.._)-"
00284 << " no overlap\n";
00285 return false;
00286 }
00287
00288 tx = -(intersection->get_min_x()), ty = -(intersection->get_min_y());
00289 int w = (int)intersection->width(), h = (int)intersection->height();
00290 for (int cam =0; cam<n_cams_; cam++)
00291 {
00292 vgl_h_matrix_2d<double> H = homgs[cam];
00293
00294
00295
00296 vgl_h_matrix_2d<double> Hinv = H.get_inverse();
00297
00298 vgl_h_matrix_2d<double> Hinvt = translate_h(Hinv, tx, ty);
00299
00300 vil1_memory_image_of<float> image =smooth_images_[cam];
00301 vil1_memory_image_of<float> projection(w, h);
00302 if (!brip_vil1_float_ops::homography(image, Hinvt, projection, true))
00303 return false;
00304 imgs.push_back(projection);
00305 }
00306 return true;
00307 }
00308
00309
00310 bool brct_plane_sweeper::
00311 overlapping_projections(vcl_vector<vgl_h_matrix_2d<double> > const& homgs,
00312 vcl_vector<vil1_memory_image_of<float> >& imgs,
00313 vcl_vector<vcl_vector<vsol_point_2d_sptr> >& corners,
00314 double& tx, double& ty)
00315 {
00316 if (!overlapping_projections(homgs, imgs, tx, ty))
00317 return false;
00318 corners.clear();
00319
00320 for (int cam =0; cam<n_cams_; cam++)
00321 {
00322 vgl_h_matrix_2d<double> H = homgs[cam];
00323 vgl_h_matrix_2d<double> Hinv = H.get_inverse();
00324 vgl_h_matrix_2d<double> Hinvt = translate_h(Hinv, tx, ty);
00325 vcl_vector<vsol_point_2d_sptr> hc = harris_corners_[cam];
00326 vcl_vector<vsol_point_2d_sptr> pcs =
00327 this->project_corners(Hinvt, hc);
00328 corners.push_back(pcs);
00329 }
00330 return true;
00331 }
00332
00333
00334
00335 bool brct_plane_sweeper::
00336 overlapping_projections(const int plane,
00337 vcl_vector<vil1_memory_image_of<float> >& imgs)
00338 {
00339 vcl_vector<vgl_h_matrix_2d<double> > homgs = homographies_[plane];
00340 double tx=0, ty=0;
00341 if (!overlapping_projections(homgs, imgs, tx, ty))
00342 return false;
00343 return true;
00344 }
00345
00346
00347 bool brct_plane_sweeper::
00348 overlapping_projections(const double z,
00349 vcl_vector<vil1_memory_image_of<float> >& imgs)
00350 {
00351 vcl_vector<vgl_h_matrix_2d<double> > homgs;
00352 this->homographies_at_z(z, homgs);
00353 double tx=0, ty=0;
00354 if (!overlapping_projections(homgs, imgs, tx, ty))
00355 return false;
00356 return true;
00357 }
00358
00359 bool brct_plane_sweeper::
00360 overlapping_projections(const double z,
00361 vcl_vector<vil1_memory_image_of<float> >& imgs,
00362 vcl_vector<vcl_vector<vsol_point_2d_sptr> >& corners)
00363 {
00364 vcl_vector<vgl_h_matrix_2d<double> > homgs;
00365 this->homographies_at_z(z, homgs);
00366 double tx=0, ty=0;
00367 if (!overlapping_projections(homgs, imgs, corners, tx, ty))
00368 return false;
00369 return true;
00370 }
00371
00372
00373
00374
00375 vil1_memory_image_of<unsigned char>
00376 brct_plane_sweeper::cross_correlate_projections(const int plane)
00377 {
00378 vil1_memory_image_of<unsigned char> out;
00379 if (n_cams_<2)
00380 {
00381 vcl_cout << "In brct_plane_sweeper::cross_correlate_projections(..)-"
00382 << "less than two images\n";
00383 return out;
00384 }
00385 vcl_vector<vil1_memory_image_of<float> > imgs;
00386 this->overlapping_projections(plane, imgs);
00387 vil1_memory_image_of<float> cc;
00388 if (!brip_vil1_float_ops::cross_correlate(imgs[0], imgs[1], cc,
00389 corr_radius_, intensity_thresh_))
00390 return out;
00391 out = brip_vil1_float_ops::convert_to_byte(cc, corr_min_, corr_max_);
00392 return out;
00393 }
00394
00395
00396
00397
00398 vil1_memory_image_of<unsigned char>
00399 brct_plane_sweeper::cross_correlate_projections(const double z)
00400 {
00401 vil1_memory_image_of<unsigned char> out;
00402 if (n_cams_<2)
00403 {
00404 vcl_cout << "In brct_plane_sweeper::cross_correlate_projections(..)-"
00405 << "less than two images\n";
00406 return out;
00407 }
00408 vcl_vector<vil1_memory_image_of<float> > imgs;
00409 vcl_vector<vgl_h_matrix_2d<double> > homgs;
00410 this->homographies_at_z(z, homgs);
00411 double tx=0, ty=0;
00412 this->overlapping_projections(homgs, imgs, tx, ty);
00413 vil1_memory_image_of<float> cc;
00414 if (!brip_vil1_float_ops::cross_correlate(imgs[0], imgs[1], cc,
00415 corr_radius_, intensity_thresh_))
00416 return out;
00417 out = brip_vil1_float_ops::convert_to_byte(cc, corr_min_, corr_max_);
00418 return out;
00419 }
00420
00421 bool
00422 brct_plane_sweeper::
00423 cross_correlate_proj_corners(const double z,
00424 vil1_image& back,
00425 vcl_vector<vsol_point_2d_sptr>& matched_corners,
00426 vcl_vector<vsol_point_2d_sptr>& back_proj_cnrs,
00427 vcl_vector<vsol_point_2d_sptr>& orig_cnrs0)
00428 {
00429 if (n_cams_<2)
00430 {
00431 vcl_cout << "In brct_plane_sweeper::cross_correlate_projections(..)-"
00432 << "less than two images\n";
00433 return false;
00434 }
00435
00436 vcl_vector<vil1_memory_image_of<float> > imgs;
00437 vcl_vector<vsol_point_2d_sptr> temp;
00438 vcl_vector<vcl_vector<vsol_point_2d_sptr> > proj_corners;
00439 if (!overlapping_projections(z, imgs, proj_corners))
00440 return false;
00441 vcl_cout << "Correlating corners at z" << z << vcl_endl;
00442
00443 if (!this->correlate_corners(imgs, proj_corners, matched_corners))
00444 return false;
00445
00446 vcl_vector<vgl_h_matrix_2d<double> > homgs;
00447 this->homographies_at_z(z, homgs);
00448 vgl_h_matrix_2d<double> H0=homgs[0], H1 = homgs[1];
00449 vgl_h_matrix_2d<double> H1inv = H1.get_inverse();
00450 vcl_vector<vsol_point_2d_sptr> world_pts =
00451 this->project_corners(H1inv, matched_corners);
00452 back_proj_cnrs = this->project_corners(H0, world_pts);
00453 orig_cnrs0 = harris_corners_[0];
00454 vcl_cout << "World Points/BackProj\n";
00455 int n = world_pts.size();
00456 for (int i = 0; i<n; i++)
00457 {
00458 bsol_algs::print(world_pts[i]);
00459 bsol_algs::print(back_proj_cnrs[i]);
00460 vcl_cout << vcl_endl;
00461 }
00462
00463
00464 back = images_[1];
00465 return true;
00466 }
00467
00468 vsol_box_2d_sptr brct_plane_sweeper::
00469 depth_image_box(const double zmin, const double zmax)
00470 {
00471 vsol_box_2d_sptr un = new vsol_box_2d();
00472 un->add_point(0, 0);
00473 vcl_vector<vgl_h_matrix_2d<double> > homgs;
00474 for (double z = zmin; z<=zmax; z+=del_)
00475 {
00476 this->homographies_at_z(zmin, homgs);
00477 vsol_box_2d_sptr bb;
00478 this->overlapping_box(homgs, bb);
00479 if (!bsol_algs::box_union(un, bb, un))
00480 continue;
00481 }
00482 return un;
00483 }
00484
00485 #if 0 // unused static function
00486 static void debug_print(const int c0, const int r0, const int dr,
00487 const int c, const int r,
00488 const float cc_val)
00489 {
00490 int cmin = c0-dr, rmin = r0-dr;
00491 int cmax = c0+dr, rmax = r0+dr;
00492 if (c<cmin||c>cmax||r<rmin||r>rmax)
00493 return;
00494 vcl_cout << "C[" << r << "][" << c << "]= " << cc_val << vcl_endl;
00495 }
00496 #endif // 0
00497
00498
00499 bool brct_plane_sweeper::
00500 depth_image(vil1_memory_image_of<unsigned char>& depth_out,
00501 vil1_memory_image_of<unsigned char>& corr_out)
00502 {
00503 if (n_cams_<2)
00504 {
00505 vcl_cout << "In brct_plane_sweeper::cross_correlate_projections(..)-"
00506 << "less than two images\n";
00507 return false;
00508 }
00509 z_corr_images_.clear();
00510 int n_zvals = nz_;
00511 if (n_zvals>256)
00512 n_zvals = 256;
00513 if (n_zvals<=0)
00514 n_zvals = 1;
00515 del_ = (zmax_-zmin_)/n_zvals;
00516
00517
00518 vsol_box_2d_sptr un = this->depth_image_box(zmin_, zmax_);
00519 double Tx = -(un->get_min_x()), Ty = -(un->get_min_y());
00520 int w = (int)(un->width()), h = (int)(un->height());
00521
00522
00523
00524 vil1_memory_image_of<float> max_corr(w, h);
00525 float maxv = vnl_numeric_traits<float>::maxval;
00526 max_corr.fill(-maxv);
00527
00528 vil1_memory_image_of<float> depth(w, h);
00529 float null_depth = -10;
00530 depth.fill(null_depth);
00531 float null_corr = -1.0;
00532
00533
00534 vcl_vector<vil1_memory_image_of<float> > imgs;
00535 vcl_vector<vgl_h_matrix_2d<double> > homgs, trans_homgs;
00536 for (double z = zmin_; z<=zmax_; z+=del_)
00537 {
00538
00539 this->homographies_at_z(z, homgs);
00540 double tx=0, ty=0;
00541 this->overlapping_projections(homgs, imgs, tx, ty);
00542
00543
00544
00545
00546 vil1_memory_image_of<float> cc;
00547 if (!brip_vil1_float_ops::cross_correlate(imgs[0], imgs[1],
00548 cc, corr_radius_,
00549 intensity_thresh_))
00550 return false;
00551
00552 double dtx = 2*Tx-tx, dty = 2*Ty-ty;
00553 vgl_h_matrix_2d<double> Htrans = translation_h(dtx, dty);
00554
00555 vil1_memory_image_of<float> base(w, h);
00556 if (!brip_vil1_float_ops::homography(cc, Htrans, base, true, null_corr))
00557 continue;
00558 z_corr_images_.push_back(base);
00559 vcl_cout << "corr for depth " << z << vcl_endl;
00560 for (int r = 0; r<h; r++)
00561 for (int c=0; c<w; c++)
00562 {
00563 float cc_val = base(c, r);
00564 if (cc_val<corr_thresh_)
00565 continue;
00566 if (cc_val > max_corr(c, r))
00567 {
00568 max_corr(c, r) = cc_val;
00569 depth(c, r) = float(z);
00570 }
00571 }
00572 }
00573 depth_out = brip_vil1_float_ops::convert_to_byte(depth, null_depth, zmax_);
00574 corr_out = brip_vil1_float_ops::convert_to_byte(max_corr, corr_min_,
00575 corr_max_);
00576 return true;
00577 }
00578
00579
00580 bool brct_plane_sweeper::
00581 harris_depth_match(vcl_vector<vsol_point_3d_sptr>& points_3d,
00582 vcl_vector<vsol_point_2d_sptr>& proj_points)
00583 {
00584 if (n_cams_<2)
00585 {
00586 vcl_cout << "In brct_plane_sweeper::cross_correlate_projections(..)-"
00587 << "less than two images\n";
00588 return false;
00589 }
00590 points_3d.clear();
00591 proj_points.clear();
00592
00593 int n_zvals = nz_;
00594 if (n_zvals>256)
00595 n_zvals = 256;
00596 if (n_zvals<=0)
00597 n_zvals = 1;
00598 del_ = (zmax_-zmin_)/n_zvals;
00599
00600
00601 vsol_box_2d_sptr un = this->depth_image_box(zmin_, zmax_);
00602 int w = (int)(un->width()), h = (int)(un->height());
00603
00604
00605
00606 vil1_memory_image_of<float> max_corr(w, h);
00607 float maxv = vnl_numeric_traits<float>::maxval;
00608 max_corr.fill(-maxv);
00609
00610 vil1_memory_image_of<float> depth(w, h);
00611 float null_depth = -10;
00612 depth.fill(null_depth);
00613
00614 vil1_memory_image_of<float> back;
00615 vcl_vector<vil1_memory_image_of<float> > imgs;
00616 vcl_vector<vgl_h_matrix_2d<double> > homgs, trans_homgs;
00617 vcl_vector<vcl_vector<vsol_point_2d_sptr> > proj_corners;
00618
00619 for (double z = zmin_; z<=zmax_; z+=del_)
00620 {
00621
00622 this->homographies_at_z(z, homgs);
00623 double tx=0, ty=0;
00624 this->overlapping_projections(homgs, imgs, proj_corners, tx, ty);
00625 vcl_vector<vsol_point_2d_sptr> matched_corners;
00626 if (!this->correlate_corners(imgs, proj_corners, matched_corners))
00627 return false;
00628 vcl_cout << "Matched " << matched_corners.size() << " corners at z = "
00629 << z << vcl_endl;
00630 for (vcl_vector<vsol_point_2d_sptr>::iterator pit = matched_corners.begin();
00631 pit != matched_corners.end(); pit++)
00632 {
00633 proj_points.push_back(*pit);
00634
00635 }
00636
00637
00638 vcl_vector<vsol_point_2d_sptr> trans_pts =
00639 this->project_corners(homgs[1], matched_corners);
00640
00641 for (vcl_vector<vsol_point_2d_sptr>::iterator pit = trans_pts.begin();
00642 pit != trans_pts.end(); pit++)
00643 {
00644 double x = (*pit)->x(), y = (*pit)->y();
00645 vsol_point_3d_sptr p3d = new vsol_point_3d(x, y, z);
00646 points_3d.push_back(p3d);
00647 bsol_algs::print(p3d);
00648 }
00649 vcl_cout << vcl_endl;
00650 }
00651 return true;
00652 }
00653
00654 bool brct_plane_sweeper::compute_harris()
00655 {
00656 int n_images = images_.size();
00657 if (n_images!=n_cams_)
00658 {
00659 vcl_cout << "In brct_plane_sweeper::compute_harris() - "
00660 << "images not matched to cameras\n";
00661 return false;
00662 }
00663 vcl_cout << hdp_ << vcl_endl;
00664 sdet_harris_detector hd(hdp_);
00665 for (int cam = 0; cam<n_cams_; cam++)
00666 {
00667 hd.clear();
00668 hd.set_image(images_[cam]);
00669 hd.extract_corners();
00670 vcl_vector<vsol_point_2d_sptr> points = hd.get_points();
00671 harris_corners_[cam]=points;
00672 }
00673 harris_valid_ = true;
00674 return true;
00675 }
00676
00677
00678 static bool has_neighbor(const int r, const int c , const int radius,
00679 const int h, const int w,
00680 vbl_array_2d<bool> const& cnr_array)
00681 {
00682
00683 int rmin = radius, rmax = h-radius-1, cmin = radius, cmax = w-radius-1;
00684 if (r<rmin||r>rmax||c<cmin||c>cmax)
00685 return false;
00686 for (int r0 = -radius; r0<=radius; r0++)
00687 for (int c0 = -radius; c0<=radius; c0++)
00688 if (cnr_array[r+r0][c+c0])
00689 return true;
00690 return false;
00691 }
00692
00693
00694 bool brct_plane_sweeper::
00695 correlate_corners(vcl_vector<vil1_memory_image_of<float> > const& imgs,
00696 vcl_vector<vcl_vector<vsol_point_2d_sptr> > const& corners,
00697 vcl_vector<vsol_point_2d_sptr>& matched_corners)
00698 {
00699 int n_imgs=imgs.size();
00700 int n_corn=corners.size();
00701 if (n_imgs!=2||n_imgs!=n_corn)
00702 return false;
00703 matched_corners.clear();
00704 int w = imgs[0].width(), h = imgs[0].height();
00705 vbl_array_2d<bool> pt_index(h, w);
00706 pt_index.fill(false);
00707 vcl_vector<vsol_point_2d_sptr> const& pts0 = corners[0],
00708 pts1 = corners[1];
00709
00710 vcl_vector<vsol_point_2d_sptr> h1 = harris_corners_[1];
00711
00712 for (vcl_vector<vsol_point_2d_sptr>::const_iterator pit = pts0.begin();
00713 pit != pts0.end(); pit++)
00714 {
00715 int r = (int)((*pit)->y()), c = (int)((*pit)->x());
00716 if (r<0||r>=h||c<0||c>=w)
00717 continue;
00718 pt_index[r][c] = true;
00719 }
00720
00721 int n1 = pts1.size();
00722 for (int i = 0; i< n1; i++)
00723 {
00724
00725 double x0 = pts1[i]->x(), y0 = pts1[i]->y();
00726
00727 int r = (int)y0, c = (int)x0;
00728 if (r<0||r>=h||c<0||c>=w)
00729 continue;
00730 int pr = (int)point_radius_;
00731 if (has_neighbor(r, c, pr, h, w, pt_index))
00732 {
00733 float val =
00734 brip_vil1_float_ops::cross_correlate(imgs[0], imgs[1],
00735 float(x0), float(y0),
00736 corr_radius_,
00737 intensity_thresh_);
00738
00739 if (val > corr_thresh_)
00740 {
00741 vsol_point_2d_sptr p = h1[i];
00742 matched_corners.push_back(p);
00743 vcl_cout << "C(" << p->x() << ' ' << p->y()
00744 << ")=" << val << vcl_endl;
00745 }
00746 }
00747 }
00748 return true;
00749 }
00750
00751 vcl_vector<vsol_point_2d_sptr>
00752 brct_plane_sweeper::harris_corners(const int cam)
00753 {
00754 vcl_vector<vsol_point_2d_sptr> points;
00755 if (cam>=n_cams_||!harris_valid_)
00756 return points;
00757 return harris_corners_[cam];
00758 }
00759
00760
00761 vil1_memory_image_of<unsigned char>
00762 brct_plane_sweeper::z_corr_image(const int i)
00763 {
00764 vil1_memory_image_of<unsigned char> temp;
00765 int li = i;
00766 int n = z_corr_images_.size();
00767 if (!n)
00768 return temp;
00769 if (i>=n)
00770 li = n-1;
00771 temp = brip_vil1_float_ops::convert_to_byte(z_corr_images_[li],
00772 corr_min_, corr_max_);
00773 return temp;
00774 }
00775
00776 void brct_plane_sweeper::corr_vals(const int col, const int row,
00777 vcl_vector<float>& z,
00778 vcl_vector<float>& corr)
00779 {
00780 z.clear();
00781 corr.clear();
00782 int i = 0, n = z_corr_images_.size();
00783 for (float zi = zmin_; zi<=zmax_; zi+=del_, i++)
00784 {
00785 z.push_back(zi);
00786 if (i<n)
00787 corr.push_back(z_corr_images_[i](col, row));
00788 }
00789 }
00790
00791 vsol_point_2d_sptr brct_plane_sweeper::
00792 map_point(vsol_point_2d_sptr const& p, vgl_h_matrix_2d<double> const& Hcomp)
00793 {
00794 vgl_homg_point_2d<double> hp(p->x(), p->y()), hp_to;
00795
00796 hp_to = Hcomp(hp);
00797 vgl_point_2d<double> p_to(hp_to);
00798 return new vsol_point_2d(p_to);
00799 }
00800
00801 vsol_point_2d_sptr brct_plane_sweeper::
00802 map_point(vsol_point_2d_sptr const& p, const int cam, const double z)
00803 {
00804 vsol_point_2d_sptr q;
00805 if (!p)
00806 return q;
00807 vcl_vector<vgl_h_matrix_2d<double> > homgs;
00808 this->homographies_at_z(z, homgs);
00809
00810 int nc = homgs.size();
00811 if (nc!=2||cam>=nc)
00812 return q;
00813 vgl_h_matrix_2d<double> H_from = homgs[cam], H_to =homgs[1-cam];
00814
00815 vgl_h_matrix_2d<double> H_from_inv = H_from.get_inverse();
00816 vgl_h_matrix_2d<double> Hcomp = H_to*H_from_inv;
00817 return this->map_point(p, Hcomp);
00818 }
00819
00820
00821 bool brct_plane_sweeper::
00822 map_points(const int from_cam, const double z,
00823 vcl_vector<vsol_point_2d_sptr> const& from_points,
00824 vcl_vector<vsol_point_2d_sptr>& to_points)
00825 {
00826
00827 vcl_vector<vgl_h_matrix_2d<double> > homgs;
00828 this->homographies_at_z(z, homgs);
00829 int nc = homgs.size();
00830 if (nc!=2||from_cam>=nc)
00831 return false;
00832 to_points.clear();
00833 int to_cam = 1-from_cam;
00834 vgl_h_matrix_2d<double> H_from = homgs[from_cam], H_to =homgs[to_cam];
00835
00836 vgl_h_matrix_2d<double> H_from_inv = H_from.get_inverse();
00837 vgl_h_matrix_2d<double> Hcomp = H_to*H_from_inv;
00838
00839 for (vcl_vector<vsol_point_2d_sptr>::const_iterator pit = from_points.begin();
00840 pit != from_points.end(); pit++)
00841 to_points.push_back(this->map_point(*pit, Hcomp));
00842
00843 return true;
00844 }
00845
00846
00847
00848 bool brct_plane_sweeper::map_image(const int from_cam, const double z,
00849 vil1_memory_image_of<float>& mapped_image)
00850 {
00851
00852 vcl_vector<vgl_h_matrix_2d<double> > homgs;
00853 this->homographies_at_z(z, homgs);
00854 int nc = homgs.size();
00855 if (nc!=2||from_cam>=nc)
00856 return false;
00857 int to_cam = 1-from_cam;
00858
00859 vgl_h_matrix_2d<double> Ha = homgs[from_cam], Hb =homgs[to_cam];
00860 vgl_h_matrix_2d<double> Hainv = Ha.get_inverse();
00861 vgl_h_matrix_2d<double> Hcomp = Hb*Hainv;
00862 vil1_memory_image_of<float> temp = smooth_images_[from_cam],
00863 to = smooth_images_[to_cam];
00864 vsol_box_2d_sptr from_box =box_from_image(temp), to_box = box_from_image(to),
00865 inter_box;
00866 vcl_cout << "Intersecting Mapped Box\n";
00867 if (this->intersecting_bounding_box(Hcomp, from_box, to_box, inter_box))
00868 bsol_algs::print(inter_box);
00869
00870 mapped_image.resize(temp.width(), temp.height());
00871 if (!brip_vil1_float_ops::homography(temp, Hcomp, mapped_image, true, 0))
00872 return false;
00873 return true;
00874 }
00875
00876
00877
00878 bool brct_plane_sweeper::map_image_to_image(const int from_cam, const double z,
00879 vil1_memory_image_of<unsigned char>& mapped_to_image,
00880 vil1_memory_image_of<unsigned char>& orig_to_image)
00881 {
00882 vil1_memory_image_of<float> temp;
00883 if (!this->map_image(from_cam, z, temp))
00884 return false;
00885 int to_cam = 1-from_cam;
00886 mapped_to_image = brip_vil1_float_ops::convert_to_byte(temp, 0, 255);
00887 orig_to_image =
00888 brip_vil1_float_ops::convert_to_byte(smooth_images_[to_cam], 0, 255);
00889 return true;
00890 }
00891
00892 bool brct_plane_sweeper::
00893 intersecting_bounding_box(vgl_h_matrix_2d<double> const& Hcomp,
00894 vsol_box_2d_sptr const& from_box,
00895 vsol_box_2d_sptr const& to_box,
00896 vsol_box_2d_sptr & box)
00897 {
00898 vsol_box_2d_sptr intersection = new vsol_box_2d();
00899 vsol_box_2d_sptr mapped_box;
00900 if (!bsol_algs::homography(from_box, Hcomp, mapped_box))
00901 return false;
00902 if (!bsol_algs::intersection(mapped_box, to_box, box))
00903 return false;
00904 return true;
00905 }
00906
00907 bool brct_plane_sweeper::
00908 map_harris_corners(const int from_cam, const double z,
00909 vcl_vector<vsol_point_2d_sptr>& mapped_to_points,
00910 vcl_vector<vsol_point_2d_sptr>& orig_to_points)
00911 {
00912 if (from_cam<0||from_cam>=2)
00913 return false;
00914 if (!harris_valid_)
00915 return false;
00916 int to_cam = 1-from_cam;
00917 vcl_vector<vsol_point_2d_sptr> harris_from = harris_corners_[from_cam];
00918 orig_to_points = harris_corners_[to_cam];
00919 this->map_points(from_cam, z, harris_from, mapped_to_points);
00920 return true;
00921 }
00922
00923
00924 void brct_plane_sweeper::init_harris_match(const int from_cam)
00925 {
00926
00927 int nrows = 192, ncols = 256;
00928 int to_cam = 1-from_cam;
00929 vcl_vector<vsol_point_2d_sptr> to_points = harris_corners_[to_cam];
00930 pindx_ = bsol_point_index_2d(nrows, ncols, to_points);
00931 vcl_vector<vsol_point_2d_sptr> temp = pindx_.points();
00932 vcl_cout << "\nTotal points in point index = " << temp.size() << vcl_endl;
00933 pindx_.clear_marks();
00934 matched_corners_.clear();
00935 del_ = (zmax_-zmin_)/nz_;
00936 }
00937
00938
00939 bool brct_plane_sweeper::
00940 match_harris_corners(const int from_cam,