28 #include <opencv2/core/core.hpp>
29 #include <opencv2/core/types_c.h>
30 #include <opencv2/highgui/highgui_c.h>
31 #include <opencv2/imgproc/imgproc_c.h>
32 #include <opencv2/flann/miniflann.hpp>
33 #include <opencv2/features2d/features2d.hpp>
34 #include <opencv2/nonfree/features2d.hpp>
49 "vocabularyComparison.exe \"dictionary/path\"\n"
50 " Dictionary path example: \"data/Dictionary49k.txt\""
51 " Note that 400 first descriptors in the file are used as queries.\n");
64 std::string dictionaryPath =
argv[argc-1];
65 std::list<std::vector<float> > objectDescriptors;
67 std::map<int, std::vector<float> > descriptors;
70 int objectDescriptorsSize= 400;
73 if(!dictionaryPath.empty())
75 file.open(dictionaryPath.c_str(), std::ifstream::in);
79 UDEBUG(
"Loading the dictionary from \"%s\"", dictionaryPath.c_str());
83 std::list<std::string> strList;
86 for(std::list<std::string>::iterator
iter = strList.begin();
iter != strList.end(); ++
iter)
90 dimension = std::atoi(
iter->c_str());
95 if(dimension == 0 || dimension > 1000)
97 UERROR(
"Invalid dictionary file, visual word dimension (%d) is not valid, \"%s\"", dimension, dictionaryPath.c_str());
101 int descriptorsLoaded = 0;
107 if((
int)strList.size() == dimension+1)
110 std::list<std::string>::iterator
iter = strList.begin();
111 int id = atoi(
iter->c_str());
118 for(;
i<dimension &&
iter != strList.end(); ++
i, ++
iter)
127 if(++descriptorsLoaded<=objectDescriptorsSize)
134 descriptors.insert(std::make_pair(
id,
descriptor));
139 UWARN(
"Cannot parse line \"%s\"",
str.c_str());
144 UDEBUG(
"Time loading dictionary = %fs, dimension=%d",
timer.ticks(), dimension);
148 UERROR(
"Cannot open dictionary file \"%s\"", dictionaryPath.c_str());
152 if(descriptors.size() && objectDescriptors.size() && dimension)
157 UDEBUG(
"Creating data structures...");
159 dataTree = cv::Mat((
int)descriptors.size(), dimension, CV_32F);
162 std::map<int, std::vector<float> >::const_iterator
iter = descriptors.begin();
163 for(
unsigned int i=0;
i < descriptors.size(); ++
i, ++
iter)
167 memcpy(dataTree.ptr<
float>(
i),
iter->second.data(), dimension*
sizeof(
float));
173 queries = cv::Mat((
int)objectDescriptors.size(), dimension, CV_32F);
175 std::list<std::vector<float> >::const_iterator
iter = objectDescriptors.begin();
176 for(
unsigned int i=0;
i < objectDescriptors.size(); ++
i, ++
iter)
179 memcpy(queries.ptr<
float>(
i),
iter->data(), dimension*
sizeof(
float));
185 UDEBUG(
"descriptors.size()=%d, objectDescriptorsSize=%d, copying data = %f s",descriptors.size(), objectDescriptors.size(),
timer.ticks());
187 UDEBUG(
"Creating indexes...");
189 UDEBUG(
"Time to create linearIndex = %f s",
timer.ticks());
192 UDEBUG(
"Time to create kdTreeIndex1 = %f s",
timer.ticks());
195 UDEBUG(
"Time to create kdTreeIndex4 = %f s",
timer.ticks());
198 UDEBUG(
"Time to create kMeansIndex = %f s",
timer.ticks());
201 UDEBUG(
"Time to create compositeIndex = %f s",
timer.ticks());
207 UDEBUG(
"Search indexes...");
209 cv::Mat
results(queries.rows, k, CV_32SC1);
210 cv::Mat dists(queries.rows, k, CV_32FC1);
212 linearIndex->knnSearch(queries,
results, dists, k);
214 cv::Mat transposedLinear = dists.t();
215 UDEBUG(
"Time to search linearIndex = %f s",
timer.ticks());
217 kdTreeIndex1->knnSearch(queries,
results, dists, k);
219 cv::Mat transposed = dists.t();
220 UDEBUG(
"Time to search kdTreeIndex1 = %f s (size=%d, dist error(k1,k2)=(%f,%f))",
225 (
float*)transposedLinear.data,
226 transposedLinear.cols),
229 &transposedLinear.at<
float>(1,0),
230 transposedLinear.cols));
232 kdTreeIndex4->knnSearch(queries,
results, dists, k);
234 transposed = dists.t();
235 UDEBUG(
"Time to search kdTreeIndex4 = %f s (size=%d, dist error(k1,k2)=(%f,%f))",
240 (
float*)transposedLinear.data,
241 transposedLinear.cols),
244 &transposedLinear.at<
float>(1,0),
245 transposedLinear.cols));
247 kMeansIndex->knnSearch(queries,
results, dists, k);
249 transposed = dists.t();
250 UDEBUG(
"Time to search kMeansIndex = %f s (size=%d, dist error(k1,k2)=(%f,%f))",
255 (
float*)transposedLinear.data,
256 transposedLinear.cols),
259 &transposedLinear.at<
float>(1,0),
260 transposedLinear.cols));
262 compositeIndex->knnSearch(queries,
results, dists, k);
264 transposed = dists.t();
265 UDEBUG(
"Time to search compositeIndex = %f s (size=%d, dist error(k1,k2)=(%f,%f))",
270 (
float*)transposedLinear.data,
271 transposedLinear.cols),
274 &transposedLinear.at<
float>(1,0),
275 transposedLinear.cols));
284 delete compositeIndex;