~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/samples/cpp/matchmethod_orb_akaze_brisk.cpp

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <opencv2/opencv.hpp>
 
2
#include <vector>
 
3
#include <iostream>
 
4
 
 
5
using namespace std;
 
6
using namespace cv;
 
7
 
 
8
static void help()
 
9
{
 
10
    cout << "\n This program demonstrates how to detect compute and match ORB BRISK and AKAZE descriptors \n"
 
11
        "Usage: \n"
 
12
        "  ./matchmethod_orb_akaze_brisk --image1=<image1(../data/basketball1.png as default)> --image2=<image2(../data/basketball2.png as default)>\n"
 
13
        "Press a key when image window is active to change algorithm or descriptor";
 
14
}
 
15
 
 
16
 
 
17
 
 
18
int main(int argc, char *argv[])
 
19
{
 
20
    vector<String> typeDesc;
 
21
    vector<String> typeAlgoMatch;
 
22
    vector<String> fileName;
 
23
    // This descriptor are going to be detect and compute
 
24
    typeDesc.push_back("AKAZE-DESCRIPTOR_KAZE_UPRIGHT");    // see http://docs.opencv.org/trunk/d8/d30/classcv_1_1AKAZE.html
 
25
    typeDesc.push_back("AKAZE");    // see http://docs.opencv.org/trunk/d8/d30/classcv_1_1AKAZE.html
 
26
    typeDesc.push_back("ORB");      // see http://docs.opencv.org/trunk/de/dbf/classcv_1_1BRISK.html
 
27
    typeDesc.push_back("BRISK");    // see http://docs.opencv.org/trunk/db/d95/classcv_1_1ORB.html
 
28
   // This algorithm would be used to match descriptors see http://docs.opencv.org/trunk/db/d39/classcv_1_1DescriptorMatcher.html#ab5dc5036569ecc8d47565007fa518257
 
29
    typeAlgoMatch.push_back("BruteForce");
 
30
    typeAlgoMatch.push_back("BruteForce-L1");
 
31
    typeAlgoMatch.push_back("BruteForce-Hamming");
 
32
    typeAlgoMatch.push_back("BruteForce-Hamming(2)");
 
33
    cv::CommandLineParser parser(argc, argv,
 
34
        "{ @image1 | ../data/basketball1.png | }"
 
35
        "{ @image2 | ../data/basketball2.png | }"
 
36
        "{help h ||}");
 
37
    if (parser.has("help"))
 
38
    {
 
39
        help();
 
40
        return 0;
 
41
    }
 
42
    fileName.push_back(parser.get<string>(0));
 
43
    fileName.push_back(parser.get<string>(1));
 
44
    Mat img1 = imread(fileName[0], IMREAD_GRAYSCALE);
 
45
    Mat img2 = imread(fileName[1], IMREAD_GRAYSCALE);
 
46
    if (img1.rows*img1.cols <= 0)
 
47
        {
 
48
        cout << "Image " << fileName[0] << " is empty or cannot be found\n";
 
49
        return(0);
 
50
        }
 
51
    if (img2.rows*img2.cols <= 0)
 
52
        {
 
53
        cout << "Image " << fileName[1] << " is empty or cannot be found\n";
 
54
        return(0);
 
55
        }
 
56
 
 
57
    vector<double> desMethCmp;
 
58
    Ptr<Feature2D> b;
 
59
 
 
60
    // Descriptor loop
 
61
    vector<String>::iterator itDesc;
 
62
    for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++)
 
