contrib/oxl/mvl/Probability.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/Probability.cxx
00002 #include "Probability.h"
00003 //:
00004 // \file
00005 
00006 #include <vcl_cstdlib.h>
00007 #include <vcl_vector.h>
00008 #include <vcl_iostream.h>
00009 #include <vcl_cassert.h>
00010 
00011 #include <vnl/vnl_matrix.h>
00012 #include <vnl/vnl_diag_matrix.h>
00013 #include <vnl/vnl_math.h>
00014 
00015 #include <mvl/HomgPoint2D.h>
00016 #include <mvl/FMatrix.h>
00017 
00018 //:
00019 // Randomly select samples points from the screen size of row_size & col_size
00020 // bucketed symmetrically with buckets partitions on the area.
00021 // Note that no two selected points can lie in the same bucketed partition.
00022 //
00023 // Watch this routine, if the given points are not dispersed
00024 // uniformly enough across the given distribution then the routine will
00025 // not exit, rather keep searching for the requested number of subsamples.
00026 //
00027 // Fixed => RESCALE ALL THE POINTS TO FIT -1,1(x) -1,1(y)
00028 // IT IS SUPPOSED THAT THE CENTER OF THE POINTS IS (0,0)
00029 
00030 vcl_vector<int> Monte_Carlo(vcl_vector<HomgPoint2D> points, vcl_vector<int> index, int buckets, int samples)
00031 {
00032   assert(samples > 0);
00033   double row_size = 2.0;
00034   double col_size = 2.0;
00035   vcl_vector<int> out_points(samples);
00036   double row_div = row_size/buckets;
00037   double col_div = col_size/buckets;
00038   int no_buckets = buckets*buckets;
00039   if (buckets < 1) {
00040     vcl_cerr << "Warning Monte Carlo sampling will not work.\n"
00041              << "Not enough buckets: need 1, have " << buckets << ".\n";
00042   }
00043   if (index.size() < (unsigned int)samples) {
00044     vcl_cerr << "Warning Monte Carlo sampling will not work.\n"
00045              << "Not enough points to choose from: need " << samples
00046              << ", have " << index.size() << ".\n";
00047   }
00048 
00049   //
00050   //  RESCALE AND CENTER THE POINTS
00051   //
00052   //  Store the modified points in the new list "points_rescale"
00053   //  for use in the test condition only
00054   //
00055 
00056   double max_x = -1e31, max_y = -1e31, min_x = 1e31, min_y = 1e31;
00057 
00058   for (unsigned int i=0;i<index.size();i++)
00059   {
00060     if ( points[i].x() > max_x )
00061       max_x = points[i].x();
00062 
00063     if ( points[i].y() > max_y )
00064       max_y = points[i].y();
00065 
00066     if ( points[i].x() < min_x )
00067       min_x = points[i].x();
00068 
00069     if ( points[i].y() < min_y )
00070       min_y = points[i].y();
00071   }
00072 
00073   double center_x = ( max_x - min_x ) * 0.5;
00074   double center_y = ( max_y - min_y ) * 0.5;
00075 
00076   vcl_vector<vnl_double_2> points_rescale;
00077   for (unsigned int i=0;i<index.size();i++)
00078   {
00079     vnl_double_2 v = points[i].get_double2(); // non-homogeneous representation
00080     double x = -1.0 + ( v[0] - min_x ) / center_x;
00081     double y = -1.0 + ( v[1] - min_y ) / center_y;
00082     points_rescale.push_back( vnl_double_2( x, y ) );
00083   }
00084 
00085   // ********************* //
00086 
00087   for (unsigned int i=0; i < (unsigned int)samples; )
00088   {
00089     int random;
00090     if (buckets > 1) {
00091       random  = (int)((float)(no_buckets - 1)*vcl_rand()/(RAND_MAX+1.0));
00092     } else {
00093       random  = 1;
00094     }
00095 
00096     int row_num;
00097     if (buckets > 1) {
00098       row_num = random/buckets;
00099     } else {
00100       row_num = 0;
00101     }
00102     int col_num;
00103     if (buckets > 1) {
00104       col_num = random - row_num*buckets;
00105     } else {
00106       col_num = 0;
00107     }
00108 
00109     double row_check_lower = row_num * row_div;
00110     double col_check_lower = col_num * col_div;
00111     double row_check_upper = row_num * row_div + row_div;
00112     double col_check_upper = col_num * col_div + col_div;
00113     row_check_lower -= 1.0;
00114     col_check_lower -= 1.0;
00115     row_check_upper -= 1.0;
00116     col_check_upper -= 1.0;
00117 
00118     vcl_vector<int> list;
00119 
00120     // Select from the first list
00121     for (unsigned int j = 0; j < index.size(); j++) {
00122       double x = points_rescale[j][0], y = points_rescale[j][1];
00123       if (y >= row_check_lower && y < row_check_upper &&
00124           x >= col_check_lower && x < col_check_upper) {
00125         list.push_back(index[j]);
00126       }
00127     }
00128 #if 0 // was:
00129     for (int j = 0; j < index.size(); j++) {
00130       double x = points[j].x(), y = points[j].y(), w = points[j].w();
00131       if (w < 0) { x *= -1; y *= -1; w *= -1; }
00132       if (y >= row_check_lower*w && y < row_check_upper*w &&
00133           x >= col_check_lower*w && x < col_check_upper*w)
00134         list.push_back(index[j]);
00135     }
00136 #endif //********************************************
00137 
00138     int list_size = list.size();
00139     bool not_picked = true;
00140     if (list_size != 0) {
00141       int counter = 0;
00142       bool fail;
00143       while (not_picked && counter < list_size*4) {
00144         int pick = (int)((float)(list_size - 1)*vcl_rand()/(RAND_MAX+1.0));
00145         int picked = list[pick];
00146         fail = false;
00147         for (unsigned int k = 0; k < i; k++) {
00148           if (picked == out_points[k])
00149             fail = true;
00150         }
00151         if (!fail) {
00152           out_points[i] = picked;
00153           not_picked = false;
00154           i++;
00155         } else {
00156           counter++;
00157           //vcl_cerr << "Failed\n";
00158         }
00159       }
00160     }
00161     list.clear();
00162   }
00163 
00164   return out_points;
00165 }
00166 
00167 #if 0 // Note : this hasn't been implemented properly yet
00168 vcl_vector<HomgPoint2D> Taubins_MLE(HomgPoint2D x1, HomgPoint2D x2, FMatrix *F)
00169 {
00170   vcl_vector<HomgPoint2D> actual_points;
00171 
00172   // Generate a Jacobian matrix
00173   vnl_matrix<double> J;
00174   J.put(1, 1, (F->get(1, 1) - x2*F->get(3, 1)));
00175   J.put(1, 2, (F->get(1, 2) - x2*F->get(3, 2)));
00176   J.put(1, 3, (-x*F->get(3, 1) - y*F->get(3, 2) - F->get(3, 3)));
00177   J.put(1, 4, 0.0);
00178   J.put(2, 1, (F->get(2, 1) - y_dash*F->get(3, 1)));
00179   J.put(2, 2, (F->get(2, 2) - y_dash*F->get(3, 2)));
00180   J.put(2, 3, 0.0);
00181   J.put(2, 4, (-x*F->get(3, 1) - y_dash*F->get(3, 2) - F->get(3, 3)));
00182 
00183   // Find the Moore-Penrose Pseudo Inverse for the Jacobian matrix
00184   vnl_svd<double> svd(J, 1e-8);
00185   vnl_diag_matrix<double> diag = svd.W;
00186   for (int i = 0; i < diag.size(); i++) {
00187     if (diag(i, i) != 0.0)
00188       diag(i, i) = 1 / diag(i, i);
00189   }
00190   vnl_matrix<double> pseudo = svd.U * diag * svd.V.transpose();
00191 
00192   // Find the residuals
00193 
00194   return actual_points;
00195 }
00196 #endif
00197 
00198 double Sampsons_MLE(HomgPoint2D x1, HomgPoint2D x2, FMatrix *F)
00199 {
00200   double rX, rY, rX_dash, rY_dash, GRADr, r, dist;
00201   vnl_matrix<double> temp(3, 3);
00202   temp = (vnl_matrix<double>)F->get_matrix();
00203   vcl_cerr << x2.x() << vcl_endl;
00204   rX = temp.get(0, 0)*x2.x() + temp.get(1, 0)*x2.y() + temp.get(2, 0);
00205   rY = F->get(0, 1)*x2.x() + F->get(1, 1)*x2.y() + F->get(2, 1);
00206   rX_dash = F->get(0, 0)*x1.x() + F->get(0, 1)*x1.y() + F->get(0, 2);
00207   rY_dash = F->get(1, 0)*x1.x() + F->get(1, 1)*x1.y() + F->get(1, 2);
00208   vcl_cerr << "Points : " << rX << ' ' << rY << ' ' << rX_dash << ' ' << rY_dash << vcl_endl;
00209   GRADr = vnl_math_sqr(rX*rX + rY*rY + rX_dash*rX_dash + rY_dash*rY_dash);
00210   vcl_cerr << "1 :  " << GRADr << vcl_endl;
00211   // This is an annoying interface
00212   HomgPoint2D *x1p = new HomgPoint2D(x1.x(), x1.y(), 1.0);
00213   HomgPoint2D *x2p = new HomgPoint2D(x2.x(), x2.y(), 1.0);
00214   vcl_cerr << "2\n";
00215   r = F->image1_epipolar_distance_squared(x1p, x2p);
00216   vcl_cerr << "r " << r << vcl_endl;
00217   dist = r/GRADr;
00218   return dist;
00219 }