Detect, Compute, and Match Descriptors

This program demonstrates how to detect, compute, and match descriptors using various algorithms: ORB, BRISK, and AKAZE.

Sources:

load a pair of grayscale images

img1 = cv.imread(fullfile(mexopencv.root(),'test','basketball1.png'), 'Grayscale',true);
img2 = cv.imread(fullfile(mexopencv.root(),'test','basketball2.png'), 'Grayscale',true);

descriptors we are going to detect and compute

features = {'AKAZEUpright', 'AKAZE', 'KAZE', 'ORB', 'BRISK'};
if true
    features = [features, 'SIFT', 'SURF'];  % xfeatures2d from opencv_contrib
end

algorithms used to match descriptors

matchers = strcat('BruteForce', {'', '-L1', '-Hamming', '-Hamming(2)'});

descriptors loop

D = nan(numel(features), numel(matchers));
for i=1:numel(features)
    % create Feature2D object
    switch features{i}
        case 'AKAZEUpright'
            b = cv.AKAZE('DescriptorType','KAZEUpright');
        case 'AKAZE'
            b = cv.AKAZE();
        case 'KAZE'
            b = cv.KAZE();
        case 'ORB'
            b = cv.ORB();
        case 'BRISK'
            b = cv.BRISK();
        case 'SIFT'
            b = cv.SIFT();
        case 'SURF'
            b = cv.SURF();
    end

    % detect and compute descriptors in both images
    [kpts1, desc1] = b.detectAndCompute(img1);
    [kpts2, desc2] = b.detectAndCompute(img2);

    % matchers loop
    for j=1:numel(matchers)
        % create DescriptorMatcher object
        m = cv.DescriptorMatcher(matchers{j});

        % warn about invalid combinations of descriptors and matchers
        valid = true;
        mHam = ~isempty(strfind(matchers{j}, 'Hamming'));
        bHam = ~isempty(strfind(b.defaultNorm(), 'Hamming'));
        if mHam && (~bHam || strcmp(b.descriptorType, 'single'))
            fprintf(2, 'Hamming distance only for binary descriptors\n');
            if mexopencv.isOctave()
                %HACK: avoid unhandled C++ expections, they can crash Octave!
                valid = false;
            end
        end
        if ~mHam && bHam
            fprintf(2, 'L1 or L2 distance not for binary descriptors\n');
        end

        fprintf('%s + %s:\n', features{i}, matchers{j});
        fprintf(' %d keypoints in img1\n', numel(kpts1));
        fprintf(' %d keypoints in img2\n', numel(kpts2));
        try
            % match descriptors
            assert(valid);
            matches = m.match(desc1, desc2);
            fprintf(' %d matches\n', numel(matches));

            % save matches to file
            fname = sprintf('%s_%s.yml', features{i}, matchers{j});
            fname = fullfile(tempdir(), fname);
            cv.FileStorage(fname, struct('Matches',matches));

            % Keep only best 30 matches to have a nice drawing (sorted by dist)
            [~,ord] = sort([matches.distance]);
            ord(31:end) = [];
            matches = matches(ord);

            % pretty print matches
            if ~mexopencv.isOctave()
                t = struct2table(matches);
                t.imgIdx = [];
                display(t)
            else
                %HACK: no tables in Octave
                t = cat(1, matches.distance);
                display(t)
            end

            % draw matches and show result
            out = cv.drawMatches(img1, kpts1, img2, kpts2, matches);
            figure, imshow(out)
            title(sprintf('%s + %s', features{i}, matchers{j}))

            % compute total distances between keypoint matches
            pts1 = cat(1, kpts1([matches.queryIdx]+1).pt);
            pts2 = cat(1, kpts2([matches.trainIdx]+1).pt);
            D(i,j) = sum(sqrt(sum((pts1 - pts2).^2, 2)));
            fprintf(' %f total error\n', D(i,j));
        catch ME
            fprintf(' matching failed\n');
            %warning(getReport(ME))
        end
        fprintf('%s\n', repmat('-',1,80));
    end
