00001
00002 #include "vgel_kl.h"
00003
00004 #include <vxl_config.h>
00005 #include <vil1/vil1_pixel.h>
00006 #include <vil1/vil1_memory_image_of.h>
00007 #include <vil1/vil1_image_as.h>
00008 #include <vil/vil_image_view.h>
00009 #include <vil/vil_image_resource.h>
00010 #include <vil/vil_new.h>
00011 #include <vil/vil_convert.h>
00012 #include <vgel/vgel_multi_view_data.h>
00013 #include <vtol/vtol_vertex_2d.h>
00014 #include <vidl_vil1/vidl_vil1_frame.h>
00015 #include <vidl_vil1/vidl_vil1_movie.h>
00016 #include <vidl/vidl_movie.h>
00017
00018 #include <vcl_deprecated.h>
00019 #include <vcl_iostream.h>
00020 #include <vcl_cassert.h>
00021
00022 vgel_kl::vgel_kl(const vgel_kl_params & params) : params_(params)
00023 {
00024 prev_frame_ = NULL;
00025 seq_tc_ = NULL;
00026 fl_ = NULL;
00027 }
00028
00029 vgel_kl::~vgel_kl()
00030 {
00031 reset_prev_frame();
00032 }
00033
00034 void vgel_kl::reset_prev_frame()
00035 {
00036 if (prev_frame_)
00037 {
00038 delete prev_frame_;
00039 prev_frame_ = NULL;
00040 }
00041 if (seq_tc_)
00042 {
00043 KLTFreeTrackingContext(seq_tc_);
00044 seq_tc_ = NULL;
00045 }
00046 if (fl_)
00047 {
00048 KLTFreeFeatureList(fl_);
00049 fl_ = NULL;
00050 }
00051 }
00052
00053 void vgel_kl::match_sequence(
00054 vil1_image& prev_img,
00055 vil1_image& cur_img,
00056 vgel_multi_view_data_vertex_sptr matches,
00057 bool use_persistent_features)
00058 {
00059 VXL_DEPRECATED( "vgel_kl::match_sequence(vil1_image&, vil1_image&, vgel_multi_view_data_vertex_sptr, bool)" );
00060
00061
00062
00063
00064 int width = cur_img.width();
00065 int height = cur_img.height();
00066 KLT_PixelType * prev_img_gs = NULL;
00067 KLT_PixelType * cur_img_gs = convert_to_gs_image(cur_img);
00068 if (!prev_frame_) {
00069 assert (width == prev_img.width());
00070 assert (height == prev_img.height());
00071 prev_img_gs = convert_to_gs_image(prev_img);
00072 }
00073 match_sequence_base (prev_img_gs, cur_img_gs, width, height, matches, use_persistent_features);
00074 }
00075
00076 void vgel_kl::match_sequence(
00077 vil_image_resource_sptr& prev_img,
00078 vil_image_resource_sptr& cur_img,
00079 vgel_multi_view_data_vertex_sptr matches,
00080 bool use_persistent_features)
00081 {
00082 int width = (*cur_img).ni();
00083 int height = (*cur_img).nj();
00084 KLT_PixelType * prev_img_gs = NULL;
00085 KLT_PixelType * cur_img_gs = convert_to_gs_image(cur_img);
00086 if (!prev_frame_) {
00087 assert (width == int((*prev_img).ni()));
00088 assert (height == int((*prev_img).nj()));
00089 prev_img_gs = convert_to_gs_image(prev_img);
00090 }
00091 match_sequence_base (prev_img_gs, cur_img_gs, width, height, matches, use_persistent_features);
00092 }
00093
00094 void vgel_kl::match_sequence(
00095 vil_image_view<vxl_byte>* prev_img,
00096 vil_image_view<vxl_byte>* cur_img,
00097 vgel_multi_view_data_vertex_sptr matches,
00098 bool use_persistent_features)
00099 {
00100 int width = (*cur_img).ni();
00101 int height = (*cur_img).nj();
00102 KLT_PixelType * prev_img_gs = NULL;
00103 KLT_PixelType * cur_img_gs = convert_to_gs_image(cur_img);
00104 if (!prev_frame_) {
00105 assert (width == int((*prev_img).ni()));
00106 assert (height == int((*prev_img).nj()));
00107 prev_img_gs = convert_to_gs_image(prev_img);
00108 }
00109 match_sequence_base (prev_img_gs, cur_img_gs, width, height, matches, use_persistent_features);
00110 }
00111
00112 void vgel_kl::match_sequence_base(
00113 KLT_PixelType * prev_img_gs,
00114 KLT_PixelType * cur_img_gs,
00115 int width,
00116 int height,
00117 vgel_multi_view_data_vertex_sptr matches,
00118 bool use_persistent_features)
00119 {
00120
00121 KLT_PixelType* cur_frame = cur_img_gs;
00122
00123 if (use_persistent_features)
00124 {
00125
00126 if (!fl_)
00127 {
00128
00129 fl_ = KLTCreateFeatureList(params_.numpoints);
00130 }
00131 }
00132 else
00133 {
00134
00135 fl_ = KLTCreateFeatureList(params_.numpoints);
00136 }
00137
00138
00139 if (!prev_frame_)
00140 {
00141
00142 prev_frame_ = prev_img_gs;
00143
00144
00145 if (seq_tc_ != NULL)
00146 {
00147 KLTFreeTrackingContext(seq_tc_);
00148 }
00149 seq_tc_ = KLTCreateTrackingContext();
00150 set_tracking_context(seq_tc_);
00151 seq_tc_->sequentialMode = TRUE;
00152
00153 if (use_persistent_features)
00154 {
00155
00156 KLTSelectGoodFeatures(seq_tc_, prev_frame_, width, height, fl_);
00157 }
00158 }
00159
00160 if (!use_persistent_features)
00161 {
00162 KLTReplaceLostFeatures(seq_tc_, prev_frame_, width, height, fl_);
00163 }
00164
00165
00166 KLT_FeatureTable ft = KLTCreateFeatureTable(2, params_.numpoints);
00167
00168
00169 KLTStoreFeatureList(fl_, ft, 0);
00170
00171
00172 KLTTrackFeatures(seq_tc_, prev_frame_, cur_frame, width, height, fl_);
00173
00174 if (use_persistent_features)
00175 {
00176
00177 if (params_.replaceLostPoints)
00178 {
00179 KLTReplaceLostFeatures(seq_tc_, cur_frame, width, height, fl_);
00180 }
00181 }
00182
00183
00184 KLTStoreFeatureList(fl_, ft, 1);
00185
00186 if (matches)
00187 {
00188
00189 matches_from_feature_table(ft, matches);
00190 }
00191
00192
00193 KLTFreeFeatureTable(ft);
00194
00195 if (use_persistent_features)
00196 {
00197
00198
00199 for (int pointnum = 0; pointnum < fl_->nFeatures; pointnum++)
00200 {
00201 fl_->feature[pointnum]->val = 1;
00202 }
00203 }
00204 else
00205 {
00206
00207 KLTFreeFeatureList(fl_);
00208 fl_ = NULL;
00209 }
00210
00211
00212
00213 delete prev_frame_;
00214 prev_frame_ = cur_frame;
00215 }
00216
00217 void vgel_kl::match_sequence(
00218 vcl_vector<vil1_image> & image_list,
00219 vgel_multi_view_data_vertex_sptr matches)
00220 {
00221 VXL_DEPRECATED( "vgel_kl::match_sequence(vcl_vector<vil1_image> &, vgel_multi_view_data_vertex_sptr)" );
00222
00223 vcl_vector<KLT_PixelType *> image_list_gs(image_list.size());
00224 int width = image_list[0].width();
00225 int height = image_list[0].height();
00226 for (unsigned n=0; n<image_list.size(); n++) {
00227 assert (width == image_list[n].width());
00228 assert (height == image_list[n].height());
00229 image_list_gs[n] = convert_to_gs_image(image_list[n]);
00230 }
00231 match_sequence_base (image_list_gs, width, height, matches);
00232 }
00233
00234 void vgel_kl::match_sequence(
00235 vcl_vector<vil_image_resource_sptr> & image_list,
00236 vgel_multi_view_data_vertex_sptr matches)
00237 {
00238 vcl_vector<KLT_PixelType *> image_list_gs(image_list.size());
00239 int width = (*image_list[0]).ni();
00240 int height = (*image_list[0]).nj();
00241 for (unsigned n=0; n<image_list.size(); n++) {
00242 assert (width == int((*image_list[1]).ni()));
00243 assert (height == int((*image_list[1]).nj()));
00244 image_list_gs[n] = convert_to_gs_image(image_list[n]);
00245 }
00246 match_sequence_base (image_list_gs, width, height, matches);
00247 }
00248
00249 void vgel_kl::match_sequence_base(
00250 vcl_vector<KLT_PixelType *> & image_list_gs,
00251 int width,
00252 int height,
00253 vgel_multi_view_data_vertex_sptr matches)
00254 {
00255
00256 int nFeatures = params_.numpoints;
00257 int nFrames = image_list_gs.size();
00258
00259
00260 if (nFrames < 1) return;
00261
00262
00263 KLT_TrackingContext tc = KLTCreateTrackingContext();
00264 KLT_FeatureList fl = KLTCreateFeatureList(nFeatures);
00265 KLT_FeatureTable ft = KLTCreateFeatureTable(nFrames, nFeatures);
00266
00267
00268 set_tracking_context (tc);
00269 tc->sequentialMode = TRUE;
00270
00271
00272 KLT_PixelType* img1=image_list_gs[0];
00273
00274
00275 KLTSelectGoodFeatures(tc, img1, width, height, fl);
00276 KLTStoreFeatureList(fl, ft, 0);
00277
00278 for (int i=1; i<nFrames; i++)
00279 {
00280 KLT_PixelType* img2=image_list_gs[i];
00281
00282
00283 KLTTrackFeatures(tc, img1, img2, width, height, fl);
00284
00285
00286 if (params_.replaceLostPoints)
00287 KLTReplaceLostFeatures(tc, img2, width, height, fl);
00288
00289
00290 KLTStoreFeatureList(fl, ft, i);
00291
00292
00293
00294 delete img2;
00295 }
00296
00297
00298
00299 delete img1;
00300 KLTFreeTrackingContext(tc);
00301
00302
00303 matches_from_feature_table(ft, matches);
00304
00305
00306
00307 KLTFreeFeatureList(fl);
00308 KLTFreeFeatureTable(ft);
00309 }
00310
00311 void vgel_kl::matches_from_feature_table(KLT_FeatureTable ft,
00312 vgel_multi_view_data_vertex_sptr matches)
00313 {
00314 int matchnum = -1;
00315 int pointnum;
00316 int viewnum;
00317
00318 for (pointnum = 0; pointnum < ft->nFeatures; pointnum++)
00319 {
00320 for (viewnum = 0; viewnum < ft->nFrames; viewnum++)
00321 {
00322
00323 KLT_Feature feat = ft->feature[pointnum][viewnum];
00324
00325
00326 float x = feat->x;
00327 float y = feat->y;
00328
00329
00330
00331
00332
00333
00334 if (feat->val == 0)
00335 {
00336 vtol_vertex_2d_sptr vertex = new vtol_vertex_2d(x, y);
00337
00338
00339 matches->set(viewnum, matchnum, vertex);
00340 }
00341
00342 else if (feat->val > 0)
00343 {
00344
00345
00346 if ((viewnum < ft->nFrames - 1) &&
00347 (ft->feature[pointnum][viewnum + 1]->val == 0))
00348 {
00349
00350 matchnum++;
00351
00352
00353 vtol_vertex_2d_sptr vertex = new vtol_vertex_2d(x, y);
00354
00355
00356 matches->set(viewnum, matchnum, vertex);
00357 }
00358 }
00359 }
00360 }
00361
00362 #if 0
00363
00364 matches->renumber();
00365 #endif
00366 }
00367
00368 void vgel_kl::match_sequence(vidl_vil1_movie_sptr movie,
00369 vgel_multi_view_data_vertex_sptr matches)
00370 {
00371 VXL_DEPRECATED( "vgel_kl::match_sequence(vidl_vil1_movie_sptr, vgel_multi_view_data_vertex_sptr)" );
00372
00373 vcl_vector<vil1_image> image_list;
00374 for (vidl_vil1_movie::frame_iterator pframe = movie->first();
00375 pframe <= movie->last();
00376 ++pframe)
00377 {
00378 vil1_image im = vil1_image(pframe->get_image());
00379 image_list.push_back(im);
00380 }
00381 match_sequence(image_list,matches);
00382 }
00383
00384 void vgel_kl::match_sequence(vidl_movie_sptr movie,
00385 vgel_multi_view_data_vertex_sptr matches)
00386 {
00387 vcl_vector<vil_image_resource_sptr> image_list;
00388 for (vidl_movie::frame_iterator pframe = movie->first();
00389 pframe <= movie->last();
00390 ++pframe)
00391 {
00392 vil_image_resource_sptr im = vil_new_image_resource_of_view (*pframe->get_view());
00393 image_list.push_back(im);
00394 }
00395 match_sequence(image_list,matches);
00396 }
00397
00398 vcl_vector<vtol_vertex_2d_sptr>* vgel_kl::extract_points(vil1_image & image)
00399 {
00400 VXL_DEPRECATED( "vgel_kl::extract_points(vil1_image &)" );
00401
00402 int width=image.width();
00403 int height=image.height();
00404 KLT_PixelType* image_gs=convert_to_gs_image(image);
00405 return extract_points_base (image_gs, width, height);
00406 }
00407
00408 vcl_vector<vtol_vertex_2d_sptr>* vgel_kl::extract_points(vil_image_resource_sptr & image)
00409 {
00410 int width=(*image).ni();
00411 int height=(*image).nj();
00412 KLT_PixelType* image_gs=convert_to_gs_image(image);
00413 return extract_points_base (image_gs, width, height);
00414 }
00415
00416 vcl_vector<vtol_vertex_2d_sptr>* vgel_kl::extract_points_base(KLT_PixelType * image_gs, int width, int height)
00417 {
00418 vcl_cerr << "Beginning points extraction\n";
00419
00420 KLT_PixelType* img1=image_gs;
00421
00422
00423 int nFeatures = params_.numpoints;
00424
00425 vcl_cerr << "Setting up the context...\n";
00426
00427 KLT_TrackingContext tc = KLTCreateTrackingContext();
00428
00429
00430 set_tracking_context (tc);
00431
00432
00433
00434
00435 vcl_cerr << "Setting up structure to hold the features...\n";
00436 KLT_FeatureList fl = KLTCreateFeatureList(nFeatures);
00437
00438
00439 vcl_cerr << "Extracting the features...\n";
00440 KLTSelectGoodFeatures(tc, img1, width, height, fl);
00441
00442
00443 vcl_vector<vtol_vertex_2d_sptr> *grp = new vcl_vector<vtol_vertex_2d_sptr>();
00444
00445 for (int i=0 ; i< fl->nFeatures ; i++)
00446 {
00447
00448 float x = fl->feature[i]->x;
00449 float y = fl->feature[i]->y;
00450
00451 vtol_vertex_2d_sptr point=new vtol_vertex_2d(x,y);
00452
00453 grp->push_back(point);
00454 }
00455
00456
00457
00458
00459
00460 return grp;
00461 }
00462
00463 KLT_PixelType* vgel_kl::convert_to_gs_image(vil1_image &image)
00464 {
00465
00466
00467 if (vil1_pixel_format(image)==VIL1_RGB_BYTE)
00468 {
00469 vcl_cerr << "Converting image to grey scale...\n";
00470
00471 int w=image.width();
00472 int h=image.height();
00473 KLT_PixelType* tab_mono=new KLT_PixelType[w*h];
00474 vcl_cerr << "width: " <<w<< " height: "<<h<< " pixel type: byte\n";
00475
00476 vil1_memory_image_of<vxl_byte> ima_mono;
00477 ima_mono.resize(w,h);
00478
00479 vil1_image_as_byte(image).get_section(ima_mono.get_buffer(), 0, 0, w, h);
00480 vxl_byte* p=ima_mono.get_buffer();
00481
00482 for (int j=0;j<h;j++)
00483 for (int i=0;i<w;i++)
00484 tab_mono[j*w+i]=(KLT_PixelType)p[j*w+i];
00485 return tab_mono;
00486 }
00487 else if (vil1_pixel_format(image)==VIL1_BYTE)
00488 {
00489 int w=image.width();
00490 int h=image.height();
00491 KLT_PixelType* tab_mono=new KLT_PixelType[w*h];
00492 vcl_cerr << "width: " <<w<< " height: "<<h<< " pixel type: byte\n";
00493
00494 vil1_memory_image_of<vxl_byte> ima_mono;
00495 ima_mono.resize(w,h);
00496
00497 vil1_image_as_byte(image).get_section(ima_mono.get_buffer(), 0, 0, w, h);
00498 vxl_byte* p=ima_mono.get_buffer();
00499
00500 for (int j=0;j<h;j++)
00501 for (int i=0;i<w;i++)
00502 tab_mono[j*w+i]=(KLT_PixelType)p[j*w+i];
00503
00504 return tab_mono;
00505 }
00506 else if (vil1_pixel_format(image)==VIL1_UINT16)
00507 {
00508 int w=image.width();
00509 int h=image.height();
00510 KLT_PixelType* tab_mono=new KLT_PixelType[w*h];
00511 vcl_cerr << "width: " <<w<< " height: "<<h<< " pixel type: uint_16\n";
00512
00513 vil1_memory_image_of<vxl_uint_16> ima_mono;
00514 ima_mono.resize(w,h);
00515
00516 vil1_image_as_uint16(image).get_section(ima_mono.get_buffer(), 0, 0, w, h);
00517 vxl_uint_16* p=ima_mono.get_buffer();
00518
00519 for (int j=0;j<h;j++)
00520 for (int i=0;i<w;i++)
00521 tab_mono[j*w+i]=(KLT_PixelType)p[j*w+i];
00522
00523 return tab_mono;
00524 }
00525 else if (vil1_pixel_format(image)==VIL1_RGB_UINT16)
00526 {
00527 int w=image.width();
00528 int h=image.height();
00529 KLT_PixelType* tab_mono=new KLT_PixelType[w*h];
00530 vcl_cerr << "width: " <<w<< " height: "<<h<< " pixel type: uint_16\n";
00531
00532 vil1_memory_image_of<vxl_uint_16> ima_mono;
00533 ima_mono.resize(w,h);
00534
00535 vil1_image_as_uint16(image).get_section(ima_mono.get_buffer(), 0, 0, w, h);
00536 vxl_uint_16* p=ima_mono.get_buffer();
00537
00538 for (int j=0;j<h;j++)
00539 for (int i=0;i<w;i++)
00540 tab_mono[j*w+i]=(KLT_PixelType)p[j*w+i];
00541
00542 return tab_mono;
00543 }
00544 else
00545 {
00546 vcl_cerr << "Error: Cannot convert pixel type: "
00547 << vil1_print(vil1_pixel_format(image)) << vcl_endl;
00548 return NULL;
00549 }
00550 }
00551
00552 KLT_PixelType* vgel_kl::convert_to_gs_image(vil_image_resource_sptr &image)
00553 {
00554
00555 vil_image_view<KLT_PixelType> imgv = vil_convert_cast (KLT_PixelType(), image->get_view());
00556
00557
00558 vil_image_view<KLT_PixelType> imgg;
00559
00560 if (imgv.nplanes() == 3)
00561 vil_convert_planes_to_grey (imgv, imgg);
00562 else
00563 imgg = imgv;
00564 if (!imgg) vil_convert_cast(imgv,imgg);
00565
00566 assert ( 1 == imgg.nplanes() );
00567
00568 KLT_PixelType* tab_mono=new KLT_PixelType[ imgg.ni() * imgg.nj() ];
00569
00570
00571 vil_image_view<KLT_PixelType> imgc (tab_mono,
00572 imgg.ni(), imgg.nj(), 1,
00573 1, imgg.ni(), imgg.ni() * imgg.nj());
00574
00575 vil_copy_deep (imgg, imgc);
00576
00577 return tab_mono;
00578 }
00579
00580
00581 KLT_PixelType* vgel_kl::convert_to_gs_image(vil_image_view<vxl_byte>* image)
00582 {
00583
00584 vil_image_view<vxl_byte> imgv = *image;
00585
00586
00587 vil_image_view<KLT_PixelType> imgg;
00588
00589 if (imgv.nplanes() == 3)
00590 vil_convert_planes_to_grey (imgv, imgg);
00591 else
00592 imgg = imgv;
00593 if (!imgg) vil_convert_cast(imgv,imgg);
00594
00595 assert ( 1 == imgg.nplanes() );
00596
00597 KLT_PixelType* tab_mono=new KLT_PixelType[ imgg.ni() * imgg.nj() ];
00598
00599
00600 vil_image_view<KLT_PixelType> imgc (tab_mono,
00601 imgg.ni(), imgg.nj(), 1,
00602 1, imgg.ni(), imgg.ni() * imgg.nj());
00603
00604 vil_copy_deep (imgg, imgc);
00605
00606 return tab_mono;
00607 }
00608
00609 void vgel_kl::set_tracking_context( KLT_TrackingContext tc)
00610 {
00611
00612 tc->mindist = params_.mindist;
00613 tc->window_width = params_.window_width;
00614 tc->window_height = params_.window_height;
00615 tc->sequentialMode = params_.sequentialMode;
00616 tc->smoothBeforeSelecting = params_.smoothBeforeSelecting;
00617 tc->writeInternalImages = params_.writeInternalImages;
00618 tc->min_eigenvalue = params_.min_eigenvalue;
00619 tc->min_determinant = params_.min_determinant;
00620 tc->max_iterations = params_.max_iterations;
00621 tc->min_displacement = params_.min_displacement;
00622 tc->max_residue = params_.max_residue;
00623 tc->grad_sigma = params_.grad_sigma;
00624 tc->smooth_sigma_fact = params_.smooth_sigma_fact;
00625 tc->pyramid_sigma_fact = params_.pyramid_sigma_fact;
00626 tc->nSkippedPixels = params_.nSkippedPixels;
00627
00628
00629 KLTChangeTCPyramid (tc, params_.search_range);
00630 KLTUpdateTCBorder (tc);
00631 }