GSoC2011SfM  0.1
Google Summer of Code 2011: Structure from motion
D:/Travail/These/Determination caracteristiques camera/GSoC/SfM/src/Boost_Matching.cpp
00001 #include "Boost_Matching.h"
00002 
00003 #include "CameraPinholeDistor.h"
00004 #include <iostream>
00005 
00006 namespace OpencvSfM{
00007 
00008   using cv::Ptr;
00009   using cv::Mat;
00010   using std::vector;
00011 
00012   size_t MatchingThread::size_list;
00013   std::vector< cv::Ptr< PointsToTrack > >* MatchingThread::matches_ = NULL;
00014   vector< cv::Mat > MatchingThread::masks;
00015   unsigned int MatchingThread::mininum_points_matches=50;
00016   PointsMatcher* MatchingThread::match_algorithm = NULL;
00017   double MatchingThread::total_matches = 0;
00018   double MatchingThread::current_match_ = 0;
00019   bool MatchingThread::print_progress_ = true;
00020 
00021   DECLARE_MUTEX( MatchingThread::thread_concurr );
00022   DECLARE_MUTEX( MatchingThread::thread_unicity );
00023 
00024 
00025   MatchingThread::MatchingThread(cv::Ptr<  SequenceAnalyzer> seq_analyser,
00026     unsigned int i)
00027   {
00028     this->i = i;
00029     this->seq_analyser = seq_analyser;
00030     this->seq_analyser.addref();//avoid ptr deletion...
00031   }
00032 
00033   void MatchingThread::operator()()
00034   {
00035     Ptr<PointsToTrack> points_to_track_i=( *matches_ )[i];
00036     double error_allowed = MAX( seq_analyser->images_[ i ].rows,
00037       seq_analyser->images_[ i ].cols ) * 0.004;
00038 
00039     points_to_track_i->computeKeypointsAndDesc( false );
00040 
00041     P_MUTEX( thread_unicity );
00042     Ptr<PointsMatcher> point_matcher = match_algorithm->clone( true );
00043     point_matcher->add( points_to_track_i );
00044     V_MUTEX( thread_unicity );
00045     point_matcher->train( );
00046 
00047     unsigned int j=i+1;
00048     while ( j < size_list )
00049     {
00050       Ptr<PointsToTrack> points_to_track_j=( *matches_ )[j];
00051 
00052       points_to_track_j->computeKeypointsAndDesc( false );
00053 
00054       P_MUTEX( thread_unicity );
00055       current_match_++;
00056       if( print_progress_ )
00057       {
00058         if( ( ((int) ((current_match_*100)/total_matches) )%10 ) == 0 )
00059           if( ((int) current_match_) % ((int) (total_matches / 100) + 1 ) == 0)
00060             std::cout<<(int)((current_match_*100)/total_matches)<<" %"<<std::endl;
00061       }
00062       Ptr<PointsMatcher> point_matcher1 = match_algorithm->clone( true );
00063       point_matcher1->add( points_to_track_j );
00064       V_MUTEX( thread_unicity );
00065       point_matcher1->train( );
00066 
00067       vector< cv::DMatch > matches_i_j;
00068       point_matcher->crossMatch( point_matcher1, matches_i_j, masks );
00069       //point_matcher->match( points_to_track_j,matches_i_j );
00070 
00071       //First compute points matches:
00072       unsigned int size_match=matches_i_j.size( );
00073       vector<cv::Point2f> srcP;
00074       vector<cv::Point2f> destP;
00075       vector<uchar> status;
00076 
00077       if( size_match>8 )
00078       {
00079         std::clog<<"Using match, found "<<matches_i_j.size( )<<
00080           " matches between "<<i<<" "<<j<<std::endl;
00081         //vector<KeyPoint> points1 = point_matcher->;
00082         for( size_t cpt = 0; cpt < size_match; ++cpt )
00083         {
00084           const cv::DMatch& match = matches_i_j[ cpt ];
00085           const cv::KeyPoint &key1 = points_to_track_j->getKeypoint(
00086             matches_i_j[ cpt ].queryIdx );
00087           const cv::KeyPoint &key2 = point_matcher->getKeypoint(
00088             matches_i_j[ cpt ].trainIdx );
00089           srcP.push_back( cv::Point2f( key1.pt.x,key1.pt.y ) );
00090           destP.push_back( cv::Point2f( key2.pt.x,key2.pt.y ) );
00091           status.push_back( 1 );
00092         }
00093 
00094         //free some memory:
00095         //point_matcher1->clear();
00096         points_to_track_j->free_descriptors();
00097 
00098         Mat fundam = cv::findFundamentalMat( srcP, destP, status,
00099           cv::FM_RANSAC, error_allowed );
00100 
00101         unsigned int nbErrors = 0, nb_iter=0;
00102         //refine the mathing :
00103         size_match = status.size( );
00104         for( size_t cpt = 0; cpt < size_match; ++cpt )
00105         {
00106         if( status[ cpt ] == 0 )
00107         {
00108           size_match--;
00109           status[ cpt ] = status[ size_match ];
00110           status.pop_back( );
00111           srcP[ cpt ] = srcP[ size_match ];
00112           srcP.pop_back( );
00113           destP[ cpt ] = destP[ size_match ];
00114           destP.pop_back( );
00115           matches_i_j[ cpt ] = matches_i_j[ size_match ];
00116           matches_i_j.pop_back( );
00117           cpt--;
00118           ++nbErrors;
00119         }
00120       }
00121 
00122         while( nbErrors > 40 && nb_iter < 3 &&
00123           matches_i_j.size( ) > mininum_points_matches )
00124         {
00125           fundam = cv::findFundamentalMat( srcP, destP, status,
00126             cv::FM_RANSAC, error_allowed*1.5 );
00127 
00128           //refine the mathing :
00129           nbErrors =0 ;
00130           size_match = status.size( );
00131           for( size_t cpt = 0; cpt < size_match; ++cpt ){
00132             if( status[ cpt ] == 0 )
00133             {
00134               size_match--;
00135               status[ cpt ] = status[ size_match ];
00136               status.pop_back( );
00137               srcP[ cpt ] = srcP[ size_match ];
00138               srcP.pop_back( );
00139               destP[ cpt ] = destP[ size_match ];
00140               destP.pop_back( );
00141               matches_i_j[ cpt ] = matches_i_j[ size_match ];
00142               matches_i_j.pop_back( );
00143               cpt--;
00144               ++nbErrors;
00145             }
00146           }
00147           nb_iter++;
00148         };
00149 
00150         //refine the mathing:
00151         fundam = cv::findFundamentalMat( srcP, destP, status, cv::FM_LMEDS );
00152 
00153         //refine the mathing :
00154         size_match = status.size( );
00155         for( size_t cpt = 0; cpt < size_match; ++cpt ){
00156           if( status[ cpt ] == 0 )
00157           {
00158             size_match--;
00159             status[ cpt ] = status[ size_match ];
00160             status.pop_back( );
00161             srcP[ cpt ] = srcP[ size_match ];
00162             srcP.pop_back( );
00163             destP[ cpt ] = destP[ size_match ];
00164             destP.pop_back( );
00165             matches_i_j[ cpt ] = matches_i_j[ size_match ];
00166             matches_i_j.pop_back( );
00167             cpt--;
00168             ++nbErrors;
00169           }
00170         }
00171 
00172         if( matches_i_j.size( ) > mininum_points_matches )
00173         {
00174           Mat * copy_of_fund = new cv::Mat();
00175           *copy_of_fund = fundam.clone();
00176           P_MUTEX( thread_unicity );
00177           seq_analyser->list_fundamental_[i][j-i] = cv::Ptr< cv::Mat >(
00178             copy_of_fund );
00179           seq_analyser->addMatches( matches_i_j,i,j );
00180           std::clog<<"; find "<<matches_i_j.size( )<<
00181             " real matches"<<std::endl;
00182           V_MUTEX( thread_unicity );
00183         }
00184         else
00185         {
00186           std::clog<<"Between "<<i<<" "<<j<<", can't find real matches"<<std::endl;
00187         }
00188 
00189       }
00190       else
00191       {
00192         std::clog<<"Using crossMatch, found only "<<matches_i_j.size( )<<
00193           " matches between "<<i<<" "<<j<<std::endl;
00194       }
00195       j++;
00196     }
00197 
00198     P_MUTEX( thread_unicity );
00199     point_matcher->clear();
00200     points_to_track_i->free_descriptors();//save memory...
00201     V_MUTEX( thread_unicity );
00202     V_MUTEX( MatchingThread::thread_concurr );//wake up waiting thread
00203   };
00204 }
 All Classes Functions Variables