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 } 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
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
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
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
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
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
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 }