GSoC2011SfM
0.1
Google Summer of Code 2011: Structure from motion
|
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 }