end
AKAZEUpright + BruteForce:
 509 keypoints in img1
 489 keypoints in img2
 509 matches
t =
  30×3 table
    queryIdx    trainIdx    distance 
    ________    ________    _________
    225         212         0.0061414
    425         400         0.0065284
    228         216         0.0078475
    432         407         0.0078775
    285         270         0.0089423
    259         244         0.0089759
    413         388         0.0093736
      1           0          0.009867
    286         272         0.0099593
    105          91          0.010512
    115         102          0.010668
    486         464          0.010733
    287         273          0.011009
    233         219          0.011101
      3           1          0.011432
    108          94             0.012
    291         277          0.012291
    288         274           0.01242
    246         231          0.012453
      6           4          0.013142
    276         262          0.015391
    114         100          0.015577
    112          97          0.016037
    273         261          0.016045
    121         108          0.016096
      4           2          0.016369
    294         279          0.016634
    292         276          0.017646
    111          98          0.017932
    110          96          0.018505
 76.347928 total error
--------------------------------------------------------------------------------
AKAZEUpright + BruteForce-L1:
 509 keypoints in img1
 489 keypoints in img2
 509 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    225         212         0.035796
    425         400         0.039139
    432         407         0.045195
    228         216         0.047979
    286         272          0.04935
    259         244         0.052619
    285         270         0.052759
    413         388         0.055712
      1           0         0.056515
    486         464         0.060291
    105          91         0.060574
    115         102         0.061157
      3           1          0.06201
    288         274         0.065543
    233         219         0.065866
    291         277         0.065992
    287         273         0.067931
    108          94          0.07174
    246         231          0.07656
      6           4         0.078552
    276         262         0.079296
    112          97         0.091108
    273         261         0.091113
    114         100         0.091542
    294         279         0.092278
    398         376         0.092863
      4           2         0.092881
    121         108         0.093999
    292         276         0.094359
    111          98         0.097353
 75.509662 total error
--------------------------------------------------------------------------------
Hamming distance only for binary descriptors
AKAZEUpright + BruteForce-Hamming:
 509 keypoints in img1
 489 keypoints in img2
 matching failed
--------------------------------------------------------------------------------
Hamming distance only for binary descriptors
AKAZEUpright + BruteForce-Hamming(2):
 509 keypoints in img1
 489 keypoints in img2
 matching failed
--------------------------------------------------------------------------------
L1 or L2 distance not for binary descriptors
AKAZE + BruteForce:
 589 keypoints in img1
 569 keypoints in img2
 589 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    444         421              0  
    461         438              2  
    432         411         5.6569  
    310         296         8.2462  
    318         302         8.3666  
     39          25         8.4853  
    439         416         12.042  
     42          31         14.595  
    275         262         16.031  
    316         300         17.205  
    312         298         17.889  
    225         215         23.431  
    265         254         23.685  
    135         123         29.086  
    469         445         32.016  
    125         113         32.062  
    127         115         37.736  
     44          34         42.544  
    542         517         43.543  
    309         294         48.052  
    167         155         62.137  
    255         243         65.315  
    315         301         68.066  
    122         108         72.166  
    249         237         74.135  
    448         424         75.472  
    153         145         93.145  
    535         507         94.366  
    547         524             96  
    537         510         99.479  
 77.536100 total error
--------------------------------------------------------------------------------
L1 or L2 distance not for binary descriptors
AKAZE + BruteForce-L1:
 589 keypoints in img1
 569 keypoints in img2
 589 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    444         421           0     
    461         438           2     
    432         411           8     
    310         296          10     
     39          25          12     
    318         302          12     
    275         262          17     
    439         416          21     
    312         298          24     
    316         300          28     
     42          31          31     
    469         445          33     
    125         113          34     
    225         215          43     
    265         254          45     
    309         294          51     
    127         115          68     
    135         123          80     
     44          34          86     
    542         517         100     
    448         424         104     
    315         301         105     
    122         108         112     
    249         237         128     
    118         105         146     
    167         155         151     
    547         524         160     
    535         507         169     
    131         119         173     
    295         106         180     
 80.196240 total error
