File: akaze_matching.markdown

package info (click to toggle)
opencv 4.6.0%2Bdfsg-12
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 276,172 kB
  • sloc: cpp: 1,079,020; xml: 682,526; python: 43,885; lisp: 30,943; java: 25,642; ansic: 7,968; javascript: 5,956; objc: 2,039; sh: 1,017; cs: 601; perl: 494; makefile: 179
file content (183 lines) | stat: -rw-r--r-- 5,549 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
AKAZE local features matching {#tutorial_akaze_matching}
=============================

@tableofcontents

@prev_tutorial{tutorial_detection_of_planar_objects}
@next_tutorial{tutorial_akaze_tracking}

|    |    |
| -: | :- |
| Original author | Fedor Morozov |
| Compatibility | OpenCV >= 3.0 |

Introduction
------------

In this tutorial we will learn how to use AKAZE @cite ANB13 local features to detect and match keypoints on
two images.
We will find keypoints on a pair of images with given homography matrix, match them and count the
number of inliers (i.e. matches that fit in the given homography).

You can find expanded version of this example here:
<https://github.com/pablofdezalc/test_kaze_akaze_opencv>

Data
----

We are going to use images 1 and 3 from *Graffiti* sequence of [Oxford dataset](http://www.robots.ox.ac.uk/~vgg/data/data-aff.html).

![](images/graf.png)

Homography is given by a 3 by 3 matrix:
@code{.none}
7.6285898e-01  -2.9922929e-01   2.2567123e+02
3.3443473e-01   1.0143901e+00  -7.6999973e+01
3.4663091e-04  -1.4364524e-05   1.0000000e+00
@endcode
You can find the images (*graf1.png*, *graf3.png*) and homography (*H1to3p.xml*) in
*opencv/samples/data/*.

### Source Code

@add_toggle_cpp
-   **Downloadable code**: Click
    [here](https://raw.githubusercontent.com/opencv/opencv/4.x/samples/cpp/tutorial_code/features2D/AKAZE_match.cpp)

-   **Code at glance:**
    @include samples/cpp/tutorial_code/features2D/AKAZE_match.cpp
@end_toggle

@add_toggle_java
-   **Downloadable code**: Click
    [here](https://raw.githubusercontent.com/opencv/opencv/4.x/samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java)

-   **Code at glance:**
    @include samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java
@end_toggle

@add_toggle_python
-   **Downloadable code**: Click
    [here](https://raw.githubusercontent.com/opencv/opencv/4.x/samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py)

-   **Code at glance:**
    @include samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py
@end_toggle

### Explanation

-   **Load images and homography**

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp load
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java load
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py load
@end_toggle

We are loading grayscale images here. Homography is stored in the xml created with FileStorage.

-   **Detect keypoints and compute descriptors using AKAZE**

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp AKAZE
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java AKAZE
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py AKAZE
@end_toggle

We create AKAZE and detect and compute AKAZE keypoints and descriptors. Since we don't need the *mask*
parameter, *noArray()* is used.

-   **Use brute-force matcher to find 2-nn matches**

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp 2-nn matching
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java 2-nn matching
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py 2-nn matching
@end_toggle

We use Hamming distance, because AKAZE uses binary descriptor by default.

-   **Use 2-nn matches and ratio criterion to find correct keypoint matches**
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp ratio test filtering
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java ratio test filtering
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py ratio test filtering
@end_toggle

If the closest match distance is significantly lower than the second closest one, then the match is correct (match is not ambiguous).

-   **Check if our matches fit in the homography model**

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp homography check
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java homography check
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py homography check
@end_toggle

If the distance from first keypoint's projection to the second keypoint is less than threshold,
then it fits the homography model.

We create a new set of matches for the inliers, because it is required by the drawing function.

-   **Output results**

@add_toggle_cpp
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp draw final matches
@end_toggle

@add_toggle_java
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java draw final matches
@end_toggle

@add_toggle_python
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py draw final matches
@end_toggle

Here we save the resulting image and print some statistics.

Results
-------

### Found matches

![](images/res.png)

Depending on your OpenCV version, you should get results coherent with:

@code{.none}
 Keypoints 1:   2943
 Keypoints 2:   3511
 Matches:       447
 Inliers:       308
 Inlier Ratio: 0.689038
@endcode