OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
Functions
match-test.cpp File Reference
#include <opencv/cv.h>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/objdetect.hpp>
#include <vector>
#include <iostream>
#include <string>

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 30 of file match-test.cpp.

31 {
32  vector<String> typeDesc;
33  vector<String> typeAlgoMatch;
34  vector<String> fileName;
35 
36  if (argc < 3)
37  {
38  help(argv[0]);
39  return 0;
40  }
41 
42  // This descriptor are going to be detect and compute
43  typeDesc.push_back("AKAZE-DESCRIPTOR_KAZE_UPRIGHT"); // see http://docs.opencv.org/trunk/d8/d30/classcv_1_1AKAZE.html
44  typeDesc.push_back("AKAZE"); // see http://docs.opencv.org/trunk/d8/d30/classcv_1_1AKAZE.html
45  typeDesc.push_back("ORB"); // see http://docs.opencv.org/trunk/de/dbf/classcv_1_1BRISK.html
46  typeDesc.push_back("BRISK"); // see http://docs.opencv.org/trunk/db/d95/classcv_1_1ORB.html
47 
48  // This algorithm would be used to match descriptors see http://docs.opencv.org/trunk/db/d39/classcv_1_1DescriptorMatcher.html#ab5dc5036569ecc8d47565007fa518257
49  typeAlgoMatch.push_back("BruteForce");
50  typeAlgoMatch.push_back("BruteForce-L1");
51  typeAlgoMatch.push_back("BruteForce-Hamming");
52  typeAlgoMatch.push_back("BruteForce-Hamming(2)");
53 
54  const String keys = "{@image1 | | Reference image }"
55  "{@image2 | | Comparison image }"
56  "{help h | | }";
57  CommandLineParser parser(argc, argv, keys);
58  if (parser.has("help"))
59  {
60  help(argv[0]);
61  return 0;
62  }
63  fileName.push_back(parser.get<string>((int) 0));
64  fileName.push_back(parser.get<string>(1));
65  Mat img1 = imread(fileName[0], IMREAD_GRAYSCALE);
66  Mat img2 = imread(fileName[1], IMREAD_GRAYSCALE);
67  if (img1.rows * img1.cols <= 0)
68  {
69  cout << "Image " << fileName[0] << " is empty or cannot be found\n";
70  return (0);
71  }
72  if (img2.rows * img2.cols <= 0)
73  {
74  cout << "Image " << fileName[1] << " is empty or cannot be found\n";
75  return (0);
76  }
77 
78  vector<double> desMethCmp;
79  Ptr<Feature2D> b;
80 
81  // Descriptor loop
82  vector<String>::iterator itDesc;
83  for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); ++itDesc)
84  {
85  Ptr<DescriptorMatcher> descriptorMatcher;
86  // Match between img1 and img2
87  vector<DMatch> matches;
88  // keypoint for img1 and img2
89  vector<KeyPoint> keyImg1, keyImg2;
90  // Descriptor for img1 and img2
91  Mat descImg1, descImg2;
92  vector<String>::iterator itMatcher = typeAlgoMatch.end();
93  if (*itDesc == "AKAZE-DESCRIPTOR_KAZE_UPRIGHT")
94  {
95  b = AKAZE::create(AKAZE::DESCRIPTOR_KAZE_UPRIGHT);
96  }
97  if (*itDesc == "AKAZE")
98  {
99  b = AKAZE::create();
100  }
101  if (*itDesc == "ORB")
102  {
103  b = ORB::create();
104  }
105  else if (*itDesc == "BRISK")
106  {
107  b = BRISK::create();
108  }
109  try
110  {
111  // We can detect keypoint with detect method and then compute their descriptors:
112  b->detect(img1, keyImg1, Mat());
113  b->compute(img1, keyImg1, descImg1);
114 
115  // or detect and compute descriptors in one step
116  b->detectAndCompute(img2, Mat(), keyImg2, descImg2, false);
117 
118  // Match method loop
119  for (itMatcher = typeAlgoMatch.begin(); itMatcher != typeAlgoMatch.end(); ++itMatcher)
120  {
121  descriptorMatcher = DescriptorMatcher::create(*itMatcher);
122  if (((*itMatcher == "BruteForce-Hamming") || (*itMatcher == "BruteForce-Hamming(2)")) &&
123  ((b->descriptorType() == CV_32F) || (b->defaultNorm() <= NORM_L2SQR)))
124  {
125  cout << "**************************************************************************\n";
126  cout << "It's strange. You should use Hamming distance only for a binary descriptor\n";
127  cout << "**************************************************************************\n";
128  }
129  if ((*itMatcher == "BruteForce" || *itMatcher == "BruteForce-L1") && (b->defaultNorm()
130  >= NORM_HAMMING))
131  {
132  cout << "**************************************************************************\n";
133  cout << "It's strange. You shouldn't use L1 or L2 distance for a binary descriptor\n";
134  cout << "**************************************************************************\n";
135  }
136  try
137  {
138  descriptorMatcher->match(descImg1, descImg2, matches, Mat());
139  // Keep best matches only to have a nice drawing.
140  // We sort distance between descriptor matches
141  Mat index;
142  int nbMatch = int(matches.size());
143  Mat tab(nbMatch, 1, CV_32F);
144  for (int i = 0; i < nbMatch; i++)
145  {
146  tab.at<float>(i, 0) = matches[i].distance;
147  }
148  sortIdx(tab, index, SORT_EVERY_COLUMN + SORT_ASCENDING);
149  vector<DMatch> bestMatches;
150  for (int i = 0; i < 30; i++)
151  {
152  bestMatches.push_back(matches[index.at<int>(i, 0)]);
153  }
154  Mat result;
155  drawMatches(img1, keyImg1, img2, keyImg2, bestMatches, result);
156  namedWindow(*itDesc + ": " + *itMatcher, WINDOW_AUTOSIZE);
157  imshow(*itDesc + ": " + *itMatcher, result);
158  // Saved result could be wrong due to bug 4308
159  FileStorage fs(*itDesc + "_" + *itMatcher + ".yml", FileStorage::WRITE);
160  fs << "Matches" << matches;
161  vector<DMatch>::iterator it;
162  cout << "**********Match results**********\n";
163  cout << "Index \tIndex \tdistance\n";
164  cout << "in img1\tin img2\n";
165  // Use to compute distance between keyPoint matches and to evaluate match algorithm
166  double cumSumDist2 = 0;
167  for (it = bestMatches.begin(); it != bestMatches.end(); ++it)
168  {
169  cout << it->queryIdx << "\t" << it->trainIdx << "\t" << it->distance << "\n";
170  Point2d p = keyImg1[it->queryIdx].pt - keyImg2[it->trainIdx].pt;
171  cumSumDist2 = p.x * p.x + p.y * p.y;
172  }
173  desMethCmp.push_back(cumSumDist2);
174  waitKey();
175  }
176  catch (Exception& e)
177  {
178  cout << e.msg << endl;
179  cout << "Cumulative distance cannot be computed." << endl;
180  desMethCmp.push_back(-1);
181  }
182  }
183  }
184  catch (Exception& e)
185  {
186  cout << "Feature : " << *itDesc << "\n";
187  if (itMatcher != typeAlgoMatch.end())
188  {
189  cout << "Matcher : " << *itMatcher << "\n";
190  }
191  cout << e.msg << endl;
192  }
193  }
194  int i = 0;
195  cout << "Cumulative distance between keypoint match for different algorithm and feature detector \n\t";
196  cout << "We cannot say which is the best but we can say results are differents! \n\t";
197  for (vector<String>::iterator itMatcher = typeAlgoMatch.begin();
198  itMatcher != typeAlgoMatch.end(); ++itMatcher)
199  {
200  cout << *itMatcher << "\t";
201  }
202  cout << "\n";
203  for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); ++itDesc)
204  {
205  cout << *itDesc << "\t";
206  for (vector<String>::iterator itMatcher = typeAlgoMatch.begin();
207  itMatcher != typeAlgoMatch.end(); ++itMatcher, ++i)
208  {
209  cout << desMethCmp[i] << "\t";
210  }
211  cout << "\n";
212  }
213  return 0;
214 }
float distance(double lat1, double lon1, double lat2, double lon2, int units)