63
    {
 
64
        Ptr<DescriptorMatcher> descriptorMatcher;
 
65
        // Match between img1 and img2
 
66
        vector<DMatch> matches;
 
67
        // keypoint  for img1 and img2
 
68
        vector<KeyPoint> keyImg1, keyImg2;
 
69
        // Descriptor for img1 and img2
 
70
        Mat descImg1, descImg2;
 
71
        vector<String>::iterator itMatcher = typeAlgoMatch.end();
 
72
        if (*itDesc == "AKAZE-DESCRIPTOR_KAZE_UPRIGHT"){
 
73
            b = AKAZE::create(AKAZE::DESCRIPTOR_KAZE_UPRIGHT);
 
74
            }
 
75
        if (*itDesc == "AKAZE"){
 
76
            b = AKAZE::create();
 
77
            }
 
78
        if (*itDesc == "ORB"){
 
79
            b = ORB::create();
 
80
        }
 
81
        else if (*itDesc == "BRISK"){
 
82
            b = BRISK::create();
 
83
        }
 
84
        try
 
85
        {
 
86
            // We can detect keypoint with detect method
 
87
            b->detect(img1, keyImg1, Mat());
 
88
            // and compute their descriptors with method  compute
 
89
            b->compute(img1, keyImg1, descImg1);
 
90
            // or detect and compute descriptors in one step
 
91
            b->detectAndCompute(img2, Mat(),keyImg2, descImg2,false);
 
92
            // Match method loop
 
93
            for (itMatcher = typeAlgoMatch.begin(); itMatcher != typeAlgoMatch.end(); itMatcher++){
 
94
                descriptorMatcher = DescriptorMatcher::create(*itMatcher);
 
95
                if ((*itMatcher == "BruteForce-Hamming" || *itMatcher == "BruteForce-Hamming(2)") && (b->descriptorType() == CV_32F || b->defaultNorm() <= NORM_L2SQR))
 
96
                {
 
97
                    cout << "**************************************************************************\n";
 
98
                    cout << "It's strange. You should use Hamming distance only for a binary descriptor\n";
 
99
                    cout << "**************************************************************************\n";
 
100
                }
 
101
                if ((*itMatcher == "BruteForce" || *itMatcher == "BruteForce-L1") && (b->defaultNorm() >= NORM_HAMMING))
 
102
                {
 
103
                    cout << "**************************************************************************\n";
 
104
                    cout << "It's strange. You shouldn't use L1 or L2 distance for a binary descriptor\n";
 
105
                    cout << "**************************************************************************\n";
 
106
                }
 
107
                try
 
108
                {
 
109
                    descriptorMatcher->match(descImg1, descImg2, matches, Mat());
 
110
                    // Keep best matches only to have a nice drawing.
 
111
                    // We sort distance between descriptor matches
 
112
                    Mat index;
 
113
                    int nbMatch=int(matches.size());
 
114
                    Mat tab(nbMatch, 1, CV_32F);
 
115
                    for (int i = 0; i<nbMatch; i++)
 
116
                    {
 
117
                        tab.at<float>(i, 0) = matches[i].distance;
 
118
                    }
 
119
                    sortIdx(tab, index, SORT_EVERY_COLUMN + SORT_ASCENDING);
 
120
                    vector<DMatch> bestMatches;
 
121
                    for (int i = 0; i<30; i++)
 
122
                    {
 
123
                        bestMatches.push_back(matches[index.at<int>(i, 0)]);
 
124
                    }
 
125
                    Mat result;
 
126
                    drawMatches(img1, keyImg1, img2, keyImg2, bestMatches, result);
 
127
                    namedWindow(*itDesc+": "+*itMatcher, WINDOW_AUTOSIZE);
 
128
                    imshow(*itDesc + ": " + *itMatcher, result);
 
129
                    // Saved result could be wrong due to bug 4308
 
130
                    FileStorage fs(*itDesc + "_" + *itMatcher + ".yml", FileStorage::WRITE);
 
131
                    fs<<"Matches"<<matches;
 
132
                    vector<DMatch>::iterator it;
 
133
                    cout<<"**********Match results**********\n";
 
134
                    cout << "Index \tIndex \tdistance\n";
 
135
                    cout << "in img1\tin img2\n";
 
136
                    // Use to compute distance between keyPoint matches and to evaluate match algorithm
 
137
                    double cumSumDist2=0;
 
138
                    for (it = bestMatches.begin(); it != bestMatches.end(); it++)
 
139
                    {
 
140
                        cout << it->queryIdx << "\t" <<  it->trainIdx << "\t"  <<  it->distance << "\n";
 
141
                        Point2d p=keyImg1[it->queryIdx].pt-keyImg2[it->trainIdx].pt;
 
142
                        cumSumDist2=p.x*p.x+p.y*p.y;
 
143
                    }
 
144
                    desMethCmp.push_back(cumSumDist2);
 
145
                    waitKey();
 
146
                }
 
147
                catch (Exception& e)
 
148
                    {
 
149
                    cout << e.msg << endl;
 
150
                    cout << "Cumulative distance cannot be computed." << endl;
 
151
                    desMethCmp.push_back(-1);
 
152
                    }
 
153
                }
 
154
        }
 
155
        catch (Exception& e)
 
156
        {
 
157
            cout << "Feature : " << *itDesc << "\n";
 
158
            if (itMatcher != typeAlgoMatch.end())
 
159
            {
 
160
                cout << "Matcher : " << *itMatcher << "\n";
 
161
            }
 
162
            cout << e.msg << endl;
 
163
        }
 
164
    }
 
165
    int i=0;
 
166
    cout << "Cumulative distance between keypoint match for different algorithm and feature detector \n\t";
 
167
    cout << "We cannot say which is the best but we can say results are differents! \n\t";
 
168
    for (vector<String>::iterator itMatcher = typeAlgoMatch.begin(); itMatcher != typeAlgoMatch.end(); itMatcher++)
 
169
    {
 
170
        cout<<*itMatcher<<"\t";
 
171
    }
 
172
    cout << "\n";
 
173
    for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++)
 
174
    {
 
175
        cout << *itDesc << "\t";
 
176
        for (vector<String>::iterator itMatcher = typeAlgoMatch.begin(); itMatcher != typeAlgoMatch.end(); itMatcher++, i++)
 
177
        {
 
178
            cout << desMethCmp[i]<<"\t";
 
179
        }
 
180
        cout<<"\n";
 
181
    }
 
182
    return 0;
 
183
}