--------------------------------------------------------------------------------
AKAZE + BruteForce-Hamming:
 589 keypoints in img1
 569 keypoints in img2
 589 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    444         421         0       
    461         438         1       
    125         113         2       
    275         262         2       
    310         296         2       
    312         298         2       
    432         411         2       
    469         445         2       
     39          25         3       
    118         105         3       
    305         291         3       
    547         524         3       
    115         102         4       
    137         127         4       
    309         294         4       
    318         302         4       
    325         310         4       
    439         416         4       
    448         424         4       
    127         115         5       
    131         119         5       
    316         300         5       
     21          15         6       
     42          31         6       
    122         108         6       
    225         215         6       
    265         254         6       
    295         106         6       
    311         297         6       
     11           5         7       
 103.266482 total error
--------------------------------------------------------------------------------
AKAZE + BruteForce-Hamming(2):
 589 keypoints in img1
 569 keypoints in img2
 589 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    444         421         0       
    461         438         1       
    125         113         2       
    275         262         2       
    310         296         2       
    312         298         2       
    432         411         2       
    469         445         2       
     39          25         3       
    118         105         3       
    305         291         3       
    309         294         3       
    547         524         3       
    115         102         4       
    137         127         4       
    318         302         4       
    325         310         4       
    439         416         4       
    448         424         4       
    127         115         5       
    131         119         5       
    316         300         5       
     21          15         6       
     42          31         6       
    122         108         6       
    225         215         6       
    265         254         6       
    295         106         6       
    311         297         6       
     11           5         7       
 103.266482 total error
--------------------------------------------------------------------------------
KAZE + BruteForce:
 962 keypoints in img1
 909 keypoints in img2
 962 matches
t =
  30×3 table
    queryIdx    trainIdx    distance 
    ________    ________    _________
    405         388         0.0085198
    646         621         0.0088553
    457         432         0.0093376
     18          16         0.0096003
    208         193          0.010034
    449         425          0.010102
    187         176          0.010281
    511         480           0.01029
      2           1          0.010337
    216         202          0.010546
    131         123          0.011074
    818         764          0.011187
    149         142          0.011195
      0           0          0.011843
    389         370          0.012087
    191         179          0.012396
    207         191          0.013254
    196         183          0.013399
    144         138          0.014298
     14          12          0.014497
    634         610          0.014566
    454         429          0.016669
    204         188           0.01698
     96          84          0.020786
    220         206          0.021669
    145         139          0.021678
    921         863          0.021951
    532         502          0.023943
     19          17          0.024116
    447         423          0.024717
 50.046663 total error
--------------------------------------------------------------------------------
KAZE + BruteForce-L1:
 962 keypoints in img1
 909 keypoints in img2
 962 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    449         425         0.046328
    457         432         0.050101
    405         388         0.052212
    646         621         0.053055
      2           1         0.055326
     18          16         0.056384
      0           0         0.057026
    818         764         0.057264
    208         193         0.057709
    187         176         0.057777
    511         480         0.058332
    216         202         0.058883
    149         142         0.061423
    131         123         0.068747
    389         370         0.071617
    191         179         0.075301
    634         610         0.080895
    196         183         0.082588
    207         191         0.084627
    204         188         0.086547
     14          12         0.090572
    144         138         0.093892
     96          84         0.099536
    454         429          0.10454
    220         206          0.11729
    145         139          0.12303
    921         863          0.12421
    536         505          0.13232
    532         502          0.13498
     19          17          0.13511
 50.707891 total error
--------------------------------------------------------------------------------
Hamming distance only for binary descriptors
KAZE + BruteForce-Hamming:
 962 keypoints in img1
 909 keypoints in img2
 matching failed
--------------------------------------------------------------------------------
Hamming distance only for binary descriptors
KAZE + BruteForce-Hamming(2):
 962 keypoints in img1
 909 keypoints in img2
 matching failed
