00001
00002 #include "Probability.h"
00003
00004
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
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00051
00052
00053
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();
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
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
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
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
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
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
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 }