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     }
00093     else {
00094       random  = 1;
00095     }
00096 
00097     int row_num;
00098     if (buckets > 1) {
00099       row_num = random/buckets;
00100     }
00101     else {
00102       row_num = 0;
00103     }
00104     int col_num;
00105     if (buckets > 1) {
00106       col_num = random - row_num*buckets;
00107     }
00108     else {
00109       col_num = 0;
00110     }
00111 
00112     double row_check_lower = row_num * row_div;
00113     double col_check_lower = col_num * col_div;
00114     double row_check_upper = row_num * row_div + row_div;
00115     double col_check_upper = col_num * col_div + col_div;
00116     row_check_lower -= 1.0;
00117     col_check_lower -= 1.0;
00118     row_check_upper -= 1.0;
00119     col_check_upper -= 1.0;
00120 
00121     vcl_vector<int> list;
00122 
00123     // Select from the first list
00124     for (unsigned int j = 0; j < index.size(); j++) {
00125       double x = points_rescale[j][0], y = points_rescale[j][1];
00126       if (y >= row_check_lower && y < row_check_upper &&
00127           x >= col_check_lower && x < col_check_upper) {
00128         list.push_back(index[j]);
00129       }
00130     }
00131 #if 0 // was:
00132     for (int j = 0; j < index.size(); j++) {
00133       double x = points[j].x(), y = points[j].y(), w = points[j].w();
00134       if (w < 0) { x *= -1; y *= -1; w *= -1; }
00135       if (y >= row_check_lower*w && y < row_check_upper*w &&
00136           x >= col_check_lower*w && x < col_check_upper*w)
00137         list.push_back(index[j]);
00138     }
00139 #endif //********************************************
00140 
00141     int list_size = list.size();
00142     bool not_picked = true;
00143     if (list_size != 0) {
00144       int counter = 0;
00145       bool fail;
00146       while (not_picked && counter < list_size*4) {
00147         int pick = (int)((float)(list_size - 1)*vcl_rand()/(RAND_MAX+1.0));
00148         int picked = list[pick];
00149         fail = false;
00150         for (unsigned int k = 0; k < i; k++) {
00151           if (picked == out_points[k])
00152             fail = true;
00153         }
00154         if (!fail) {
00155           out_points[i] = picked;
00156           not_picked = false;
00157           i++;
00158         }
00159         else {
00160           counter++;
00161           //vcl_cerr << "Failed\n";
00162         }
00163       }
00164     }
00165     list.clear();
00166   }
00167 
00168   return out_points;
00169 }
00170 
00171 #if 0 // Note : this hasn't been implemented properly yet
00172 vcl_vector<HomgPoint2D> Taubins_MLE(HomgPoint2D x1, HomgPoint2D x2, FMatrix *F)
00173 {
00174   vcl_vector<HomgPoint2D> actual_points;
00175 
00176   // Generate a Jacobian matrix
00177   vnl_matrix<double> J;
00178   J.put(1, 1, (F->get(1, 1) - x2*F->get(3, 1)));
00179   J.put(1, 2, (F->get(1, 2) - x2*F->get(3, 2)));
00180   J.put(1, 3, (-x*F->get(3, 1) - y*F->get(3, 2) - F->get(3, 3)));
00181   J.put(1, 4, 0.0);
00182   J.put(2, 1, (F->get(2, 1) - y_dash*F->get(3, 1)));
00183   J.put(2, 2, (F->get(2, 2) - y_dash*F->get(3, 2)));
00184   J.put(2, 3, 0.0);
00185   J.put(2, 4, (-x*F->get(3, 1) - y_dash*F->get(3, 2) - F->get(3, 3)));
00186 
00187   // Find the Moore-Penrose Pseudo Inverse for the Jacobian matrix
00188   vnl_svd<double> svd(J, 1e-8);
00189   vnl_diag_matrix<double> diag = svd.W;
00190   for (int i = 0; i < diag.size(); i++) {
00191     if (diag(i, i) != 0.0)
00192       diag(i, i) = 1 / diag(i, i);
00193   }
00194   vnl_matrix<double> pseudo = svd.U * diag * svd.V.transpose();
00195 
00196   // Find the residuals
00197 
00198   return actual_points;
00199 }
00200 #endif
00201 
00202 double Sampsons_MLE(HomgPoint2D x1, HomgPoint2D x2, FMatrix *F)
00203 {
00204   double rX, rY, rX_dash, rY_dash, GRADr, r, dist;
00205   vnl_matrix_fixed<double,3,3> temp = F->get_matrix();
00206   vcl_cerr << x2.x() << vcl_endl;
00207   rX = temp.get(0, 0)*x2.x() + temp.get(1, 0)*x2.y() + temp.get(2, 0);
00208   rY = F->get(0, 1)*x2.x() + F->get(1, 1)*x2.y() + F->get(2, 1);
00209   rX_dash = F->get(0, 0)*x1.x() + F->get(0, 1)*x1.y() + F->get(0, 2);
00210   rY_dash = F->get(1, 0)*x1.x() + F->get(1, 1)*x1.y() + F->get(1, 2);
00211   vcl_cerr << "Points : " << rX << ' ' << rY << ' ' << rX_dash << ' ' << rY_dash << vcl_endl;
00212   GRADr = vnl_math_sqr(rX*rX + rY*rY + rX_dash*rX_dash + rY_dash*rY_dash);
00213   vcl_cerr << "1 :  " << GRADr << vcl_endl;
00214   // This is an annoying interface
00215   HomgPoint2D *x1p = new HomgPoint2D(x1.x(), x1.y(), 1.0);
00216   HomgPoint2D *x2p = new HomgPoint2D(x2.x(), x2.y(), 1.0);
00217   vcl_cerr << "2\n";
00218   r = F->image1_epipolar_distance_squared(x1p, x2p);
00219   vcl_cerr << "r " << r << vcl_endl;
00220   dist = r/GRADr;
00221   return dist;
00222 }