00001 #include "vmal_dense_matching.h"
00002 #include <vtol/vtol_edge_2d.h>
00003 #include <vmal/vmal_convert_vtol.h>
00004 #include <vmal/vmal_operators.h>
00005 #include <vnl/vnl_double_3.h>
00006 #include <vnl/vnl_int_3.h>
00007 #include <vnl/vnl_matrix.h>
00008 #include <vnl/vnl_inverse.h>
00009 #include <vil1/vil1_memory_image_of.h>
00010 #include <vil1/vil1_save.h>
00011
00012 #include <vcl_cmath.h>
00013
00014 vmal_dense_matching::vmal_dense_matching(const vnl_double_3x3 & H0,
00015 const vnl_double_3x3 & H1)
00016 {
00017 H0_=H0;
00018 H1_=H1;
00019 }
00020
00021 vmal_dense_matching::~vmal_dense_matching()
00022 {
00023 }
00024
00025 void vmal_dense_matching::set_fmatrix(const vnl_double_3x3 & F)
00026 {
00027 F_=F;
00028 type_=1;
00029 }
00030
00031 void vmal_dense_matching::set_hmatrix(const vnl_double_3x3 & H)
00032 {
00033 H_=H;
00034 type_=2;
00035 }
00036
00037
00038
00039 void vmal_dense_matching::refine_lines_using_F(vmal_multi_view_data_edge_sptr mvd_edge,
00040 vmal_multi_view_data_edge_sptr res)
00041 {
00042
00043
00044
00045 if (type_==1)
00046 {
00047 if (mvd_edge->get_nb_views()>1)
00048 {
00049 vnl_double_3* lines0_p;
00050 vnl_double_3* lines0_q;
00051 vnl_double_3* lines1_p;
00052 vnl_double_3* lines1_q;
00053
00054 vcl_vector<vtol_edge_2d_sptr> tmp_lines0;
00055 vcl_vector<vtol_edge_2d_sptr> tmp_lines1;
00056
00057 mvd_edge->get(0,1,tmp_lines0,tmp_lines1);
00058 int numlines=tmp_lines0.size();
00059
00060 convert_lines_double_3(tmp_lines0, lines0_p, lines0_q);
00061 convert_lines_double_3(tmp_lines1, lines1_p, lines1_q);
00062 double threshold=0.1745;
00063
00064 for (int i=0;i<numlines;i++)
00065 {
00066
00067
00068 vnl_double_3 epi_line1p=F_*lines0_p[i];
00069 vnl_double_3 epi_line1q=F_*lines0_q[i];
00070 vnl_double_3 epi_line0p=(F_.transpose()*lines1_p[i]);
00071 vnl_double_3 epi_line0q=(F_.transpose()*lines1_q[i]);
00072
00073
00074 vnl_double_3 pt0p=lines0_p[i];
00075 vnl_double_3 pt0q=lines0_q[i];
00076 vnl_double_3 pt1p=lines1_p[i];
00077 vnl_double_3 pt1q=lines1_q[i];
00078
00079 vnl_double_3 inter1p;
00080 vnl_double_3 inter1q;
00081
00082 double alpha,beta;
00083
00084 if (vmal_operators::line_cross_seg(lines1_p[i], lines1_q[i], epi_line1p, inter1p,alpha))
00085 if (vmal_operators::line_cross_seg(lines1_p[i], lines1_q[i], epi_line1q, inter1q,beta))
00086 {
00087
00088 vmal_operators::line_cross_seg(lines0_p[i], lines0_q[i], epi_line0p, pt0p,alpha);
00089 vmal_operators::line_cross_seg(lines0_p[i], lines0_q[i], epi_line0q, pt0q,beta);
00090 }
00091 else
00092 {
00093
00094 vmal_operators::line_cross_seg(lines0_p[i], lines0_q[i], epi_line0p, pt0p, alpha);
00095 pt1q=inter1q;
00096 }
00097 else
00098 if (vmal_operators::line_cross_seg(lines1_p[i], lines1_q[i], epi_line1q, inter1q, beta))
00099 {
00100
00101 vmal_operators::line_cross_seg(lines0_p[i], lines0_q[i], epi_line0q, pt0q, beta);
00102 pt1p=inter1p;
00103 }
00104 else
00105 {
00106
00107 pt1p=inter1p;
00108 pt1q=inter1q;
00109 }
00110
00111 if (alpha>threshold && beta>threshold)
00112 {
00113 res->new_track();
00114 vtol_edge_2d_sptr out0=new vtol_edge_2d(pt0p[0],pt0p[1],pt0q[0],pt0q[1]);
00115 vtol_edge_2d_sptr out1=new vtol_edge_2d(pt1p[0],pt1p[1],pt1q[0],pt1q[1]);
00116 res->set(0,out0);
00117 res->set(1,out1);
00118 res->close_track();
00119 }
00120 }
00121 }
00122 }
00123 else
00124 vcl_cerr<<"Error: you must set the Fundamental matrix to use this method.\n";
00125 }
00126
00127
00128
00129 void vmal_dense_matching::refine_lines_using_H(vmal_multi_view_data_edge_sptr mvd_edge,
00130 vmal_multi_view_data_edge_sptr res)
00131 {
00132
00133 if (type_==2)
00134 {
00135 if (mvd_edge->get_nb_views()>1)
00136 {
00137 vnl_double_3* lines0_p;
00138 vnl_double_3* lines0_q;
00139 vnl_double_3* lines1_p;
00140 vnl_double_3* lines1_q;
00141
00142 vcl_vector<vtol_edge_2d_sptr> tmp_lines0;
00143 vcl_vector<vtol_edge_2d_sptr> tmp_lines1;
00144
00145 mvd_edge->get(0,1,tmp_lines0,tmp_lines1);
00146 int numlines=tmp_lines0.size();
00147
00148 convert_lines_double_3(tmp_lines0, lines0_p, lines0_q);
00149 convert_lines_double_3(tmp_lines1, lines1_p, lines1_q);
00150
00151 vnl_double_3x3 HI=vnl_inverse(H_);
00152 for (int i=0;i<numlines;i++)
00153 {
00154 vnl_double_3 pt0p=lines0_p[i];
00155 vnl_double_3 pt0q=lines0_q[i];
00156 vnl_double_3 pt1p=lines1_p[i];
00157 vnl_double_3 pt1q=lines1_q[i];
00158
00159 vnl_double_3 h_lines1_p=H_*lines0_p[i];
00160 vnl_double_3 h_lines1_q=H_*lines0_q[i];
00161 vnl_double_3 h_lines0_p=HI*lines1_p[i];
00162 vnl_double_3 h_lines0_q=HI*lines1_q[i];
00163
00164 vnl_double_3 inter1p;
00165 vnl_double_3 inter1q;
00166
00167 if (vmal_operators::project_point(h_lines1_p,lines1_p[i],lines1_q[i],inter1p))
00168 {
00169 if (vmal_operators::project_point(h_lines1_q,lines1_p[i],lines1_q[i],inter1q))
00170 {
00171
00172 vmal_operators::project_point(h_lines0_p,lines0_p[i],lines0_q[i],pt0p);
00173 vmal_operators::project_point(h_lines0_q,lines0_p[i],lines0_q[i],pt0q);
00174 }
00175 else
00176 {
00177
00178 vmal_operators::project_point(h_lines0_p,lines0_p[i],lines0_q[i],pt0p);
00179 pt1q=inter1q;
00180 }
00181 }
00182 else
00183 {
00184 if (vmal_operators::project_point(h_lines1_q,lines1_p[i],lines1_q[i],inter1q))
00185 {
00186
00187 pt1p=inter1p;
00188 vmal_operators::project_point(h_lines0_q,lines0_p[i],lines0_q[i],pt0q);
00189 }
00190 else
00191 {
00192
00193 pt1p=inter1p;
00194 pt1q=inter1q;
00195 }
00196 }
00197
00198 res->new_track();
00199 vtol_edge_2d_sptr out0=new vtol_edge_2d(pt0p[0],pt0p[1],pt0q[0],pt0q[1]);
00200 vtol_edge_2d_sptr out1=new vtol_edge_2d(pt1p[0],pt1p[1],pt1q[0],pt1q[1]);
00201 res->set(0,out0);
00202 res->set(1,out1);
00203 res->close_track();
00204 }
00205 }
00206 }
00207 else
00208 vcl_cerr<<"Error: you must set the Homography matrix to use this method.\n";
00209 }
00210
00211
00212 void vmal_dense_matching::disparity_map(vmal_multi_view_data_edge_sptr mvd_edge,
00213 int h,int w)
00214 {
00215 vnl_double_3* lines0_p;
00216 vnl_double_3* lines0_q;
00217 vnl_double_3* lines1_p;
00218 vnl_double_3* lines1_q;
00219
00220 int disparity, min_disparity=0,max_disparity=0;
00221
00222 vcl_vector<vtol_edge_2d_sptr> tmp_lines0;
00223 vcl_vector<vtol_edge_2d_sptr> tmp_lines1;
00224
00225 mvd_edge->get(0,1,tmp_lines0,tmp_lines1);
00226 int numlines=tmp_lines0.size();
00227
00228 convert_lines_double_3(tmp_lines0, lines0_p, lines0_q);
00229 convert_lines_double_3(tmp_lines1, lines1_p, lines1_q);
00230
00231 vnl_double_3x3 IH0=vnl_inverse(H0_);
00232
00233 vnl_double_3 int_line0p;
00234 vnl_double_3 int_line0q;
00235 vnl_double_3 int_line1p;
00236 vnl_double_3 int_line1q;
00237
00238 vnl_double_3 point0;
00239 vnl_double_3 point1;
00240 vnl_double_3 t_point0, t_point1;
00241 vnl_int_3 int_t_point0, int_t_point1;
00242
00243 double a0,b0,a1,b1;
00244 double delta0x,delta0y,delta1x,delta1y;
00245
00246 vnl_matrix<int> map(w,h);
00247 map.fill(0);
00248
00249 for (int i=0;i<numlines;i++)
00250 {
00251 int_line0p[0]=vmal_round(lines0_p[i][0]);
00252 int_line0p[1]=vmal_round(lines0_p[i][1]);
00253 int_line0p[2]=1.0;
00254 int_line0q[0]=vmal_round(lines0_q[i][0]);
00255 int_line0q[1]=vmal_round(lines0_q[i][1]);
00256 int_line0q[2]=1.0;
00257
00258 int_line1p[0]=vmal_round(lines1_p[i][0]);
00259 int_line1p[1]=vmal_round(lines1_p[i][1]);
00260 int_line1p[2]=1.0;
00261 int_line1q[0]=vmal_round(lines1_q[i][0]);
00262 int_line1q[1]=vmal_round(lines1_q[i][1]);
00263 int_line1q[2]=1.0;
00264
00265 double num0=int_line0p[0]-int_line0q[0];
00266 double num1=int_line1p[0]-int_line1q[0];
00267
00268 a0=(int_line0p[1]-int_line0q[1])/num0;
00269 a1=(int_line1p[1]-int_line1q[1])/num1;
00270 b0=int_line0p[1]-a0*int_line0p[0];
00271 b1=int_line1p[1]-a1*int_line1p[0];
00272
00273 if ((int_line0q[0]-int_line0p[0])>0)
00274 delta0x=0.5;
00275 else
00276 delta0x=-0.5;
00277 if ((int_line0q[1]-int_line0p[1])>0)
00278 delta0y=0.5;
00279 else
00280 delta0y=-0.5;
00281
00282 if ((int_line1q[0]-int_line1p[0])>0)
00283 delta1x=0.5;
00284 else
00285 delta1x=-0.5;
00286 if ((int_line1q[1]-int_line1p[1])>0)
00287 delta1y=0.5;
00288 else
00289 delta1y=-0.5;
00290
00291 point0=int_line0p;
00292 point1=int_line1p;
00293
00294 while (point0!=int_line0q)
00295 {
00296 if (num0!=0.0)
00297 if (vcl_fabs(((point0[0]+delta0x)*a0+b0)-point0[1])<=0.5)
00298 point0[0]+=delta0x*2;
00299 else
00300 point0[1]+=delta0y*2;
00301 else
00302 point0[1]+=delta0y*2;
00303
00304 if (num1!=0.0) {
00305 if (vcl_fabs(((point1[0]+delta1x)*a1+b1)-point1[1])<=0.5)
00306 point1[0]+=delta1x*2;
00307 else
00308 point1[1]+=delta1y*2;
00309 }
00310 else
00311 point1[1]+=delta1y*2;
00312
00313 t_point0=H0_*point0;
00314 t_point1=H1_*point1;
00315 int_t_point0[0]=(int)vmal_round(t_point0[0]/t_point0[2]);
00316 int_t_point0[1]=(int)vmal_round(t_point0[1]/t_point0[2]);
00317 int_t_point1[0]=(int)vmal_round(t_point1[0]/t_point1[2]);
00318 int_t_point1[1]=(int)vmal_round(t_point1[1]/t_point1[2]);
00319
00320
00321 disparity=1;
00322 map(vmal_round_int(point0[0]),vmal_round_int(point0[1]))=disparity;
00323 if (disparity<min_disparity)
00324 min_disparity=disparity;
00325 if (disparity>max_disparity)
00326 max_disparity=disparity;
00327 }
00328 }
00329 vcl_cerr<<"Disparity min: "<<min_disparity<<'\n'
00330 <<"Disparity max: "<<max_disparity<<'\n';
00331
00332
00333 max_disparity-=min_disparity;
00334 unsigned char* buf=new unsigned char[w*h];
00335 for (int i=0; i<h; i++)
00336 {
00337 for (int j=0; j<w; j++)
00338 {
00339 int value=vmal_round_int((map(j,i)-min_disparity)*255/max_disparity);
00340 buf[i*w+j]=(unsigned char)value;
00341 }
00342 }
00343 vil1_memory_image_of<vxl_byte> ima(buf, w, h);
00344 vil1_save(ima, "lolo.pgm");
00345 delete [] buf;
00346 }
00347
00348
00349 double vmal_round(double a)
00350 {
00351 return (a>0) ? double(int(a+0.5)) : double(int(a-0.5));
00352 }
00353
00354 int vmal_round_int(double a)
00355 {
00356 return (a>0) ? int(a+0.5) : int(a-0.5);
00357 }