--------------------------------------------------------------------------------
L1 or L2 distance not for binary descriptors
ORB + BruteForce:
 500 keypoints in img1
 500 keypoints in img2
 500 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
      2          98         11.314  
    192         173         34.176  
     80          61          46.54  
     77           7         51.769  
     81          90         57.991  
    247         221         65.276  
    174         122         66.091  
    137         139         72.076  
    149         151         73.607  
    206         237          73.79  
    319         316         73.844  
     13          75         80.144  
    199         225          84.06  
    392         392         95.682  
    252         236         97.432  
    368         341         97.499  
     60           8         101.18  
    249         278         105.33  
    345         369         107.87  
    166         146          109.8  
    124         120         112.03  
    357         363         118.08  
    351         346         120.96  
    216         356         125.39  
     46          97         129.22  
    115         144         130.32  
    123         114         132.79  
     71          40          133.2  
    163         147         134.42  
    193         155          134.6  
 78.299105 total error
--------------------------------------------------------------------------------
L1 or L2 distance not for binary descriptors
ORB + BruteForce-L1:
 500 keypoints in img1
 500 keypoints in img2
 500 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
      2          98          16     
    192         173          52     
    247         221          83     
    174         122          84     
     80          61          88     
    137         139         111     
     77           7         120     
    149         151         122     
    206         237         123     
     81          90         145     
    319         316         147     
     13          75         153     
     46          97         157     
    115         144         173     
     71          40         191     
    123         114         194     
    223         244         198     
    345         369         203     
    175         166         210     
     99         104         213     
    163         147         216     
     60           8         218     
    199         225         218     
    392         392         219     
    193         155         220     
    351         346         220     
    211         249         223     
     35          68         232     
    272         272         236     
    124         120         237     
 70.072139 total error
--------------------------------------------------------------------------------
ORB + BruteForce-Hamming:
 500 keypoints in img1
 500 keypoints in img2
 500 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
      2          98          2      
    174         122          3      
    192         173          4      
    247         221          5      
     46          97          6      
     99         104          6      
    223         244          6      
    149         151          7      
    206         237          7      
     71          40          8      
    136         138          8      
    137         139          8      
      1           3          9      
     13          75          9      
     35          68          9      
     80          61          9      
    115         144          9      
    345         369          9      
    351         346          9      
    358         355          9      
    394         419          9      
     22          92         10      
     77           7         10      
    123         114         10      
    147         129         10      
    163         147         10      
    211         249         10      
    272         272         10      
    339         371         10      
    374         340         10      
 48.577527 total error
--------------------------------------------------------------------------------
ORB + BruteForce-Hamming(2):
 500 keypoints in img1
 500 keypoints in img2
 500 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
      2          98          2      
    174         122          3      
    192         173          4      
    247         221          5      
     46          97          6      
     99         104          6      
    223         244          6      
    149         151          7      
    206         237          7      
     71          40          8      
    115         144          8      
    136         138          8      
    137         139          8      
      1           3          9      
     13          75          9      
     22          92          9      
     35          68          9      
     80          61          9      
    123         114          9      
    345         369          9      
    351         346          9      
    358         355          9      
    394         419          9      
     77           7         10      
    147         129         10      
    163         147         10      
    211         249         10      
    272         272         10      
    295         276         10      
    339         371         10      
 50.305524 total error
--------------------------------------------------------------------------------
L1 or L2 distance not for binary descriptors
BRISK + BruteForce:
 767 keypoints in img1
 735 keypoints in img2
 767 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    433         418         30.594  
    523         505             32  
    401         383         33.956  
    664         637         64.031  
    224         217         75.266  
    185         178         75.286  
    413         395          78.39  
    648         621         80.623  
    357         331         84.581  
      0           0         90.708  
    673         555         92.027  
    549         637          92.26  
     14          14         113.82  
    153         144         119.92  
    655         628         120.09  
    374         348         128.09  
    277         271          133.6  
     41          38          135.1  
    272         404         136.87  
    361         336         139.23  
    646         619         143.11  
    204         196         146.64  
    423         410         146.87  
    270         266         148.03  
    574         555         149.63  
    402         384         153.21  
    638         614         158.52  
    576         559         159.86  
    418         265         160.02  
    172         163         160.55  
 60.398485 total error
