void build_model() { vector<Mat> trainDesc; FeatureDetector *detector = new SurfFeatureDetector(); DescriptorExtractor *extractor = new SurfDescriptorExtractor(); // Generate descriptors from the image db fs::path p = fs::system_complete(IMAGE_DATABASE); fs::directory_iterator end_iter; for(fs::directory_iterator dir_itr(p); dir_itr != end_iter; ++dir_itr) { string img_name(dir_itr->path().string()); Mat img = imread(img_name, CV_LOAD_IMAGE_GRAYSCALE); // feature extraction vector<KeyPoint> keypoints; detector->detect(img, keypoints); // feature description Mat descriptor; extractor->compute(img, keypoints, descriptor); trainDesc.push_back(descriptor); imgNames.push_back(img_name); } // train the model matcher->add(trainDesc); matcher->train(); // Clean up delete detector; delete extractor; }
string exec_match(Mat testDesc, int match_method) { vector<vector<DMatch> > knnMatches; vector<DMatch> annMatches; vector<int> bestMatches(imgNames.size(), 0); // apply the required matching method switch(match_method) { case 1: { int knn = 1; matcher->knnMatch(testDesc, knnMatches, knn); // Filter results for(vector<vector<DMatch> >::const_iterator it = knnMatches.begin(); it != knnMatches.end(); ++it) { for(vector<DMatch>::const_iterator it2 = it->begin(); it2 != it->end(); ++it2) { ++bestMatches[(*it2).imgIdx]; } } } break; case 2: { matcher->match(testDesc, annMatches); for(vector<DMatch>::const_iterator iter = annMatches.begin(); iter != annMatches.end(); ++iter) { ++bestMatches[(*iter).imgIdx]; } } break; } // Filter results /* for(vector<vector<DMatch> >::const_iterator it = knnMatches.begin(); it != knnMatches.end(); ++it){ for(vector<DMatch>::const_iterator it2 = it->begin(); it2 != it->end(); ++it2){ ++bestMatches[(*it2).imgIdx]; } } */ // Find best match int bestScore = 0; int bestIdx = -1; for(int i = 0; i < bestMatches.size(); ++i){ if(bestMatches[i] >= bestScore){ bestScore = bestMatches[i]; bestIdx = i; } } string imgBaseName = string(fs::basename(imgNames.at(bestIdx))); boost::replace_all(imgBaseName, "-", " "); return imgBaseName; }
static double match(const vector<KeyPoint>& /*kpts_train*/, const vector<KeyPoint>& /*kpts_query*/, DescriptorMatcher& matcher, const Mat& train, const Mat& query, vector<DMatch>& matches) { double t = (double)getTickCount(); matcher.match(query, train, matches); //Using features2d return ((double)getTickCount() - t) / getTickFrequency(); }
void ratioTestMatching(DescriptorMatcher& descriptorMatcher, const Mat& descriptors1, const Mat& descriptors2, vector<DMatch>& filteredMatches12, float ratio = 0.6f) { const int knn = 2; filteredMatches12.clear(); vector<vector<DMatch> > matches12; descriptorMatcher.knnMatch(descriptors1, descriptors2, matches12, 2); for (size_t m = 0; m < matches12.size(); m++) { if (matches12[m][0].distance / matches12[m][1].distance < ratio) filteredMatches12.push_back(matches12[m][0]); } }