I have modified source file and add a chart to have distance between keypoint for decriptor function og matching algorithm
My english is not good so you can change some words in my comment
This commit is contained in:
parent
9ddb8bdb8b
commit
09e9e8ad9f
@ -5,37 +5,73 @@
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
|
||||
int main(void)
|
||||
static void help()
|
||||
{
|
||||
cout << "\n This program demonstrates how to detect compute and match ORB BRISK and AKAZE descriptors \n"
|
||||
"Usage: \n"
|
||||
" ./matchmethod_orb_akaze_brisk <image1(../data/basketball1.png as default)> <image2(../data/basketball2.png as default)>\n"
|
||||
"Press a key when image window is active to change algorithm or descriptor";
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
vector<String> typeDesc;
|
||||
vector<String> typeAlgoMatch;
|
||||
vector<String> fileName;
|
||||
help();
|
||||
// This descriptor are going to be detect and compute
|
||||
typeDesc.push_back("AKAZE"); // see http://docs.opencv.org/trunk/d8/d30/classcv_1_1AKAZE.html
|
||||
typeDesc.push_back("ORB"); // see http://docs.opencv.org/trunk/de/dbf/classcv_1_1BRISK.html
|
||||
typeDesc.push_back("BRISK"); // see http://docs.opencv.org/trunk/db/d95/classcv_1_1ORB.html
|
||||
// This algorithm would be used to match descriptors see http://docs.opencv.org/trunk/db/d39/classcv_1_1DescriptorMatcher.html#ab5dc5036569ecc8d47565007fa518257
|
||||
typeAlgoMatch.push_back("BruteForce");
|
||||
typeAlgoMatch.push_back("BruteForce-L1");
|
||||
typeAlgoMatch.push_back("BruteForce-Hamming");
|
||||
typeAlgoMatch.push_back("BruteForce-Hamming(2)");
|
||||
if (argc==1)
|
||||
{
|
||||
fileName.push_back("../data/basketball1.png");
|
||||
fileName.push_back("../data/basketball2.png");
|
||||
}
|
||||
else if (argc==3)
|
||||
{
|
||||
fileName.push_back(argv[1]);
|
||||
fileName.push_back(argv[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
help();
|
||||
return(0);
|
||||
}
|
||||
Mat img1 = imread(fileName[0], IMREAD_GRAYSCALE);
|
||||
Mat img2 = imread(fileName[1], IMREAD_GRAYSCALE);
|
||||
if (img1.rows*img1.cols <= 0)
|
||||
{
|
||||
cout << "Image " << fileName[0] << " is empty or cannot be found\n";
|
||||
return(0);
|
||||
}
|
||||
if (img2.rows*img2.cols <= 0)
|
||||
{
|
||||
cout << "Image " << fileName[1] << " is empty or cannot be found\n";
|
||||
return(0);
|
||||
}
|
||||
|
||||
vector<String> typeDesc;
|
||||
typeDesc.push_back("AKAZE");
|
||||
typeDesc.push_back("ORB");
|
||||
typeDesc.push_back("BRISK");
|
||||
|
||||
String dataFolder("../data/");
|
||||
vector<String> fileName;
|
||||
fileName.push_back("basketball1.png");
|
||||
fileName.push_back("basketball2.png");
|
||||
|
||||
Mat img1 = imread(dataFolder+fileName[0], IMREAD_GRAYSCALE);
|
||||
Mat img2 = imread(dataFolder+fileName[1], IMREAD_GRAYSCALE);
|
||||
|
||||
vector<double> desMethCmp;
|
||||
Ptr<Feature2D> b;
|
||||
|
||||
// Descriptor loop
|
||||
vector<String>::iterator itDesc;
|
||||
// Descriptor loop
|
||||
for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++){
|
||||
for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++)
|
||||
{
|
||||
Ptr<DescriptorMatcher> descriptorMatcher;
|
||||
vector<DMatch> matches; /*<! Match between img and img2*/
|
||||
vector<KeyPoint> keyImg1; /*<! keypoint for img1 */
|
||||
vector<KeyPoint> keyImg2; /*<! keypoint for img2 */
|
||||
Mat descImg1, descImg2; /*<! Descriptor for img1 and img2 */
|
||||
// Match between img1 and img2
|
||||
vector<DMatch> matches;
|
||||
// keypoint for img1 and img2
|
||||
vector<KeyPoint> keyImg1, keyImg2;
|
||||
// Descriptor for img1 and img2
|
||||
Mat descImg1, descImg2;
|
||||
vector<String>::iterator itMatcher = typeAlgoMatch.end();
|
||||
if (*itDesc == "AKAZE"){
|
||||
b = AKAZE::create();
|
||||
@ -47,23 +83,31 @@ int main(void)
|
||||
b = BRISK::create();
|
||||
}
|
||||
try {
|
||||
// We can detect keypoint with detect method
|
||||
b->detect(img1, keyImg1, Mat());
|
||||
// and compute their descriptors with method compute
|
||||
b->compute(img1, keyImg1, descImg1);
|
||||
// or detect and compute descriptors in one step
|
||||
b->detectAndCompute(img2, Mat(),keyImg2, descImg2,false);
|
||||
// Match method loop
|
||||
for (itMatcher = typeAlgoMatch.begin(); itMatcher != typeAlgoMatch.end(); itMatcher++){
|
||||
// Match method loop
|
||||
for (itMatcher = typeAlgoMatch.begin(); itMatcher != typeAlgoMatch.end(); itMatcher++){
|
||||
descriptorMatcher = DescriptorMatcher::create(*itMatcher);
|
||||
descriptorMatcher->match(descImg1, descImg2, matches, Mat());
|
||||
// Keep best matches only to have a nice drawing
|
||||
// Keep best matches only to have a nice drawing.
|
||||
// We sort distance between descriptor matches
|
||||
Mat index;
|
||||
int nbMatch=int(matches.size());
|
||||
Mat tab(nbMatch, 1, CV_32F);
|
||||
for (int i = 0; i<nbMatch; i++)
|
||||
{
|
||||
tab.at<float>(i, 0) = matches[i].distance;
|
||||
}
|
||||
sortIdx(tab, index, SORT_EVERY_COLUMN + SORT_ASCENDING);
|
||||
vector<DMatch> bestMatches;
|
||||
for (int i = 0; i<30; i++)
|
||||
{
|
||||
bestMatches.push_back(matches[index.at<int>(i, 0)]);
|
||||
}
|
||||
Mat result;
|
||||
drawMatches(img1, keyImg1, img2, keyImg2, bestMatches, result);
|
||||
namedWindow(*itDesc+": "+*itMatcher, WINDOW_AUTOSIZE);
|
||||
@ -71,19 +115,45 @@ int main(void)
|
||||
FileStorage fs(*itDesc+"_"+*itMatcher+"_"+fileName[0]+"_"+fileName[1]+".xml", FileStorage::WRITE);
|
||||
fs<<"Matches"<<matches;
|
||||
vector<DMatch>::iterator it;
|
||||
cout << "Index \tIndex \tindex \tdistance\n";
|
||||
cout << "in img1\tin img2\timage\t\n";
|
||||
for (it = matches.begin(); it != matches.end(); it++)
|
||||
cout << it->queryIdx << "\t" << it->trainIdx << "\t" << it->imgIdx << "\t" << it->distance<<"\n";
|
||||
cout<<"**********Match results**********\n";
|
||||
cout << "Index \tIndex \tdistance\n";
|
||||
cout << "in img1\tin img2\n";
|
||||
double cumSumDist2=0; // Use to compute distance between keyPoint matches and to evaluate match algorithm
|
||||
for (it = bestMatches.begin(); it != bestMatches.end(); it++)
|
||||
{
|
||||
cout << it->queryIdx << "\t" << it->trainIdx << "\t" << it->distance << "\n";
|
||||
Point2d p=keyImg1[it->queryIdx].pt-keyImg2[it->trainIdx].pt;
|
||||
cumSumDist2=p.x*p.x+p.y*p.y;
|
||||
}
|
||||
desMethCmp.push_back(cumSumDist2);
|
||||
waitKey();
|
||||
}
|
||||
}
|
||||
catch (Exception& e){
|
||||
catch (Exception& e)
|
||||
{
|
||||
cout << "Feature : " << *itDesc << "\n";
|
||||
if (itMatcher != typeAlgoMatch.end())
|
||||
{
|
||||
cout << "Matcher : " << *itMatcher << "\n";
|
||||
}
|
||||
cout<<e.msg<<endl;
|
||||
}
|
||||
}
|
||||
int i=0;
|
||||
cout << "Cumulative distance between keypoint match for different algorithm and feature detector \n\t";
|
||||
for (vector<String>::iterator itMatcher = typeAlgoMatch.begin(); itMatcher != typeAlgoMatch.end(); itMatcher++)
|
||||
{
|
||||
cout<<*itMatcher<<"\t";
|
||||
}
|
||||
cout << "\n";
|
||||
for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++)
|
||||
{
|
||||
cout << *itDesc << "\t";
|
||||
for (vector<String>::iterator itMatcher = typeAlgoMatch.begin(); itMatcher != typeAlgoMatch.end(); itMatcher++, i++)
|
||||
{
|
||||
cout << desMethCmp[i]<<"\t";
|
||||
}
|
||||
cout<<"\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user