--------------------------------------------------------------------------------
L1 or L2 distance not for binary descriptors
BRISK + BruteForce-L1:
 767 keypoints in img1
 735 keypoints in img2
 767 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    523         505          32     
    401         383          49     
    664         637          66     
    433         418          68     
    413         395         129     
    374         348         136     
    224         217         137     
      0           0         138     
    185         178         140     
    673         555         151     
    549         637         152     
    648         621         162     
    646         619         192     
    277         271         204     
    357         331         214     
    204         196         224     
    423         410         234     
    361         336         253     
    272         404         255     
    270         266         266     
    153         144         292     
    206         197         313     
    172         163         316     
     14          14         318     
    402         384         325     
    638         614         325     
      3           5         327     
    574         555         331     
    643         618         337     
    576         559         338     
 49.992817 total error
--------------------------------------------------------------------------------
BRISK + BruteForce-Hamming:
 767 keypoints in img1
 735 keypoints in img2
 767 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    523         505          1      
    646         619          2      
    664         637          2      
    204         196          3      
    374         348          4      
    401         383          4      
    413         395          4      
    549         637          4      
      0           0          5      
    423         410          5      
     96          87          6      
    673         555          6      
    167         157          7      
    224         217          7      
    433         418          8      
    648         621          8      
    172         163          9      
    185         178         10      
    315         295         10      
    724         696         10      
    411         393         11      
      3           5         12      
    270         266         12      
    277         271         12      
    361         336         12      
    402         384         12      
    420         406         12      
     89          82         13      
    197         189         13      
    731         704         13      
 56.118373 total error
--------------------------------------------------------------------------------
BRISK + BruteForce-Hamming(2):
 767 keypoints in img1
 735 keypoints in img2
 767 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    523         505          1      
    646         619          2      
    664         637          2      
    204         196          3      
    374         348          4      
    401         383          4      
    413         395          4      
    549         637          4      
      0           0          5      
    423         410          5      
     96          87          6      
    167         157          6      
    673         555          6      
    224         217          7      
    433         418          8      
    648         621          8      
    172         163          9      
    185         178         10      
    315         295         10      
    411         393         10      
    724         696         10      
    402         384         11      
      3           5         12      
    270         266         12      
    277         271         12      
    361         336         12      
    420         406         12      
     89          82         13      
    197         189         13      
    377         521         13      
 56.575280 total error
--------------------------------------------------------------------------------
SIFT + BruteForce:
 538 keypoints in img1
 554 keypoints in img2
 538 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    151         158         7.6158  
    200         206          9.434  
    169         183         9.8995  
    133         138          10.05  
    122         126          11.18  
    145         152         12.124  
    135         140         12.806  
    180         192         13.304  
    128         131         13.342  
    154         165         14.107  
    189         198         14.248  
    153         162         17.117  
    138         143         17.378  
    137         142         17.578  
     14          13         17.972  
     76          77         19.209  
    181         193         20.224  
     85          91         21.237  
     20          20         21.307  
    129         133         21.794  
    110         117         21.932  
    107         114         22.226  
    440         451         22.383  
    162         172         22.583  
    164         175         23.937  
    163         174         24.678  
     81          88         24.839  
    171         184             25  
     38          37         27.129  
    288         308         27.532  
 22.399791 total error
--------------------------------------------------------------------------------
SIFT + BruteForce-L1:
 538 keypoints in img1
 554 keypoints in img2
 538 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
    151         158          38     
    200         206          51     
    133         138          59     
    145         152          59     
    135         140          64     
    169         183          64     
    122         126          67     
    180         192          73     
    154         165          75     
    128         131          78     
    137         142          89     
    138         143          92     
    189         198          93     
     76          77          95     
    153         162          95     
    129         133         105     
     14          13         109     
     81          88         117     
     85          91         117     
    181         193         125     
    162         172         130     
    164         175         141     
    440         451         145     
    182         194         147     
    184         196         147     
     20          20         150     
     82          89         153     
    171         184         153     
    288         308         154     
    163         174         155     
 21.775604 total error
