GSoC2011SfM  0.1
Google Summer of Code 2011: Structure from motion
D:/Travail/These/Determination caracteristiques camera/GSoC/SfM/src/SequenceAnalyzer.cpp
00001 
00002 #include <boost/thread/thread.hpp>
00003 
00004 #include <iostream>
00005 #include <sstream>
00006 
00007 #include "SequenceAnalyzer.h"
00008 #include "Boost_Matching.h"
00009 #include "Camera.h"
00010 
00011 #include "config_SFM.h"  //SEMAPHORE
00012 
00013 using cv::Ptr;
00014 using cv::Mat;
00015 using cv::DMatch;
00016 using cv::KeyPoint;
00017 using std::vector;
00018 using cv::Point3d;
00019 
00020 namespace OpencvSfM{
00021 
00022   int SequenceAnalyzer::mininum_points_matches = 20;
00023   int SequenceAnalyzer::mininum_image_matches = 2;
00024 
00025 
00026   SequenceAnalyzer::SequenceAnalyzer( 
00027     cv::Ptr<cv::FeatureDetector> feature_detector,
00028     cv::Ptr<cv::DescriptorExtractor> descriptor_extractor,
00029     cv::Ptr<PointsMatcher> match_algorithm )
00030     :match_algorithm_( match_algorithm ),
00031     feature_detector_( feature_detector ),
00032     descriptor_extractor_( descriptor_extractor )
00033   {
00034 
00035   }
00036 
00037   SequenceAnalyzer::SequenceAnalyzer( MotionProcessor input_sequence,
00038     cv::Ptr< cv::FeatureDetector > feature_detector,
00039     cv::Ptr< cv::DescriptorExtractor > descriptor_extractor,
00040     cv::Ptr< PointsMatcher > match_algorithm )
00041     :match_algorithm_( match_algorithm ),
00042     feature_detector_( feature_detector ),
00043     descriptor_extractor_( descriptor_extractor )
00044   {
00045     //only finite sequences can be used:
00046     CV_DbgAssert( input_sequence.isBidirectional( ) );
00047     //go back to the begining:
00048     input_sequence.setProperty( CV_CAP_PROP_POS_FRAMES,0 );
00049 
00050     //load entire sequence! Can be problematic but if a user want to have
00051     //more controls, he can use the other constructor...
00052 
00053     int nbFrame=0;
00054     Mat currentImage=input_sequence.getFrame( );
00055     while ( !currentImage.empty( ) )// && nbFrame<50 )
00056     {
00057       addImageToPipeline( currentImage );
00058       nbFrame++;
00059       currentImage=input_sequence.getFrame( );
00060     }
00061   }
00062 
00063   SequenceAnalyzer::SequenceAnalyzer(
00064     std::vector< cv::Ptr< PointsToTrack > > &points_to_track,
00065     std::vector< cv::Mat > *images,
00066     cv::Ptr<PointsMatcher> match_algorithm )
00067     :points_to_track_( points_to_track )
00068   {
00069     if( match_algorithm.empty() )
00070       match_algorithm_ = new PointsMatcher( 
00071       Ptr<cv::DescriptorMatcher>( new cv::FlannBasedMatcher( ) ) );
00072     else
00073       match_algorithm_ = match_algorithm;
00074     if( images != NULL)
00075       images_ = (*images);
00076   }
00077 
00078   //by default, use flann based matcher
00079   SequenceAnalyzer::SequenceAnalyzer( cv::FileNode file,
00080     std::vector<cv::Mat> *images,
00081     cv::Ptr<PointsMatcher> match_algorithm )
00082   {
00083     if( match_algorithm.empty() )
00084       match_algorithm_ = new PointsMatcher(
00085       Ptr<cv::DescriptorMatcher>( new cv::FlannBasedMatcher( ) ) );
00086     else
00087       match_algorithm_ = match_algorithm;
00088     if( images != NULL)
00089       images_ = (*images);
00090     read( file,*this );
00091   }
00092 
00093   SequenceAnalyzer::~SequenceAnalyzer( void )
00094   {
00095   }
00096 
00097   void SequenceAnalyzer::addImageToPipeline( cv::Mat image, cv::Ptr<PointsToTrack> points )
00098   {
00099     if( points.empty( ) )
00100     {
00101       CV_DbgAssert( !feature_detector_.empty( ) &&
00102         !descriptor_extractor_.empty( ) );
00103       int nbFrame = points_to_track_.size( );
00104       Ptr<PointsToTrack> ptrPoints_tmp( new PointsToTrackWithImage (
00105         nbFrame, image, feature_detector_, descriptor_extractor_ ));
00106       ptrPoints_tmp->computeKeypointsAndDesc( );
00107 
00108       points_to_track_.push_back( ptrPoints_tmp );
00109     }
00110     else
00111       points_to_track_.push_back( points );
00112 
00113     images_.push_back( image );
00114   }
00115 
00116   void SequenceAnalyzer::addImageToTracks( cv::Mat image, cv::Ptr<PointsToTrack> points )
00117   {
00118     if( points.empty( ) )
00119     {
00120       CV_DbgAssert( !feature_detector_.empty( ) &&
00121         !descriptor_extractor_.empty( ) );
00122       int nbFrame = points_to_track_.size( );
00123       points = new PointsToTrackWithImage (
00124         nbFrame, image, feature_detector_, descriptor_extractor_ );
00125       points->computeKeypointsAndDesc( );
00126 
00127       points_to_track_.push_back( points );
00128     }
00129     else
00130       points_to_track_.push_back( points );
00131 
00132     images_.push_back( image );
00133 
00135     //First compute missing features descriptors:
00136     vector< Ptr< PointsToTrack > >::iterator matches_it =
00137       points_to_track_.begin( ),
00138       end_matches_it = points_to_track_.end( );
00139 
00140     Ptr<PointsMatcher> point_matcher = match_algorithm_->clone( true );
00141     point_matcher->add( points );
00142     point_matcher->train( );
00143     int i = 0;
00144     while ( matches_it != end_matches_it )
00145     {
00146       Ptr<PointsMatcher> point_matcher1 = match_algorithm_->clone( true );
00147       point_matcher1->add( points_to_track_[i] );
00148       point_matcher1->train( );
00149 
00150 
00151       std::vector< cv::DMatch > matches = SequenceAnalyzer::simple_matching(
00152         point_matcher, point_matcher1, 10 );
00153 
00154       i++;
00155       matches_it++;
00156     }
00157 
00158       //compute the color of each matches:
00159       unsigned int max_tracks = tracks_.size();
00160       for(unsigned int t=0;t<max_tracks; t++)
00161       {
00162         TrackOfPoints& tmp = tracks_[t];
00163         if(tmp.color == 0)
00164         {
00165           unsigned int max_points = tmp.point_indexes_.size();
00166           int R = 0, G = 0, B = 0;
00167           for(unsigned int j=0; j<max_points; ++j)
00168           {
00169             unsigned int img_idx = tmp.images_indexes_[j];
00170             unsigned int pt_idx = tmp.point_indexes_[j];
00171 
00172             unsigned int packed_color = points_to_track_[ img_idx ]->getColor( pt_idx );
00173             R += (packed_color>>16) & 0x000000FF;
00174             G += (packed_color>>8) & 0x000000FF;
00175             B += (packed_color) & 0x000000FF;
00176           }
00177           R /= max_points;
00178           G /= max_points;
00179           B /= max_points;
00180           tmp.color = (unsigned int)(
00181             ((R<<16) & 0x00FF0000) | ((R<<8) & 0x0000FF00)| (B & 0x000000FF));
00182         }
00183       }
00184       TrackOfPoints::fusionDuplicates( tracks_ );
00186   }
00187 
00188   void SequenceAnalyzer::computeMatches( uchar nbMaxThread, bool printProgress )
00189   {
00190     //First compute missing features descriptors:
00191     vector< Ptr< PointsToTrack > >::iterator matches_it =
00192       points_to_track_.begin( ),
00193       end_matches_it = points_to_track_.end( );
00194     MatchingThread::size_list = points_to_track_.size();
00195     MatchingThread::match_algorithm = match_algorithm_;
00196 
00197     MatchingThread::matches_ = &points_to_track_;
00198 
00199     double nbMatches = points_to_track_.size();
00200     MatchingThread::total_matches = nbMatches * nbMatches / 2.0;
00201     MatchingThread::current_match_ = 0;
00202     MatchingThread::print_progress_ = printProgress;
00203 
00204     //then init the fundamental matrix list:
00205     list_fundamental_.clear();
00206 
00207     for( size_t cpt = 0; cpt<MatchingThread::size_list; ++cpt )
00208       list_fundamental_.push_back(
00209       vector< cv::Ptr<Mat> > ( MatchingThread::size_list - cpt + 1 ) );
00210 
00211     //Try to match each picture with other:
00212     vector<Mat> masks;
00213 
00214     MatchingThread::mininum_points_matches = mininum_points_matches;
00215     unsigned int nb_proc = MIN( nbMaxThread, boost::thread::hardware_concurrency() );
00216     INIT_SEMAPHORE( MatchingThread::thread_concurr, nb_proc );
00217     INIT_MUTEX( MatchingThread::thread_unicity );
00218 
00219     unsigned int i=0;
00220 
00221     while ( matches_it != end_matches_it )
00222     {
00223       //can we start a new thread?
00224       P_MUTEX( MatchingThread::thread_concurr );
00225       //create local values for the thead:
00226       MatchingThread match_thread(this, i );
00227       //start the thread:
00228       boost::thread myThread(match_thread);
00229 
00230       i++;
00231       matches_it++;
00232     }
00233     for(unsigned int wait_endThread = 0;
00234       wait_endThread<nb_proc ; ++wait_endThread)
00235       P_MUTEX( MatchingThread::thread_concurr );//wait for last threads
00236 
00237     //compute the color of each matches:
00238     unsigned int max_tracks = tracks_.size();
00239     for(unsigned int t=0;t<max_tracks; t++)
00240     {
00241       TrackOfPoints& tmp = tracks_[t];
00242       unsigned int max_points = tmp.point_indexes_.size();
00243       int R = 0, G = 0, B = 0;
00244       for(unsigned int j=0; j<max_points; ++j)
00245       {
00246         unsigned int img_idx = tmp.images_indexes_[j];
00247         unsigned int pt_idx = tmp.point_indexes_[j];
00248 
00249         unsigned int packed_color = points_to_track_[ img_idx ]->getColor( pt_idx );
00250         R += (packed_color>>16) & 0x000000FF;
00251         G += (packed_color>>8) & 0x000000FF;
00252         B += (packed_color) & 0x000000FF;
00253       }
00254       R /= max_points;
00255       G /= max_points;
00256       B /= max_points;
00257       tmp.color = (unsigned int)(
00258         ((R<<16) & 0x00FF0000) | ((R<<8) & 0x0000FF00)| (B & 0x000000FF));
00259     }
00260     TrackOfPoints::fusionDuplicates( tracks_ );
00261   }
00262 
00263   void SequenceAnalyzer::keepOnlyCorrectMatches(
00264     std::vector<TrackOfPoints>& tracks,
00265     unsigned int min_matches, unsigned int min_consistance )
00266   {
00267     unsigned int tracks_size = tracks.size( );
00268     unsigned int index=0;
00269 
00270     while ( index < tracks_size )
00271     {
00272       if( ( tracks[ index ].getNbTrack( ) < min_matches ) ||
00273         ( tracks[ index ].track_consistance < (int)min_consistance ) )
00274       {
00275         //problem with this track, too small to be consistent
00276         // or inconsistant...
00277         tracks_size--;
00278         tracks[ index ]=tracks[ tracks_size ];
00279         tracks.pop_back( );
00280         index--;
00281       }
00282       index++;
00283     }
00284   }
00285 
00286   void SequenceAnalyzer::addMatches( std::vector< cv::DMatch > &newMatches,
00287     unsigned int img1, unsigned int img2 )
00288   {
00289     //add to tracks_ the new matches:
00290 
00291     vector<DMatch>::iterator match_it = newMatches.begin( );
00292     vector<DMatch>::iterator match_it_end = newMatches.end( );
00293 
00294     while ( match_it != match_it_end )
00295     {
00296       DMatch &point_matcher = ( *match_it );
00297 
00298       bool is_found=false;
00299       vector<TrackOfPoints>::iterator tracks_it = tracks_.begin( );
00300       while ( tracks_it != tracks_.end( ) && !is_found )
00301       {
00302         TrackOfPoints& track = ( *tracks_it );
00303 
00304         if( track.containPoint( img1,point_matcher.trainIdx ))
00305         {
00306           track.addMatch( img2,point_matcher.queryIdx );
00307           is_found=true;
00308         }
00309         else
00310         {
00311           if( track.containPoint( img2,point_matcher.queryIdx ))
00312           {
00313             track.addMatch( img1,point_matcher.trainIdx );
00314             is_found=true;
00315           }
00316         }
00317         tracks_it++;
00318       }
00319       if( !is_found )
00320       {
00321         //it's a new point match, create a new track:
00322         TrackOfPoints newTrack;
00323         newTrack.addMatch( img1,point_matcher.trainIdx );
00324         newTrack.addMatch( img2,point_matcher.queryIdx );
00325         tracks_.push_back( newTrack );
00326       }
00327 
00328       match_it++;
00329     }
00330   }
00331 
00332   void SequenceAnalyzer::addTracks( std::vector< TrackOfPoints > &newTracks )
00333   {
00334 
00335     vector<TrackOfPoints>::iterator match_it = newTracks.begin( ),
00336       match_it_end = newTracks.end( );
00337 
00338     while ( match_it != match_it_end )
00339     {
00340       tracks_.push_back( *match_it );
00341 
00342       match_it++;
00343     }
00344   }
00345 
00346   void SequenceAnalyzer::showTracks( int timeBetweenImg )
00347   {
00348     if( points_to_track_.size( ) == 0 )
00349       return;//nothing to do...
00350 
00351     unsigned int it=0,it1=0;
00352     unsigned int end_iter = points_to_track_.size( ) - 1 ;
00353     if( images_.size( ) - 1 < end_iter )
00354       end_iter = images_.size( ) - 1;
00355     while ( it < end_iter )
00356     {
00357       it1=it+1;
00358       while ( it1 < end_iter )
00359       {
00360         vector<DMatch> matches_to_print;
00361         //add to matches_to_print only points of img it and it+1:
00362 
00363         vector<TrackOfPoints>::iterator match_it = tracks_.begin( );
00364         vector<TrackOfPoints>::iterator match_it_end = tracks_.end( );
00365 
00366         while ( match_it != match_it_end )
00367         {
00368           if( match_it->containImage( it ) &&
00369             match_it->containImage( it1 ) )
00370           {
00371             matches_to_print.push_back( match_it->toDMatch( it,it1 ));
00372           }
00373           match_it++;
00374         }
00375 
00376         if( matches_to_print.size()>0 )
00377         {
00378           Mat firstImg=images_[ it ];
00379           Mat outImg;
00380 
00381           PointsMatcher::drawMatches( firstImg, points_to_track_[ it ]->getKeypoints( ),
00382             points_to_track_[ it1 ]->getKeypoints( ),
00383             matches_to_print, outImg,
00384             cv::Scalar::all( -1 ), cv::Scalar::all( -1 ), vector<char>( ),
00385             cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
00386 
00387           imshow( "showTracks",outImg );
00388           cv::waitKey( timeBetweenImg );
00389         }
00390 
00391         it1++;
00392       }
00393       it++;
00394     }
00395     cvDestroyWindow( "showTracks" );
00396   }
00397 
00398   void SequenceAnalyzer::showTracks( int img_to_show, int timeBetweenImg )
00399   {
00400     unsigned int it=0,it1=0;
00401     unsigned int end_iter = points_to_track_.size( ) - 1 ;
00402     if( images_.size( ) - 1 < end_iter )
00403       end_iter = images_.size( ) - 1;
00404     vector< vector<DMatch> > matches_to_print;
00405     matches_to_print.assign( points_to_track_.size( ), vector<DMatch>() );
00406     //add to matches_to_print only points of img it and it+1:
00407 
00408     vector<TrackOfPoints>::iterator match_it = tracks_.begin( );
00409     vector<TrackOfPoints>::iterator match_it_end = tracks_.end( );
00410     unsigned int i = 0;
00411     while ( match_it != match_it_end )
00412     {
00413       if( match_it->containImage( img_to_show ) )
00414       {
00415         for(i = 0; i<match_it->images_indexes_.size(); i++)
00416         {
00417           if(match_it->images_indexes_[i] != img_to_show)
00418           {
00419             matches_to_print[ match_it->images_indexes_[i] ].
00420               push_back( match_it->toDMatch( img_to_show, match_it->images_indexes_[i] ));
00421           }
00422         }
00423       }
00424       match_it++;
00425     }
00426 
00427     for(i = 0; i<matches_to_print.size(); i++)
00428     {
00429       if( matches_to_print[i].size()>0 )
00430       {
00431         Mat firstImg=images_[ it ];
00432         Mat outImg;
00433 
00434         PointsMatcher::drawMatches( firstImg, points_to_track_[ img_to_show ]->getKeypoints( ),
00435           points_to_track_[ i ]->getKeypoints( ),
00436           matches_to_print[i], outImg,
00437           cv::Scalar::all( -1 ), cv::Scalar::all( -1 ), vector<char>( ),
00438           cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
00439 
00440         imshow( "showTracks",outImg );
00441         cv::waitKey( timeBetweenImg );
00442       }
00443     }
00444     cvDestroyWindow( "showTracks" );
00445   }
00446 
00447   cv::Mat SequenceAnalyzer::showTracksBetween( unsigned int img1, unsigned int img2,
00448     cv::Mat img, bool should_print )
00449   {
00450     CV_Assert( points_to_track_.size( ) != 0 );
00451     CV_Assert( images_.size( ) > img1 && images_.size( ) > img2 );
00452     CV_Assert( 0 <= img1 &&  0 <= img2 );
00453 
00454     vector<DMatch> matches_to_print,matches_to_print1;
00455     //add to matches_to_print only points of img1 and img2:
00456 
00457     vector<TrackOfPoints>::iterator match_it = tracks_.begin( );
00458     vector<TrackOfPoints>::iterator match_it_end = tracks_.end( );
00459 
00460     while ( match_it != match_it_end )
00461     {
00462       if( match_it->containImage( img1 ) &&
00463         match_it->containImage( img2 ) )
00464       {
00465         matches_to_print.push_back( match_it->toDMatch( img1,img2 ));
00466         matches_to_print1.push_back( match_it->toDMatch( img2,img1 ));
00467       }
00468       match_it++;
00469     }
00470     if( img.empty() )
00471       img = images_[ img1 ];
00472     Mat outImg,outImg1;
00473     PointsMatcher::drawMatches( img, points_to_track_[ img1 ]->getKeypoints( ),
00474       points_to_track_[ img2 ]->getKeypoints( ),
00475       matches_to_print, outImg,
00476       cv::Scalar::all( -1 ), cv::Scalar::all( -1 ), vector<char>( ),
00477       cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
00478     if(should_print)
00479       imshow( "showTracks Img1-Img2",outImg );
00480 
00481     if(should_print)
00482     {
00483     PointsMatcher::drawMatches( images_[ img2 ], points_to_track_[ img2 ]->getKeypoints( ),
00484       points_to_track_[ img1 ]->getKeypoints( ),
00485       matches_to_print1, outImg1,
00486       cv::Scalar::all( -1 ), cv::Scalar::all( -1 ), vector<char>( ),
00487       cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
00488 
00489       imshow( "showTracks Img2-Img1",outImg1 );
00490       cv::waitKey( 0 );
00491     }
00492 
00493     cvDestroyAllWindows();
00494     return outImg;
00495   }
00496 
00497   void SequenceAnalyzer::read( const cv::FileNode& node, SequenceAnalyzer& me )
00498   {
00499     std::string myName=node.name( );
00500     if( myName != "SequenceAnalyzer" )
00501     {
00502       std::string error = "FileNode is not correct!\nExpected \"SequenceAnalyzer\", got ";
00503       error += node.name();
00504       CV_Error( CV_StsError, error.c_str() );
00505     }
00506     if( node.empty( ) || !node.isMap( ) )
00507       CV_Error( CV_StsError, "SequenceAnalyzer FileNode is not correct!" );
00508 
00509     int nb_pictures = ( int ) node[ "nbPictures" ];
00510     //initialisation of all empty vectors
00511     for( int i=0; i<nb_pictures; i++ )
00512     {
00513       Ptr<PointsToTrack> ptt = Ptr<PointsToTrack>( new PointsToTrackWithImage( i, me.images_[i] ));
00514       me.points_to_track_.push_back( ptt );
00515 
00516       Ptr<PointsMatcher> p_m = Ptr<PointsMatcher>( new PointsMatcher(
00517         *me.match_algorithm_ ) );
00518       p_m->add( ptt );
00519 
00520       me.matches_.push_back( p_m );
00521     }
00522 
00523     cv::FileNode node_TrackPoints = node[ "TrackPoints" ];
00524 
00525     //tracks are stored in the following form:
00526     //list of track where a track is stored like this:
00527     // nbPoints idImage1 point1  idImage2 point2 ...
00528     if( node_TrackPoints.empty( ) || !node_TrackPoints.isSeq( ) )
00529       CV_Error( CV_StsError, "SequenceAnalyzer FileNode is not correct!" );
00530     cv::FileNodeIterator it = node_TrackPoints.begin( ),
00531       it_end = node_TrackPoints.end( );
00532     while( it != it_end )
00533     {
00534       cv::FileNode it_track = ( *it )[ 0 ];
00535       int nbPoints,track_consistance;
00536       it_track[ "nbPoints" ] >> nbPoints;
00537       it_track[ "track_consistance" ] >> track_consistance;
00538       bool has_3d_point = false;
00539       it_track[ "has_3d_position" ] >> has_3d_point;
00540       TrackOfPoints track;
00541       if( has_3d_point )
00542       {
00543         cv::Vec3d point;
00544         point[ 0 ] = it_track[ "point3D_triangulated" ][ 0 ];
00545         point[ 1 ] = it_track[ "point3D_triangulated" ][ 1 ];
00546         point[ 2 ] = it_track[ "point3D_triangulated" ][ 2 ];
00547         track.point3D = Ptr<cv::Vec3d>( new cv::Vec3d( point ) );
00548       }
00549       int color;
00550       it_track[ "color" ] >> color;
00551       track.setColor( *((unsigned int*)&color) );
00552       cv::FileNodeIterator itPoints = it_track[ "list_of_points" ].begin( ),
00553         itPoints_end = it_track[ "list_of_points" ].end( );
00554       while( itPoints != itPoints_end )
00555       {
00556         int idImage;
00557         cv::KeyPoint kpt;
00558         idImage = ( *itPoints )[ 0 ];
00559         itPoints++;
00560         kpt.pt.x = ( *itPoints )[ 0 ];
00561         kpt.pt.y = ( *itPoints )[ 1 ];
00562         kpt.size = ( *itPoints )[ 2 ];
00563         kpt.angle = ( *itPoints )[ 3 ];
00564         kpt.response = ( *itPoints )[ 4 ];
00565         kpt.octave = ( *itPoints )[ 5 ];
00566         kpt.class_id = ( *itPoints )[ 6 ];
00567 
00568         unsigned int point_index = me.points_to_track_[ idImage ]->
00569           addKeypoint( kpt );
00570         track.addMatch( idImage,point_index );
00571 
00572         itPoints++;
00573       }
00574       track.track_consistance = track_consistance;
00575       me.tracks_.push_back( track );
00576       it++;
00577     }
00578   }
00579 
00580   void SequenceAnalyzer::write( cv::FileStorage& fs, const SequenceAnalyzer& me )
00581   {
00582     vector<TrackOfPoints>::size_type key_size = me.tracks_.size( );
00583     int idImage=-1, idPoint=-1;
00584 
00585     fs << "SequenceAnalyzer" << "{";
00586     fs << "nbPictures" << ( int )me.points_to_track_.size( );
00587     fs << "nbPoints" << ( int )key_size;
00588     fs << "TrackPoints" << "[";
00589     for ( vector<TrackOfPoints>::size_type i=0; i < key_size; i++ )
00590     {
00591       const TrackOfPoints &track = me.tracks_[ i ];
00592       unsigned int nbPoints = track.getNbTrack( );
00593       if( nbPoints > 0 )
00594       {
00595         fs << "{" << "nbPoints" << ( int )nbPoints;
00596         fs << "track_consistance" << track.track_consistance;
00597         fs << "has_3d_position" << ( !track.point3D.empty( ) );
00598         if( !track.point3D.empty( ) )
00599           fs << "point3D_triangulated" << *(track.point3D);
00600 
00601         unsigned int real_color = track.getColor();
00602         int color = *((int*)&real_color);
00603         fs << "color" << color;
00604 
00605         fs << "list_of_points" << "[:";
00606         nbPoints = track.images_indexes_.size();
00607         for ( unsigned int j = 0; j < nbPoints ; j++ )
00608         {
00609           if( track.good_values[j] )
00610           {
00611             idImage = track.images_indexes_[ j ];
00612             idPoint = track.point_indexes_[ j ];
00613             if( idImage>=0 && idPoint>=0 )
00614             {
00615               fs << idImage;
00616               fs  << "[:";
00617 
00618               const cv::KeyPoint kpt = me.points_to_track_[ idImage ]->
00619                 getKeypoints( )[ idPoint ];
00620               cv::write( fs, kpt.pt.x );
00621               cv::write( fs, kpt.pt.y );
00622               cv::write( fs, kpt.size );
00623               cv::write( fs, kpt.angle );
00624               cv::write( fs, kpt.response );
00625               cv::write( fs, kpt.octave );
00626               cv::write( fs, kpt.class_id );
00627               fs << "]" ;
00628             }
00629           }
00630         }
00631         fs << "]" << "}" ;
00632       }
00633     }
00634     fs << "]" << "}";
00635   }
00636 
00637   void SequenceAnalyzer::constructImagesGraph( )
00638   {
00639     images_graph_.initStructure( points_to_track_.size( ) );
00640 
00641     //for each points:
00642     vector<TrackOfPoints>::size_type key_size = tracks_.size( );
00643     vector<TrackOfPoints>::size_type i;
00644 
00645     for ( i=0; i < key_size; i++ )
00646     {
00647       TrackOfPoints &track = tracks_[ i ];
00648       unsigned int nviews = track.images_indexes_.size( );
00649 
00650       for( unsigned int cpt=0;cpt<nviews;cpt++ )
00651       {
00652         unsigned int imgSrc = track.images_indexes_[ cpt ];
00653         for( unsigned int cpt1=cpt+1;cpt1<nviews;cpt1++ )
00654         {
00655           images_graph_.addLink( imgSrc, track.images_indexes_[ cpt1 ] );
00656         }
00657       }
00658     }
00659   }
00660 
00661   std::vector< cv::Vec3d > SequenceAnalyzer::get3DStructure( )
00662   {
00663     vector<cv::Vec3d> out_vector;
00664     vector<TrackOfPoints>::iterator itTrack=tracks_.begin( );
00665     while ( itTrack != tracks_.end( ) )
00666     {
00667       if( !itTrack->point3D.empty( ) )
00668         out_vector.push_back( ( cv::Vec3d )( *itTrack ) );
00669       itTrack++;
00670     }
00671     return out_vector;
00672   }
00673 
00674   std::vector< unsigned int > SequenceAnalyzer::getColors( )
00675   {
00676     vector<unsigned int> out_vector;
00677     vector<TrackOfPoints>::iterator itTrack=tracks_.begin( );
00678     while ( itTrack != tracks_.end( ) )
00679     {
00680       if( !itTrack->point3D.empty( ) )
00681         out_vector.push_back( itTrack->getColor() );
00682       itTrack++;
00683     }
00684     return out_vector;
00685   }
00686 
00687   void SequenceAnalyzer::showPointsOnImage(unsigned int i,
00688     const std::vector<cv::Vec2d>& pixelProjection)
00689   {
00690     CV_Assert( i < images_.size() );
00691     //convert Vec2D into Keypoints:
00692     std::vector<KeyPoint> keypoints;
00693     for(size_t cpt = 0; cpt<pixelProjection.size(); ++cpt)
00694     {
00695       keypoints.push_back( cv::KeyPoint( (float)pixelProjection[ cpt ][0],
00696         (float)pixelProjection[ cpt ][1], 1.0 ) );
00697     }
00698     cv::Mat outImg;
00699     cv::drawKeypoints( images_[i], keypoints, outImg );
00700     cv::imshow( "Keypoints", outImg );
00701     cv::waitKey( 0 );
00702     cv::destroyWindow( "Keypoints" );
00703   }
00704 
00705   std::vector< cv::DMatch > SequenceAnalyzer::simple_matching(
00706     cv::Ptr<PointsMatcher> point_matcher,
00707     cv::Ptr<PointsMatcher> point_matcher1,
00708     unsigned int mininum_points_matches)
00709   {
00710     vector< cv::DMatch > matches_i_j;
00711     point_matcher->crossMatch( point_matcher1, matches_i_j );
00712 
00713     //First compute points matches:
00714     unsigned int size_match=matches_i_j.size( );
00715     vector<cv::Point2f> srcP;
00716     vector<cv::Point2f> destP;
00717     vector<uchar> status;
00718 
00719     //vector<KeyPoint> points1 = point_matcher->;
00720     for( size_t cpt = 0; cpt < size_match; ++cpt ){
00721       const cv::KeyPoint &key1 = point_matcher1->getKeypoint(
00722         matches_i_j[ cpt ].queryIdx );
00723       const cv::KeyPoint &key2 = point_matcher->getKeypoint(
00724         matches_i_j[ cpt ].trainIdx );
00725       srcP.push_back( cv::Point2f( key1.pt.x,key1.pt.y ) );
00726       destP.push_back( cv::Point2f( key2.pt.x,key2.pt.y ) );
00727       status.push_back( 1 );
00728     }
00729 
00730     //free some memory:
00731     point_matcher->clear();
00732     point_matcher1->clear();
00733 
00734     if( srcP.size()< mininum_points_matches )
00735       return matches_i_j;
00736     cv::Mat fundam = cv::findFundamentalMat( srcP, destP, status, cv::FM_RANSAC, 1 );
00737 
00738     unsigned int nbErrors = 0, nb_iter=0;
00739     //refine the mathing :
00740     size_match = status.size( );
00741     for( size_t cpt = 0; cpt < size_match; ++cpt ){
00742       if( status[ cpt ] == 0 )
00743       {
00744         size_match--;
00745         status[ cpt ] = status[ size_match ];
00746         status.pop_back( );
00747         srcP[ cpt ] = srcP[ size_match ];
00748         srcP.pop_back( );
00749         destP[ cpt ] = destP[ size_match ];
00750         destP.pop_back( );
00751         matches_i_j[ cpt ] = matches_i_j[ size_match ];
00752         matches_i_j.pop_back( );
00753         cpt--;
00754         ++nbErrors;
00755       }
00756     }
00757 
00758     if( srcP.size()< mininum_points_matches )
00759       return matches_i_j;
00760 
00761     //refine the mathing:
00762     fundam = cv::findFundamentalMat( srcP, destP, status, cv::FM_LMEDS );
00763 
00764     size_match = status.size( );
00765     for( size_t cpt = 0; cpt < size_match; ++cpt ){
00766       if( status[ cpt ] == 0 )
00767       {
00768         size_match--;
00769         status[ cpt ] = status[ size_match ];
00770         status.pop_back( );
00771         srcP[ cpt ] = srcP[ size_match ];
00772         srcP.pop_back( );
00773         destP[ cpt ] = destP[ size_match ];
00774         destP.pop_back( );
00775         matches_i_j[ cpt ] = matches_i_j[ size_match ];
00776         matches_i_j.pop_back( );
00777         cpt--;
00778         ++nbErrors;
00779       }
00780     }
00781     return matches_i_j;
00782   };
00783 
00784 
00785   void SequenceAnalyzer::removePointsWithoutProjection(
00786     SequenceAnalyzer &motion_estim )
00787   {
00788     vector<TrackOfPoints>::size_type key_size = motion_estim.tracks_.size( );
00789     int idImage=-1, idPoint=-1;
00790     vector< Ptr<PointsToTrack> > new_ptt;
00791     //initialisation of empty vector
00792     int before = 0, after = 0;
00793     for( size_t i=0; i<motion_estim.points_to_track_.size(); i++ )
00794     {
00795       Ptr<PointsToTrack> ptt = Ptr<PointsToTrack>(
00796         new PointsToTrackWithImage( i, motion_estim.images_[i],
00797         motion_estim.feature_detector_, motion_estim.descriptor_extractor_ ));
00798       new_ptt.push_back( ptt );
00799       before += motion_estim.points_to_track_[i]->getKeypoints().size();
00800     }
00801     for ( size_t i=0; i < key_size; i++ )
00802     {
00803       TrackOfPoints &track = motion_estim.tracks_[ i ];
00804       unsigned int nbPoints = track.getNbTrack( );
00805       if( nbPoints > 0 && !track.point3D.empty( ) )
00806       {
00807         nbPoints = track.images_indexes_.size();
00808         for ( unsigned int j = 0; j < nbPoints ; j++ )
00809         {
00810           if( track.good_values[j] )
00811           {
00812             idImage = track.images_indexes_[ j ];
00813             idPoint = track.point_indexes_[ j ];
00814             if( idImage>=0 && idPoint>=0 )
00815             {
00816 
00817               const cv::KeyPoint kpt = 
00818                 motion_estim.points_to_track_[ idImage ]->
00819                 getKeypoints( )[ idPoint ];
00820               track.point_indexes_[ j ] = new_ptt[ idImage ]->addKeypoint( kpt );
00821             }
00822           }
00823         }
00824       }
00825     }
00826     motion_estim.points_to_track_ = new_ptt;
00827     for( size_t i=0; i<motion_estim.points_to_track_.size(); i++ )
00828     {
00829       Ptr<PointsToTrack> ptt = Ptr<PointsToTrack>(
00830         new PointsToTrackWithImage( i, motion_estim.images_[i] ));
00831       new_ptt.push_back( ptt );
00832       after += motion_estim.points_to_track_[i]->getKeypoints().size();
00833     }
00834     std::cout<<" before "<<before<<", after "<<after<<std::endl;
00835   }
00836 }
 All Classes Functions Variables