void OpenFABMap::compare(cv::Mat &frame, std::vector< cv::of2::IMatch > &matches, cv::Mat &bow, std::vector<cv::KeyPoint> &kpts, std::vector< std::vector < int > > &pointIDXOfCLusters, cv::Mat *completeDescriptors) { /// Get the BoW of the frame //use a FLANN matcher to generate bag-of-words representations cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased"); cv::BOWImgDescriptorExtractor bide(descriptor_extractor_, matcher); bide.setVocabulary(vocabulary_); feature_detector_->detect(frame, kpts); bide.compute(frame, kpts, bow, &pointIDXOfCLusters, completeDescriptors); /// TODO: find a way to use the returned descriptors from the bide extractor /// why? because for now it returns a 0x0 matrix, so find out why :( cv::SurfDescriptorExtractor extractor; extractor.compute(frame, kpts, *completeDescriptors); // std::cout << "#of keypoints: " << kpts.size() << " - Descriptor size: " << completeDescriptors->cols << "x" << completeDescriptors->rows << std::endl; /// Compare with the map open_fab_map_->compare(bow, matches); }
/* generate FabMap bag-of-words data : an image descriptor for each frame */ int generateBOWImageDescs(std::string dataPath, std::string bowImageDescPath, std::string vocabPath, cv::Ptr<cv::FeatureDetector> &detector, cv::Ptr<cv::DescriptorExtractor> &extractor, int minWords) { cv::FileStorage fs; //ensure not overwriting training data std::ifstream checker; checker.open(bowImageDescPath.c_str()); if(checker.is_open()) { std::cerr << bowImageDescPath << ": FabMap Training/Testing Data " "already present" << std::endl; checker.close(); return -1; } //load vocabulary std::cout << "Loading Vocabulary" << std::endl; fs.open(vocabPath, cv::FileStorage::READ); cv::Mat vocab; fs["Vocabulary"] >> vocab; if (vocab.empty()) { std::cerr << vocabPath << ": Vocabulary not found" << std::endl; return -1; } fs.release(); //use a FLANN matcher to generate bag-of-words representations cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased"); cv::BOWImgDescriptorExtractor bide(extractor, matcher); bide.setVocabulary(vocab); //load movie cv::VideoCapture movie; movie.open(dataPath); if(!movie.isOpened()) { std::cerr << dataPath << ": movie not found" << std::endl; return -1; } //extract image descriptors cv::Mat fabmapTrainData; std::cout << "Extracting Bag-of-words Image Descriptors" << std::endl; std::cout.setf(std::ios_base::fixed); std::cout.precision(0); std::ofstream maskw; if(minWords) { maskw.open(std::string(bowImageDescPath + "mask.txt").c_str()); } cv::Mat frame, bow; std::vector<cv::KeyPoint> kpts; while(movie.read(frame)) { detector->detect(frame, kpts); bide.compute(frame, kpts, bow); if(minWords) { //writing a mask file if(cv::countNonZero(bow) < minWords) { //frame masked maskw << "0" << std::endl; } else { //frame accepted maskw << "1" << std::endl; fabmapTrainData.push_back(bow); } } else { fabmapTrainData.push_back(bow); } std::cout << 100.0 * (movie.get(CV_CAP_PROP_POS_FRAMES) / movie.get(CV_CAP_PROP_FRAME_COUNT)) << "% \r"; fflush(stdout); } std::cout << "Done " << std::endl; movie.release(); //save training data fs.open(bowImageDescPath, cv::FileStorage::WRITE); fs << "BOWImageDescs" << fabmapTrainData; fs.release(); return 0; }