--------------------------------------------------------------------------------
Hamming distance only for binary descriptors
SIFT + BruteForce-Hamming:
 538 keypoints in img1
 554 keypoints in img2
 matching failed
--------------------------------------------------------------------------------
Hamming distance only for binary descriptors
SIFT + BruteForce-Hamming(2):
 538 keypoints in img1
 554 keypoints in img2
 matching failed
--------------------------------------------------------------------------------
SURF + BruteForce:
 833 keypoints in img1
 819 keypoints in img2
 833 matches
t =
  30×3 table
    queryIdx    trainIdx    distance 
    ________    ________    _________
     21          22         0.0044549
     25          26         0.0075029
    741         752         0.0083626
    332         324         0.0084082
    371         351         0.0086561
    265         248         0.0094784
    129         123         0.0098364
    119         112          0.010511
     20          17           0.01079
    104         100          0.011485
    434         393          0.011719
     87          93          0.011821
    224         211          0.012183
     72          65          0.013086
    814         740           0.01342
    171         165          0.013746
    508         487           0.01501
    380         356           0.01558
    731         712          0.015842
     69          68          0.015907
    500         446          0.016303
    502         473          0.016388
    753         729          0.016895
     61          67          0.017205
    559         531           0.01759
    663         633          0.017897
    793         769          0.017943
    560         475          0.018021
    509         483          0.018098
    403         377          0.018622
 39.197591 total error
--------------------------------------------------------------------------------
SURF + BruteForce-L1:
 833 keypoints in img1
 819 keypoints in img2
 833 matches
t =
  30×3 table
    queryIdx    trainIdx    distance
    ________    ________    ________
     21          22         0.017737
     25          26         0.031595
    332         324         0.036884
    265         248         0.039954
    371         351         0.042173
    129         123         0.043942
    741         752         0.045758
    104         100         0.049184
    119         112          0.04946
    434         393           0.0545
     72          65         0.054785
     87          93         0.054964
    224         211         0.056004
     20          17          0.05609
    380         356          0.06616
    171         165         0.066818
     69          68         0.067284
    814         740         0.067873
    508         487         0.069274
    500         446         0.071465
    731         712         0.075041
     61          67         0.079448
    481         424         0.079876
    502         473         0.081175
    793         769         0.081626
    247         234         0.084103
    403         377         0.084347
    559         531         0.084814
    666         639         0.086527
    535         508         0.087287
 30.480832 total error
--------------------------------------------------------------------------------
Hamming distance only for binary descriptors
SURF + BruteForce-Hamming:
 833 keypoints in img1
 819 keypoints in img2
 matching failed
--------------------------------------------------------------------------------
Hamming distance only for binary descriptors
SURF + BruteForce-Hamming(2):
 833 keypoints in img1
 819 keypoints in img2
 matching failed
--------------------------------------------------------------------------------

Cumulative distances between matched keypoint for different matchers and feature detectors

if ~mexopencv.isOctave()
    t = array2table(D, 'RowNames',features, ...
        'VariableNames',regexprep(matchers,'\W',''));
    display(t)
else
    %HACK: no tables in Octave
    display(D)
end
t =
  7×4 table
                    BruteForce    BruteForceL1    BruteForceHamming    BruteForceHamming2
                    __________    ____________    _________________    __________________
    AKAZEUpright    76.348         75.51             NaN                  NaN            
    AKAZE           77.536        80.196          103.27               103.27            
    KAZE            50.047        50.708             NaN                  NaN            
    ORB             78.299        70.072          48.578               50.306            
    BRISK           60.398        49.993          56.118               56.575            
    SIFT              22.4        21.776             NaN                  NaN            
    SURF            39.198        30.481             NaN                  NaN