1
+ # ---
2
+ # cover: assets/orb.gif
3
+ # title: ORB Descriptor
4
+ # description: This demo shows ORB descriptor
5
+ # author: Anchit Navelkar, Ashwani Rathee
6
+ # date: 2021-07-12
7
+ # ---
8
+
9
+ # The `ORB` (Oriented Fast and Rotated Brief) descriptor is a somewhat similar to [BRIEF](brief.md).
10
+ # It doesn’t have an elaborate sampling pattern as [BRISK](brisk.md) or [FREAK](freak.md).
11
+
12
+ # However, there are two main differences between ORB and BRIEF:
13
+
14
+ # - ORB uses an orientation compensation mechanism, making it rotation invariant.
15
+ # - ORB learns the optimal sampling pairs, whereas BRIEF uses randomly chosen sampling pairs.
16
+
17
+ # The ORB descriptor uses the intensity centroid as a measure of orientation.
18
+ # To calculate the centroid, we first need to find the moment of a patch, which is given by
19
+ # `Mpq = x,yxpyqI(x,y)`. The centroid, or ‘centre of mass' is then given by `C=(M10M00, M01M00)`.
20
+
21
+ # The vector from the corner’s center to the centroid gives the orientation of the patch.
22
+ # Now, the patch can be rotated to some predefined canonical orientation before calculating
23
+ # the descriptor, thus achieving rotation invariance.
24
+
25
+ # ORB tries to take sampling pairs which are uncorrelated so that each new pair will bring
26
+ # new information to the descriptor, thus maximizing the amount of information the descriptor
27
+ # carries. We also want high variance among the pairs making a feature more discriminative,
28
+ # since it responds differently to inputs. To do this, we consider the sampling pairs over
29
+ # keypoints in standard datasets and then do a greedy evaluation of all the pairs in order
30
+ # of distance from mean till the number of desired pairs are obtained i.e. the size of the descriptor.
31
+
32
+ # The descriptor is built using intensity comparisons of the pairs. For each pair if the
33
+ # first point has greater intensity than the second, then 1 is written else 0 is written
34
+ # to the corresponding bit of the descriptor.
35
+
36
+ # ## Example
37
+
38
+ # Let us take a look at a simple example where the ORB descriptor is used to match two
39
+ # images where one has been translated by `(50, 40)` pixels and then rotated by an angle
40
+ # of 75 degrees. We will use the `lighthouse` image from the [TestImages](https://github.com/JuliaImages/TestImages.jl) package for this example.
41
+
42
+ # First, let us create the two images we will match using ORB.
43
+
44
+ using ImageFeatures, TestImages, Images, ImageDraw, CoordinateTransformations, Rotations
45
+
46
+ img = testimage (" cameraman" )
47
+ img1 = Gray .(img)
48
+ rot = recenter (RotMatrix (5pi / 6 ), [size (img1)... ] .÷ 2 ) # a rotation around the center
49
+ tform = rot ∘ Translation (- 50 , - 40 )
50
+ img2 = warp (img1, tform, axes (img1))
51
+
52
+ # The ORB descriptor calculates the keypoints as well as the descriptor, unlike [BRIEF](brief.md).
53
+ # To create the ORB descriptor, we first need to define the parameters by calling the [`ORB`](@ref) constructor.
54
+
55
+ orb_params = ORB (num_keypoints = 1000 )
56
+
57
+ # Now pass the image with the parameters to the [`create_descriptor`](@ref) function.
58
+
59
+ desc_1, ret_keypoints_1 = create_descriptor (img1, orb_params)
60
+ desc_2, ret_keypoints_2 = create_descriptor (img2, orb_params)
61
+
62
+ # The obtained descriptors can be used to find the matches between the two
63
+ # images using the [`match_keypoints`](@ref) function.
64
+
65
+ matches = match_keypoints (ret_keypoints_1, ret_keypoints_2, desc_1, desc_2, 0.2 )
66
+
67
+ # We can use the [ImageDraw.jl](https://github.com/JuliaImages/ImageDraw.jl) package to view the results.
68
+
69
+ grid = hcat (img1, img2)
70
+ offset = CartesianIndex (0 , size (img1, 2 ))
71
+ map (m -> draw! (grid, LineSegment (m[1 ], m[2 ] + offset)), matches)
72
+ grid
73
+
74
+ save (" assets/orb.gif" , cat (img1, img2, grid[1 : 512 ,1 : 512 ], grid[1 : 512 ,513 : 1024 ]; dims= 3 ); fps= 2 ) # src
0 commit comments