contrib/gel/vmal/vmal_rectifier.cxx

Go to the documentation of this file.
00001 // This is gel/vmal/vmal_rectifier.cxx
00002 #include "vmal_rectifier.h"
00003 //:
00004 // \file
00005 
00006 #include <vmal/vmal_convert_vtol.h>
00007 #include <vcl_cmath.h> // atan2()
00008 #include <vbl/vbl_bounding_box.h>
00009 #include <vnl/algo/vnl_svd.h>
00010 #include <vnl/vnl_inverse.h>
00011 #include <vnl/algo/vnl_determinant.h>
00012 #include <vnl/vnl_vector.h>
00013 //#include <vcl_cmath.h>
00014 #include <mvl/FMatrix.h>
00015 #include <mvl/FMatrixComputeLinear.h>
00016 #include <mvl/FMatrixComputeRANSAC.h>
00017 #include <mvl/FMatrixComputeMLESAC.h>
00018 #include <mvl/FMatrixComputeRobust.h>
00019 #include <vil/vil_bilin_interp.h>
00020 
00021 vmal_rectifier::vmal_rectifier()
00022 {
00023   lines0_p_=NULL;
00024   lines0_q_=NULL;
00025   lines1_p_=NULL;
00026   lines1_q_=NULL;
00027   points0_=NULL;
00028   points1_=NULL;
00029   rectL =  new vil_image_view<vxl_byte>(1,1,1);
00030   rectR =  new vil_image_view<vxl_byte>(1,1,1);
00031   //  rectL =  NULL;
00032   //  rectR =  NULL;
00033 }
00034 
00035 vmal_rectifier::vmal_rectifier(vmal_multi_view_data_vertex_sptr mvd_vertex,
00036                                vmal_multi_view_data_edge_sptr mvd_edge,
00037                                int ima_height, int ima_width) :
00038   is_f_compute_(false)
00039 {
00040   lines0_p_=NULL;
00041   lines0_q_=NULL;
00042   lines1_p_=NULL;
00043   lines1_q_=NULL;
00044   points0_=NULL;
00045   rectL =  new vil_image_view<vxl_byte>(1,1,1);
00046   rectR =  new vil_image_view<vxl_byte>(1,1,1);
00047 
00048   if ((mvd_vertex->get_nb_views()>1) && (mvd_edge->get_nb_views()>1))
00049   {
00050     // Prescale the points
00051     vcl_vector<vtol_edge_2d_sptr> tmp_lines0;
00052     vcl_vector<vtol_edge_2d_sptr> tmp_lines1;
00053 
00054     mvd_edge->get(0,1,tmp_lines0,tmp_lines1);
00055     numpoints_=tmp_lines0.size();
00056 
00057     convert_lines_double_3(tmp_lines0, lines0_p_, lines0_q_);
00058     convert_lines_double_3(tmp_lines1, lines1_p_, lines1_q_);
00059 
00060     vcl_vector<vtol_vertex_2d_sptr> tmp_points0;
00061     vcl_vector<vtol_vertex_2d_sptr> tmp_points1;
00062 
00063     mvd_vertex->get(0,1,tmp_points0,tmp_points1);
00064 
00065     convert_points_double_3(tmp_points0, points0_);
00066     convert_points_double_3(tmp_points1, points1_);
00067     height_=ima_height;
00068     width_=ima_width;
00069   }
00070 }
00071 
00072 // Constructor for dealing with just matched points
00073 
00074 vmal_rectifier::vmal_rectifier(vcl_vector< vnl_vector<double> >* pts0,
00075                                vcl_vector< vnl_vector<double> >* pts1,
00076                                int ima_height, int ima_width) :
00077   lines0_p_(0), lines0_q_(0), lines1_p_(0), lines1_q_(0),
00078   numpoints_(pts0->size()), height_(ima_height), width_(ima_width),
00079   is_f_compute_(false)
00080 {
00081   rectL = new vil_image_view<vxl_byte>(1,1,1);
00082   rectR = new vil_image_view<vxl_byte>(1,1,1);
00083 
00084   // put the points in the proper buffers...
00085   points0_ = new vnl_double_3[numpoints_];
00086   points1_ = new vnl_double_3[numpoints_];
00087   vcl_vector< vnl_vector<double> >::iterator vit0 = pts0->begin();
00088   vcl_vector< vnl_vector<double> >::iterator vit1 = pts1->begin();
00089   for (int i=0; i<numpoints_; ++i,++vit0,++vit1)
00090   {
00091     points0_[i][0] = (*vit0)[0]; // [1]
00092     points0_[i][1] = (*vit0)[1]; // [0]
00093     points0_[i][2] = 1.0;
00094     points1_[i][0] = (*vit1)[0]; // [1]
00095     points1_[i][1] = (*vit1)[1]; // [0]
00096     points1_[i][2] = 1.0;
00097   }
00098 }
00099 
00100 
00101 vmal_rectifier::~vmal_rectifier()
00102 {
00103   delete [] points0_;
00104   delete [] points1_;
00105   delete [] lines0_p_;
00106   delete [] lines0_q_;
00107   delete [] lines1_p_;
00108   delete [] lines1_q_;
00109   delete rectL;
00110   delete rectR;
00111 }
00112 
00113 void vmal_rectifier::rectification_matrix(vnl_double_3x3& H0,
00114                                           vnl_double_3x3& H1)
00115 {
00116   if (!is_f_compute_)
00117   {
00118     is_f_compute_=true;
00119     vcl_vector<HomgPoint2D> v_points0;
00120     vcl_vector<HomgPoint2D> v_points1;
00121     for (int i=0;i<numpoints_;i++)
00122     {
00123       HomgPoint2D tmp_point0(points0_[i][0],points0_[i][1]);
00124       HomgPoint2D tmp_point1(points1_[i][0],points1_[i][1]);
00125       v_points0.push_back(tmp_point0);
00126       v_points1.push_back(tmp_point1);
00127     }
00128 
00129     FMatrixComputeLinear tmp_fcom(true,true);
00130     FMatrix tmp_f;
00131     tmp_fcom.compute(v_points0,v_points1,& tmp_f);
00132     tmp_f.get(&F12_.as_ref().non_const());
00133 
00134     vcl_cout << "Fundamental Matrix:\n" << tmp_f << vcl_endl;
00135 
00136     HomgPoint2D epi1;
00137     HomgPoint2D epi2;
00138 
00139     tmp_f.get_epipoles (&epi1, &epi2);
00140     double x1,y1;
00141     double x2,y2;
00142     epi1.get_nonhomogeneous(x1,y1);
00143     epi2.get_nonhomogeneous(x2,y2);
00144 
00145     vnl_double_3 tmp_epi1;
00146     tmp_epi1[0]=x1;
00147     tmp_epi1[1]=y1;
00148     tmp_epi1[2]=1.0;
00149 
00150     vnl_double_3 tmp_epi2;
00151     tmp_epi2[0]=x2;
00152     tmp_epi2[1]=y2;
00153     tmp_epi2[2]=1.0;
00154 
00155     epipoles_.push_back(tmp_epi1);
00156     epipoles_.push_back(tmp_epi2);
00157   }
00158   bool affine=false;
00159   int out_height;
00160   int out_width;
00161   int sweeti=(int)(width_/2);  // sweetx in RH parlance
00162   int sweetj=(int)(height_/2);  // sweety in RH parlance
00163 
00164   compute_joint_epipolar_transform_new(
00165     points0_,       // Points in one view
00166     points1_,       // Points in the other view
00167     numpoints_,     // Number of matched points
00168     H0_, H1_,       // The matrices to be returned
00169     height_, width_,// Dimensions of the input images
00170     out_height, out_width,
00171     sweeti, sweetj, // Sweet spot in the first image
00172     affine);
00173   H0=H0_;
00174   H1=H1_;
00175   // vnl_double_3 p1=H0*epipoles_[0], p2=H1*epipoles_[1], p3=H0*points0_[0], p4=H1*points1_[0];
00176 }
00177 
00178 //In this case (3 cameras), we assume that the first camera matrix is equal
00179 //to P=[I|0]. So epi1 corresponds to e', i.e. the epipole of the second image and
00180 //epi2 corresponds to e", i.e. the epipole of the third image in relation to the
00181 //first image.
00182 void vmal_rectifier::set_tritensor(TriTensor &tri)
00183 {
00184   //this method is helpful when using the vmal_projective_reconstruction class
00185   //that compute the tritensor.
00186   is_f_compute_=true;
00187   tritensor_=tri;
00188 
00189   HomgPoint2D epi12=tri.get_epipole_12();
00190   FMatrix F12(tri.get_fmatrix_12());
00191 
00192   double x,y;
00193   epi12.get_nonhomogeneous(x,y);
00194 
00195   vnl_double_3 tmp_epi;
00196   tmp_epi[0]=x;
00197   tmp_epi[1]=y;
00198   tmp_epi[2]=1.0;
00199 
00200   epipoles_.push_back(tmp_epi);
00201   F12.get(&F12_.as_ref().non_const());
00202 }
00203 
00204 void vmal_rectifier::compute_joint_epipolar_transform_new (
00205   vnl_double_3* points0,  // Points in one view
00206   vnl_double_3* points1,  // Points in the other view
00207   int numpoints,          // Number of matched points
00208   vnl_double_3x3 &H0, vnl_double_3x3 &H1,  // The matrices to be returned
00209   int /* in_height */, int /* in_width */, // Dimensions of the input images
00210   int & /* out_height */, int & /* out_width */,
00211   double sweeti, double sweetj,// Sweet spot in the first image
00212   bool affine // = FALSE
00213 )
00214 {
00215    // Compute the pair of epipolar transforms to rectify matched points
00216    compute_initial_joint_epipolar_transforms (points0, points1, numpoints,
00217                                               H0, H1, sweeti, sweetj, affine);
00218 
00219    // Apply the affine correction
00220    apply_affine_correction (points0, points1, numpoints, H0, H1);
00221 #if 0
00222    // Next set the range so that the overlap is properly placed
00223    center_overlap_region (H0, im1_roi, H1, im2_roi, output_roi);
00224 #endif
00225    // Rotate through 90 degrees
00226    // NEED TO SET out_height & out_width!!! They're not set yet in this version!!! GWB - 06/25/03
00227    // use of out_height is currently removed in rectify_rotate90, so this is safe for now...
00228    //   rectify_rotate90 (out_height,out_width, H0, H1);
00229    // We do this twice because the images come out upside down!
00230    //   rectify_rotate90 (out_height,out_width, H0, H1);
00231    conditional_rectify_rotate180 (H0, H1);
00232 #if 0
00233    // Also, rotate a further 180 degrees if necessary
00234    conditional_rectify_rotate180 (output_roi, H0, H1);
00235 #endif
00236    vcl_cerr << "vmal_rectifier::compute_joint_epipolar_transform_new() not yet fully implemented\n";
00237 }
00238 
00239 void vmal_rectifier::compute_initial_joint_epipolar_transforms (
00240    vnl_double_3* /* points0 */,       // Points in one view
00241    vnl_double_3* /* points1 */,       // Points in the other view
00242    int /* numpoints */,               // Number of matched points
00243    vnl_double_3x3 &H0, vnl_double_3x3 &H1,  // The matrices to be returned
00244    double sweeti, double sweetj,// Sweet spot in the first image
00245    bool /* affine */ // = FALSE
00246    )
00247 {
00248    // Compute the pair of epipolar transforms to rectify matched points
00249    // This does a minimally distorting correction to H0 and matches it with H1.
00250 
00251   if (is_f_compute_)
00252   {
00253     //the epipoles are already set, we don't have to compute the
00254     //the fundamental matrix.
00255     if ( !compute_initial_joint_epipolar_transforms (F12_,sweeti, sweetj, H0, H1))
00256     {
00257       // Error message and exit
00258       vcl_cerr<<"Computation of epipolar transform failed\n";
00259     }
00260   }
00261   else // TODO
00262   {
00263     vcl_cerr << "vmal_rectifier::compute_initial_joint_epipolar_transforms() not yet fully implemented\n";
00264 #if 0
00265     // First of all compute the Q matrix
00266     rhMatrix Q(3, 3);
00267 
00268     // Compute and refine the estimate of the Q matrix
00269     if (affine)
00270     {
00271     // We do not call affine_optimum_solveQmatrix right now,
00272     // since it is faulty, because the triangulation routine is bad.
00273       affine_solveQmatrix (u1, v1, u2, v2, numpoints, Q);
00274       checkQmatrix (u1, v1, u2, v2, numpoints, Q);
00275     }
00276     else
00277     {
00278       solveQmatrix (u1, v1, u2, v2, numpoints, Q);
00279       refine_Q_matrix (u1, v1, u2, v2, numpoints, Q);
00280       checkQmatrix (u1, v1, u2, v2, numpoints, Q);
00281     }
00282 
00283     // Compute the epipolar transforms.
00284     if ( !compute_initial_joint_epipolar_transforms (Q, sweeti, sweetj, H0, H1))
00285     {
00286       // Error message and exit
00287       error_message ("Computation of epipolar transform failed\n");
00288       bail_out (2);
00289     }
00290 #endif
00291   }
00292 }
00293 
00294 //: Computes a pair of transformation matrices for an image pair that will define the joint epipolar projection.
00295 // This does a minimally distortion-free correction to H0 and then
00296 // gets a matching H0.
00297 
00298 int vmal_rectifier::compute_initial_joint_epipolar_transforms (
00299   const vnl_double_3x3 &Q,
00300   double ci, double cj,   // Position of reference point in first image
00301   vnl_double_3x3 &H0,     // The first transformation matrix computed
00302   vnl_double_3x3 &H1      // second transformation matrix to be computed
00303   )
00304 {
00305   // First get the epipole e'
00306   vnl_double_3 p1 = epipoles_[0];
00307 
00308   // Next, compute the mapping H' for the second image
00309 
00310   // First of all, translate the centre pixel to 0, 0
00311   H0[0][0] = 1.0; H0[0][1] = 0.0; H0[0][2] = -ci;
00312   H0[1][0] = 0.0; H0[1][1] = 1.0; H0[1][2] = -cj;
00313   H0[2][0] = 0.0; H0[2][1] = 0.0; H0[2][2] = 1.0;
00314 
00315   // Translate the epipole as well
00316   p1 = H0 * p1;
00317 
00318   // Make sure that the epipole is not at the origin
00319   if (p1[0] == 0.0 && p1[1] == 0.0)
00320   {
00321     vcl_cerr<<"Error : Epipole is at image center\n";
00322     return 0;
00323   }
00324 
00325   // Next determine a rotation that will send the epipole to (1, 0, x)
00326   double theta = vcl_atan2 (p1[1], p1[0]);
00327   double c = vcl_cos (theta);
00328   double s = vcl_sin (theta);
00329 
00330   vnl_double_3x3 T;
00331 
00332   T[0][0] =   c; T[0][1] =   s; T[0][2] = 0.0;
00333   T[1][0] =  -s; T[1][1] =   c; T[1][2] = 0.0;
00334   T[2][0] = 0.0; T[2][1] = 0.0; T[2][2] = 1.0;
00335 
00336     // Multiply things out
00337   H0 =  T * H0;
00338   p1 = T * p1;
00339   vnl_double_3 ep1=H0*epipoles_[0];
00340 
00341   // Now send the epipole to infinity
00342   double x = p1[2]/p1[0];
00343 
00344   vnl_double_3x3 E;
00345   E[0][0] = 1.0; E[0][1] = 0.0; E[0][2] = 0.0;
00346   E[1][0] = 0.0; E[1][1] = 1.0; E[1][2] = 0.0;
00347   E[2][0] =  -x; E[2][1] = 0.0; E[2][2] = 1.0;
00348 
00349   // Multiply things out.  Put the result in H0
00350   H0 = E * H0;
00351   ep1=H0*epipoles_[0];
00352   vcl_cout << "vmal_rectifier::c_i_j_e_t: epipole[0] at infinity = " << ep1 << vcl_endl;
00353   // Next compute the initial 2x
00354   H1 = matching_transform (Q.transpose(), H0);
00355 
00356   vnl_double_3 ep2=H1*epipoles_[1];
00357   vcl_cout << "vmal_rectifier::c_i_j_e_t: epipole[1] at infinity = " << ep2 << vcl_endl;
00358 
00359   // Return 1 value
00360   return 1;
00361 }
00362 
00363 vnl_double_3x3 vmal_rectifier::matching_transform (
00364   const vnl_double_3x3 &Q,
00365   const vnl_double_3x3 &H1
00366   )
00367    {
00368    // Computes a transform compatible with H1.  It is assumed that
00369    // H1 maps the epipole p2 to infinity (1, 0, 0)
00370    vnl_double_3x3 S, M;
00371    factor_Q_matrix_SR (Q, M, S);
00372 
00373    // Compute the matching transform
00374    vnl_double_3x3 H0 = H1 * M;
00375    return H0;
00376 }
00377 
00378 //: This routine comes up with a factorization of Q into R S
00379 void vmal_rectifier::factor_Q_matrix_SR (
00380         const vnl_double_3x3 &Q,// 3 x 3 matrix
00381         vnl_double_3x3 &R,      // non-singular matrix
00382         vnl_double_3x3 &S)      // Skew-symmetric part
00383 {
00384   double r, s;            // The two singular values
00385 
00386   // First do the singular value decomposition of Q
00387 
00388   vnl_svd<double> SVD(Q);
00389   vnl_double_3x3 U(SVD.U());
00390   vnl_double_3x3 V(SVD.V());
00391 
00392   vnl_double_3x3 E(0.0);
00393   vnl_double_3x3 Z(0.0);
00394   E[1][0]=E[2][2]=1;
00395   E[0][1]=-1;
00396   Z[0][1]=1;Z[1][0]=-1;
00397 
00398   r = SVD.W(0);
00399   s = SVD.W(1);
00400 
00401   // Transpose V, since we will need to multiply by it
00402   vnl_double_3x3 Vt = V.transpose();
00403   vnl_double_3x3 Ut = U.transpose();
00404 
00405   // Define RS
00406   vnl_double_3x3 RS;
00407   RS[0][0] =  r; RS[0][1] =  0; RS[0][2] =  0;
00408   RS[1][0] =  0; RS[1][1] =  s; RS[1][2] =  0;
00409   RS[2][0] =  0; RS[2][1] =  0; RS[2][2] =  s;
00410 
00411   // Construct the result
00412   // First of all the R matrix
00413   R=(U * E * RS * Vt);
00414 
00415   // Next the S matrix
00416   S=(U * Z * Ut);
00417 }
00418 
00419 vnl_double_3x3 vmal_rectifier::affine_correction (
00420    vnl_double_3* points0,
00421    vnl_double_3* points1,
00422    int numpoints,
00423    const vnl_double_3x3 &H0,
00424    const vnl_double_3x3 &H1)
00425   {
00426    // Correct according to an affine transformation
00427    // Finds the correction to H1 that would make it closest to H0
00428 
00429   // Matrices for a linear least-squares problem
00430   vnl_matrix<double> E(numpoints, 3);
00431   vnl_vector<double> x(numpoints);
00432    // Fill out the equations
00433    for (int i=0; i<numpoints; i++)
00434    {
00435       // Compute the transformed points
00436       vnl_double_3 u2hat = H1 * points1[i];
00437       double uu2 = u2hat[0]/u2hat[2];
00438       double vv2 = u2hat[1]/u2hat[2];
00439 
00440       vnl_double_3 u1hat = H0 * points0[i];
00441       double uu1 = u1hat[0]/u1hat[2];
00442 
00443       // Fill out the equation
00444       E[i][0] = uu2;
00445       E[i][1] = vv2;
00446       E[i][2] = 1.0;
00447       x[i] = uu1;
00448    }
00449 
00450    // Now solve the equations
00451    vnl_svd<double> SVD(E);
00452    vnl_double_3 a=SVD.solve(x);
00453   // rhVector a = lin_solve(E, x);
00454 
00455    // Now, make up a matrix A to do the transformation
00456    vnl_double_3x3 A;
00457    A.set_identity();
00458    A[0][0] = a[0];  A[0][1] = a[1];  A[0][2] = a[2];
00459 
00460    // This is the affine correction matrix to be returned
00461    return A;
00462 }
00463 
00464 void vmal_rectifier::apply_affine_correction (
00465    vnl_double_3* points0,       // Points in one view
00466    vnl_double_3* points1,       // Points in the other view
00467    int numpoints,               // Number of matched points
00468    vnl_double_3x3 &H0, vnl_double_3x3 &H1   // The matrices to be returned
00469    )
00470 {
00471    // Correct H0 so that it matches with H1 best on the points given
00472    vnl_double_3x3 A = affine_correction (points0, points1, numpoints, H0, H1);
00473 
00474    // Now correct H0
00475    H1 = A * H1;
00476 
00477    // Make both H0 and H1 have positive determinant)
00478    if (vnl_determinant (H1) < 0.0) H1 = -H1;
00479 }
00480 
00481 void vmal_rectifier::rectify_rotate90 (
00482   int &height, int &width,
00483   vnl_double_3x3 &H0,
00484   vnl_double_3x3 &H1
00485   )
00486 {
00487    // Make a correction so that the horizontal lines come out horizontal
00488    // instead of vertical
00489 
00490    // Define a matrix for rotating the images
00491    vnl_double_3x3 R;
00492 
00493    // This line is commented out because height is not defined yet coming into
00494    // this routine. Hence, it's garbage.
00495    //   R[0][0] = 0.0;  R[0][1] = -1.0; R[0][2] = height;
00496    R[0][0] = 0.0;  R[0][1] = -1.0; R[0][2] = 0.0;
00497    R[1][0] = 1.0;  R[1][1] =  0.0; R[1][2] = 0.0;
00498    R[2][0] = 0.0;  R[2][1] =  0.0; R[2][2] = 1.0;
00499 
00500    // Multiply the matrices
00501    H0 = R * H0;
00502    H1 = R * H1;
00503 
00504    // Now return the output image dimensions
00505    int t = width; width = height; height = t;
00506 }
00507 
00508 // Not quite R. Hartley's implementation, but it works for me for now...
00509 // G.W. Brooksby
00510 void vmal_rectifier::conditional_rectify_rotate180 (
00511   vnl_double_3x3 &H0,
00512   vnl_double_3x3 &H1
00513   )
00514 {
00515    // Rotate by 180 degrees if needed
00516 
00517   if ( H1[0][0]/H1[2][2] > 0)
00518     return;
00519 
00520 
00521    // Define a matrix for rotating the images
00522    vnl_double_3x3 R;
00523 
00524    R[0][0] = -1.0;  R[0][1] = 0.0; R[0][2] = 0.0;
00525    R[1][0] = 0.0;  R[1][1] =  -1.0; R[1][2] = 0.0;
00526    R[2][0] = 0.0;  R[2][1] =  0.0; R[2][2] = 1.0;
00527 
00528    // Multiply the matrices
00529    H0 = R * H0;
00530    H1 = R * H1;
00531 }
00532 
00533 // vmal_rectifier::resample -
00534 // This routine takes two input transforms and images and resamples
00535 // the images according to the transforms.  The resultant images are returned
00536 // through the provided pointers.
00537 
00538 void vmal_rectifier::resample(vnl_double_3x3 H0, vnl_double_3x3 H1,
00539                               vil_image_view<vxl_byte> imgL,
00540                               vil_image_view<vxl_byte> imgR)
00541 {
00542   // Find the bound of the image to be resampled
00543   vnl_double_3 ipointL; // input and output image points
00544   vnl_double_3 opointL; // "input" = non-rectified image
00545   vnl_double_3 ipointR; // "output" = rectified image
00546   vnl_double_3 opointR;
00547   vbl_bounding_box<double,2> boxL;
00548   // Here we're presuming the two images are the same dimensions!
00549   int img_h = imgL.nj();
00550   int img_w = imgL.ni();
00551   for (int i=0; i<img_h; i++)
00552   {
00553     for (int j=0; j<img_w; j++)
00554     {
00555       ipointL[0]=j; ipointL[1]=i; ipointL[2]=1.0;
00556       ipointR[0]=j; ipointR[1]=i; ipointR[2]=1.0;
00557       opointL = H0 * ipointL;
00558       opointR = H1 * ipointR;
00559       opointL /= opointL[2]; // unhomogenize the point... [x,y,1.0]
00560       opointR /= opointR[2];
00561       // save the extremes for image sizing and bounds checking
00562       boxL.update(opointL[0],opointL[1]);
00563 //    boxR.update(opointR[0],opointR[1]);
00564     }
00565   }
00566 
00567   // Now we know the size of the image
00568   // Now do the warping
00569 
00570   // Find the mapping from rectified space back to the original
00571   // using the inverse of the transforms
00572   vnl_double_3x3 H0inv = vnl_inverse(H0);
00573   vnl_double_3x3 H1inv = vnl_inverse(H1);
00574 
00575   int img2_h = int(boxL.max()[1] - boxL.min()[1] + 1); // output image size
00576   int img2_w = int(boxL.max()[0] - boxL.min()[0] + 1); // (make them both the same)
00577   int planes=1;
00578 
00579   //re-size the images for the next iteration...
00580   rectL->set_size(img2_w,img2_h,planes);
00581   rectR->set_size(img2_w,img2_h,planes);
00582 
00583   for (int i=0; i<img2_h; i++)
00584   {
00585     for (int j=0; j<img2_w; j++)
00586     {
00587       // create the homogeneous point in rectified image(s)
00588       opointL[0]=j+boxL.min()[0]; opointL[1]=i+boxL.min()[1]; opointL[2]=1.0;
00589 
00590       // map it into the original image(s)
00591       ipointL = H0inv * opointL; ipointL /= ipointL[2]; // unhomogenize
00592       ipointR = H1inv * opointL; ipointR /= ipointR[2];
00593 
00594       // Bounds checking...
00595       if (ipointL[0] >= 0 && ipointL[0] < img_w-1 &&
00596           ipointL[1] >= 0 && ipointL[1] < img_h-1)
00597       {
00598         // interpolate the rectified image point from the original.
00599         (*rectL)(j,i) = (vxl_byte)vil_bilin_interp(imgL,ipointL[0],ipointL[1],0);
00600       }
00601       else
00602         (*rectL)(j,i) = vxl_byte(0);
00603 
00604       if (ipointR[0] >= 0 && ipointR[0] < img_w-1 &&
00605           ipointR[1] >= 0 && ipointR[1] < img_h-1)
00606       {
00607         // interpolate the rectified image point from the original.
00608         (*rectR)(j,i) = (vxl_byte)vil_bilin_interp(imgR,ipointR[0],ipointR[1],0);
00609       }
00610       else
00611         (*rectR)(j,i) = vxl_byte(0);
00612     }
00613   }
00614 }

Generated on Mon Oct 6 05:17:35 2008 for contrib/gel/vmal by  doxygen 1.5.1