void ControlleurFigurine::exec() { int mercure; do { mercure = m_vue.exec(); } while(!valide() && mercure != QDialog::Rejected); }
/** * Put masks to white, images are conserved * * \param[out] maskLeft Mask of the left image (initialized to corresponding image size). * \param[out] maskRight Mask of the right image (initialized to corresponding image size). * * \return True. */ virtual bool computeMask( image::Image< unsigned char > & maskLeft, image::Image< unsigned char > & maskRight ) { std::vector< matching::IndMatch > vec_KVLDMatches; image::Image< unsigned char > imageL, imageR; image::ReadImage( _sLeftImage.c_str(), &imageL ); image::ReadImage( _sRightImage.c_str(), &imageR ); image::Image< float > imgA ( imageL.GetMat().cast< float >() ); image::Image< float > imgB(imageR.GetMat().cast< float >()); std::vector< Pair > matchesFiltered, matchesPair; for( std::vector< matching::IndMatch >::const_iterator iter_match = _vec_PutativeMatches.begin(); iter_match != _vec_PutativeMatches.end(); ++iter_match ) { matchesPair.push_back( std::make_pair( iter_match->i_, iter_match->j_ ) ); } std::vector< double > vec_score; //In order to illustrate the gvld(or vld)-consistant neighbors, the following two parameters has been externalized as inputs of the function KVLD. openMVG::Mat E = openMVG::Mat::Ones( _vec_PutativeMatches.size(), _vec_PutativeMatches.size() ) * ( -1 ); // gvld-consistancy matrix, intitialized to -1, >0 consistancy value, -1=unknow, -2=false std::vector< bool > valide( _vec_PutativeMatches.size(), true );// indices of match in the initial matches, if true at the end of KVLD, a match is kept. size_t it_num = 0; KvldParameters kvldparameters;//initial parameters of KVLD //kvldparameters.K = 5; while ( it_num < 5 && kvldparameters.inlierRate > KVLD( imgA, imgB, _vec_featsL, _vec_featsR, matchesPair, matchesFiltered, vec_score, E, valide, kvldparameters ) ) { kvldparameters.inlierRate /= 2; std::cout<<"low inlier rate, re-select matches with new rate="<<kvldparameters.inlierRate<<std::endl; kvldparameters.K = 2; it_num++; } bool bOk = false; if( !matchesPair.empty()) { // Get mask getKVLDMask( &maskLeft, &maskRight, _vec_featsL, _vec_featsR, matchesPair, valide, E); bOk = true; } else{ maskLeft.fill( 0 ); maskRight.fill( 0 ); } return bOk; }
int main(int argc,char*argv[]) { std::cout<<"Warming: K-VLD may suffer performance degradation under Linux OS!"<<std::endl <<"Please first check existing result in the output folder as a reference!"<<std::endl; //================= load images ======================// cv::Mat image1, image2; int imageID=4;// index of a pair of images you want to use in folder demo_images std::string index; std::stringstream f; f<<imageID; f>>index; std::string input=std::string(SOURCE_DIR)+"/demo_image/IMG_"; image1= cv::imread(input+index+".jpg", CV_LOAD_IMAGE_GRAYSCALE); image2= cv::imread(input+index+"bis.jpg", CV_LOAD_IMAGE_GRAYSCALE); cv::Mat image1color, image2color, concat;//for visualization image1color= cv::imread(input+index+".jpg", CV_LOAD_IMAGE_COLOR); image2color= cv::imread(input+index+"bis.jpg", CV_LOAD_IMAGE_COLOR); //=============== compute SIFT points =================// std::cout<<"Extracting SIFT features"<<std::endl; std::vector<cv::KeyPoint> feat1,feat2; cv::SIFT detector;//default setting is ok, 5 levels generate too much features cv::SiftDescriptorExtractor extractor; cv::Mat descriptors1,descriptors2; detector.detect(image1,feat1); extractor.compute(image1,feat1,descriptors1); std::cout<< "sift:: 1st image: " << feat1.size() << " keypoints"<<std::endl; detector.detect(image2,feat2); extractor.compute(image2,feat2,descriptors2); std::cout<< "sift:: 2nd image: " << feat2.size() << " keypoints"<<std::endl; //=============== compute matches using brute force matching ====================// std::vector<cv::DMatch> matches; bool bSymmetricMatches = false;//caution, activate this with knn matching will cause errors. cv::BFMatcher matcher(cv::NORM_L2, bSymmetricMatches); if (bSymmetricMatches){ matcher.match(descriptors1,descriptors2,matches); } else { std::vector<std::vector<cv::DMatch>> knnmatches; matcher.knnMatch(descriptors1,descriptors2,knnmatches,2); for (std::vector<std::vector<cv::DMatch>>::const_iterator it=knnmatches.begin();it!=knnmatches.end();it++){ if (it->at(0).distance<sift_matching_criterion*it->at(1).distance) matches.push_back((*it)[0]); } } //=============== convert openCV sturctures to KVLD recognized elements Image<float> If1, If2; Convert_image(image1, If1); Convert_image(image2, If2); std::vector<keypoint> F1, F2; Convert_detectors(feat1,F1);//we only need detectors for KVLD Convert_detectors(feat2,F2);//we only need detectors for KVLD std::vector<Pair> matchesPair; Convert_matches(matches,matchesPair); //=============================== KVLD method ==================================// std::cout<<"K-VLD starts with "<<matches.size()<<" matches"<<std::endl; std::vector<Pair> matchesFiltered; std::vector<double> vec_score; //In order to illustrate the gvld(or vld)-consistant neighbors, the following two parameters has been externalized as inputs of the function KVLD. libNumerics::matrix<float> E = libNumerics::matrix<float>::ones(matches.size(),matches.size())*(-1); // gvld-consistency matrix, intitialized to -1, >0 consistency value, -1=unknow, -2=false std::vector<bool> valide(matches.size(), true);// indices of match in the initial matches, if true at the end of KVLD, a match is kept. size_t it_num=0; KvldParameters kvldparameters;//initial parameters of KVLD while (it_num < 5 && kvldparameters.inlierRate>KVLD(If1, If2,F1,F2, matchesPair, matchesFiltered, vec_score,E,valide,kvldparameters)) { kvldparameters.inlierRate/=2; kvldparameters.rang_ratio=sqrt(2.0f); std::cout<<"low inlier rate, re-select matches with new rate="<<kvldparameters.inlierRate<<std::endl; if (matchesFiltered.size()==0) kvldparameters.K=2; it_num++; } std::cout<<"K-VLD filter ends with "<<matchesFiltered.size()<<" selected matches"<<std::endl; //================= write files to output folder ==================// std::cout<<"Writing results to the output folder..."<<std::endl; std::string output=std::string(SOURCE_DIR)+"/demo_output/IMG_"+index+"_"; writeResult(output,F1, F2, matchesPair, matchesFiltered, vec_score); //================= Visualize matching result ====================// cv::vconcat(image1color, image2color,concat); for( std::vector<cv::DMatch>::const_iterator ptr = matches.begin(); ptr != matches.end(); ++ptr) { cv::KeyPoint start = feat1[ptr->queryIdx]; cv::KeyPoint end = feat2[ptr->trainIdx]; cv::line( concat,start.pt, end.pt+cv::Point2f(0,image1.rows),cv::Scalar(0, 255,0 )); } cv::imwrite(output+"initial.png",concat); //========== KVLD result =============// cv::vconcat(image1color, image2color,concat); //draw gvld-consistant neighbors (not exhostive) for (int it1=0; it1<matchesPair.size()-1;it1++){ for (int it2=it1+1; it2<matchesPair.size();it2++){ if (valide[it1] && valide[it2] && E(it1,it2)>=0){ cv::KeyPoint l1 = feat1[matchesPair[it1].first]; cv::KeyPoint l2 = feat1[matchesPair[it2].first]; cv::KeyPoint r1 = feat2[matchesPair[it1].second]; cv::KeyPoint r2 = feat2[matchesPair[it2].second]; cv::line(concat,l1.pt, l2.pt,cv::Scalar(255,0,255),2); cv::line(concat,r1.pt+cv::Point2f(0,image1.rows), r2.pt+cv::Point2f(0,image1.rows),cv::Scalar(255,0,255),2); } } } for( std::vector<Pair >::const_iterator ptr = matchesFiltered.begin(); ptr != matchesFiltered.end(); ++ptr) { size_t i = ptr->first; size_t j = ptr->second; cv::KeyPoint start = feat1[i]; cv::KeyPoint end = feat2[j]; cv::line( concat,start.pt, end.pt+cv::Point2f(0,image1.rows),cv::Scalar(0, 255, 0 )); } cv::imwrite(output+"kvld_filtered.png",concat); std::cout<<"Please check the output folder for results."<<std::endl; return 0; }