mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
7.4 KiB
214 lines
7.4 KiB
/*M/////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. |
|
// |
|
// By downloading, copying, installing or using the software you agree to this license. |
|
// If you do not agree to this license, do not download, install, |
|
// copy or use the software. |
|
// |
|
// This file originates from the openFABMAP project: |
|
// [http://code.google.com/p/openfabmap/] |
|
// |
|
// For published work which uses all or part of OpenFABMAP, please cite: |
|
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6224843] |
|
// |
|
// Original Algorithm by Mark Cummins and Paul Newman: |
|
// [http://ijr.sagepub.com/content/27/6/647.short] |
|
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=5613942] |
|
// [http://ijr.sagepub.com/content/30/9/1100.abstract] |
|
// |
|
// License Agreement |
|
// |
|
// Copyright (C) 2012 Arren Glover [aj.glover@qut.edu.au] and |
|
// Will Maddern [w.maddern@qut.edu.au], all rights reserved. |
|
// |
|
// |
|
// Redistribution and use in source and binary forms, with or without modification, |
|
// are permitted provided that the following conditions are met: |
|
// |
|
// * Redistribution's of source code must retain the above copyright notice, |
|
// this list of conditions and the following disclaimer. |
|
// |
|
// * Redistribution's in binary form must reproduce the above copyright notice, |
|
// this list of conditions and the following disclaimer in the documentation |
|
// and/or other materials provided with the distribution. |
|
// |
|
// * The name of the copyright holders may not be used to endorse or promote products |
|
// derived from this software without specific prior written permission. |
|
// |
|
// This software is provided by the copyright holders and contributors "as is" and |
|
// any express or implied warranties, including, but not limited to, the implied |
|
// warranties of merchantability and fitness for a particular purpose are disclaimed. |
|
// In no event shall the Intel Corporation or contributors be liable for any direct, |
|
// indirect, incidental, special, exemplary, or consequential damages |
|
// (including, but not limited to, procurement of substitute goods or services; |
|
// loss of use, data, or profits; or business interruption) however caused |
|
// and on any theory of liability, whether in contract, strict liability, |
|
// or tort (including negligence or otherwise) arising in any way out of |
|
// the use of this software, even if advised of the possibility of such damage. |
|
// |
|
//M*/ |
|
|
|
|
|
#include "opencv2/opencv.hpp" |
|
#include "opencv2/nonfree/nonfree.hpp" |
|
|
|
using namespace cv; |
|
using namespace std; |
|
|
|
int main(int argc, char * argv[]) { |
|
|
|
/* |
|
|
|
Note: the vocabulary and training data is specifically made for this openCV |
|
example. It is not reccomended for use with other datasets as it is |
|
intentionally small to reduce baggage in the openCV project. |
|
|
|
A new vocabulary can be generated using the supplied BOWMSCtrainer (or other |
|
clustering method such as K-means |
|
|
|
New training data can be generated by extracting bag-of-words using the |
|
openCV BOWImgDescriptorExtractor class. |
|
|
|
vocabulary, chow-liu tree, training data, and test data can all be saved and |
|
loaded using openCV's FileStorage class and it is not necessary to generate |
|
data each time as done in this example |
|
|
|
*/ |
|
|
|
cout << "This sample program demonstrates the FAB-MAP image matching " |
|
"algorithm" << endl << endl; |
|
|
|
string dataDir; |
|
if (argc == 1) { |
|
dataDir = "fabmap/"; |
|
} else if (argc == 2) { |
|
dataDir = string(argv[1]); |
|
dataDir += "/"; |
|
} else { |
|
//incorrect arguments |
|
cout << "Usage: fabmap_sample <sample data directory>" << |
|
endl; |
|
return -1; |
|
} |
|
|
|
FileStorage fs; |
|
|
|
//load/generate vocab |
|
cout << "Loading Vocabulary: " << |
|
dataDir + string("vocab_small.yml") << endl << endl; |
|
fs.open(dataDir + string("vocab_small.yml"), FileStorage::READ); |
|
Mat vocab; |
|
fs["Vocabulary"] >> vocab; |
|
if (vocab.empty()) { |
|
cerr << "Vocabulary not found" << endl; |
|
return -1; |
|
} |
|
fs.release(); |
|
|
|
//load/generate training data |
|
|
|
cout << "Loading Training Data: " << |
|
dataDir + string("train_data_small.yml") << endl << endl; |
|
fs.open(dataDir + string("train_data_small.yml"), FileStorage::READ); |
|
Mat trainData; |
|
fs["BOWImageDescs"] >> trainData; |
|
if (trainData.empty()) { |
|
cerr << "Training Data not found" << endl; |
|
return -1; |
|
} |
|
fs.release(); |
|
|
|
//create Chow-liu tree |
|
cout << "Making Chow-Liu Tree from training data" << endl << |
|
endl; |
|
of2::ChowLiuTree treeBuilder; |
|
treeBuilder.add(trainData); |
|
Mat tree = treeBuilder.make(); |
|
|
|
//generate test data |
|
cout << "Extracting Test Data from images" << endl << |
|
endl; |
|
Ptr<FeatureDetector> detector = |
|
new DynamicAdaptedFeatureDetector( |
|
AdjusterAdapter::create("STAR"), 130, 150, 5); |
|
Ptr<DescriptorExtractor> extractor = |
|
new SurfDescriptorExtractor(1000, 4, 2, false, true); |
|
Ptr<DescriptorMatcher> matcher = |
|
DescriptorMatcher::create("FlannBased"); |
|
|
|
BOWImgDescriptorExtractor bide(extractor, matcher); |
|
bide.setVocabulary(vocab); |
|
|
|
vector<string> imageNames; |
|
imageNames.push_back(string("stlucia_test_small0000.jpeg")); |
|
imageNames.push_back(string("stlucia_test_small0001.jpeg")); |
|
imageNames.push_back(string("stlucia_test_small0002.jpeg")); |
|
imageNames.push_back(string("stlucia_test_small0003.jpeg")); |
|
imageNames.push_back(string("stlucia_test_small0004.jpeg")); |
|
imageNames.push_back(string("stlucia_test_small0005.jpeg")); |
|
imageNames.push_back(string("stlucia_test_small0006.jpeg")); |
|
imageNames.push_back(string("stlucia_test_small0007.jpeg")); |
|
imageNames.push_back(string("stlucia_test_small0008.jpeg")); |
|
imageNames.push_back(string("stlucia_test_small0009.jpeg")); |
|
|
|
Mat testData; |
|
Mat frame; |
|
Mat bow; |
|
vector<KeyPoint> kpts; |
|
|
|
for(size_t i = 0; i < imageNames.size(); i++) { |
|
cout << dataDir + imageNames[i] << endl; |
|
frame = imread(dataDir + imageNames[i]); |
|
if(frame.empty()) { |
|
cerr << "Test images not found" << endl; |
|
return -1; |
|
} |
|
|
|
detector->detect(frame, kpts); |
|
|
|
bide.compute(frame, kpts, bow); |
|
|
|
testData.push_back(bow); |
|
|
|
drawKeypoints(frame, kpts, frame); |
|
imshow(imageNames[i], frame); |
|
waitKey(10); |
|
} |
|
|
|
//run fabmap |
|
cout << "Running FAB-MAP algorithm" << endl << |
|
endl; |
|
Ptr<of2::FabMap> fabmap; |
|
|
|
fabmap = new of2::FabMap2(tree, 0.39, 0, of2::FabMap::SAMPLED | |
|
of2::FabMap::CHOW_LIU); |
|
fabmap->addTraining(trainData); |
|
|
|
vector<of2::IMatch> matches; |
|
fabmap->compare(testData, matches, true); |
|
|
|
//display output |
|
Mat result_small = Mat::zeros(10, 10, CV_8UC1); |
|
vector<of2::IMatch>::iterator l; |
|
|
|
for(l = matches.begin(); l != matches.end(); l++) { |
|
if(l->imgIdx < 0) { |
|
result_small.at<char>(l->queryIdx, l->queryIdx) = |
|
(char)(l->match*255); |
|
|
|
} else { |
|
result_small.at<char>(l->queryIdx, l->imgIdx) = |
|
(char)(l->match*255); |
|
} |
|
} |
|
|
|
Mat result_large(100, 100, CV_8UC1); |
|
resize(result_small, result_large, Size(500, 500), 0, 0, INTER_NEAREST); |
|
|
|
cout << endl << "Press any key to exit" << endl; |
|
imshow("Confusion Matrix", result_large); |
|
waitKey(); |
|
|
|
return 0; |
|
}
|
|
|