Skip to content

Commit 5a5f515

Browse files
committed
ORB tutorial
1 parent 1c02e0d commit 5a5f515

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed

docs/src/tutorials/brief.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ BRIEF is a very simple feature descriptor and does not provide scale or rotation
1616

1717
## Example
1818

19-
Let us take a look at a simple example where the BRIEF descriptor is used to match two images where one has been translated by `(10, 20)` pixels.
19+
Let us take a look at a simple example where the BRIEF descriptor is used to match two images where one has been translated by `(10, 20)` pixels. We will use the `lena_gray` image from the [TestImages](https://github.com/timholy/TestImages.jl) package for this example.
20+
2021

2122
First, let us define a warping function to transform the image.
2223

docs/src/tutorials/orb.md

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,89 @@ The vector from the corner’s center to the centroid gives the orientation of t
1010

1111
ORB tries to take sampling pairs which are uncorrelated so that each new pair will bring new information to the descriptor, thus maximizing the amount of information the descriptor carries. We also want high variance among the pairs making a feature more discriminative, since it responds differently to inputs. To do this, we consider the sampling pairs over keypoints in standard datasets and then do a greedy evaluation of all the pairs in order of distance from mean till the number of desired pairs are obtained i.e. the size of the descriptor.
1212

13-
The descriptor is built using intensity comparisons of the pairs. For each pair if the first point has greater intensity than the second, then 1 is written else 0 is written to the corresponding bit of the descriptor.
13+
The descriptor is built using intensity comparisons of the pairs. For each pair if the first point has greater intensity than the second, then 1 is written else 0 is written to the corresponding bit of the descriptor.
14+
15+
## Example
16+
17+
Let us take a look at a simple example where the ORB descriptor is used to match two images where one has been translated by `(50, 40)` pixels and then rotated by an angle of 75 degrees. We will use the `lighthouse` image from the [TestImages](https://github.com/timholy/TestImages.jl) package for this example.
18+
19+
First, lets define warping functions to transform and rotate the image.
20+
21+
```@example 1
22+
function _warp(img, transx, transy)
23+
res = zeros(eltype(img), size(img))
24+
for i in 1:size(img, 1) - transx
25+
for j in 1:size(img, 2) - transy
26+
res[i + transx, j + transy] = img[i, j]
27+
end
28+
end
29+
res = shareproperties(img, res)
30+
res
31+
end
32+
33+
function _warp(img, angle)
34+
cos_angle = cos(angle)
35+
sin_angle = sin(angle)
36+
res = zeros(eltype(img), size(img))
37+
cx = size(img, 1) / 2
38+
cy = size(img, 2) / 2
39+
for i in 1:size(res, 1)
40+
for j in 1:size(res, 2)
41+
i_rot = ceil(Int, cos_angle * (i - cx) - sin_angle * (j - cy) + cx)
42+
j_rot = ceil(Int, sin_angle * (i - cx) + cos_angle * (j - cy) + cy)
43+
if checkbounds(Bool, img, i_rot, j_rot) res[i, j] = bilinear_interpolation(img, i_rot, j_rot) end
44+
end
45+
end
46+
res = shareproperties(img, res)
47+
res
48+
end
49+
nothing # hide
50+
```
51+
52+
Now, let us create the two images we will match using ORB.
53+
54+
```@example 1
55+
56+
using ImageFeatures, TestImages, Images, ImageDraw
57+
58+
img = testimage("lighthouse")
59+
img_temp_2 = _warp(img_array_1, 5 * pi / 6)
60+
img_array_2 = _warp(img_temp_2, 50, 40)
61+
62+
nothing # hide
63+
```
64+
65+
The ORB descriptor calculates the keypoints as well as the descriptor, unlike [BRIEF](brief). To create the ORB descriptor, we first need to define the parameters by calling the [`ORB`](@ref) constructor.
66+
67+
```@example 1
68+
orb_params = ORB(num_keypoints = 1000)
69+
nothing # hide
70+
```
71+
72+
Now pass the image with the parameters to the [`create_descriptor`](@ref) function.
73+
74+
```@example 1
75+
desc_1, ret_keypoints_1 = create_descriptor(img_array_1, orb_params)
76+
desc_2, ret_keypoints_2 = create_descriptor(img_array_2, orb_params)
77+
nothing # hide
78+
```
79+
80+
The obtained descriptors can be used to find the matches between the two images using the [`match_keypoints`](@ref) function.
81+
82+
```@example 1
83+
matches = match_keypoints(ret_keypoints_1, ret_keypoints_2, desc_1, desc_2, 0.2)
84+
nothing # hide
85+
```
86+
87+
We can use the [ImageDraw.jl](https://github.com/JuliaImages/ImageDraw.jl) package to view the results.
88+
89+
```@example 1
90+
91+
grid = hcat(img_array_1, img_array_2)
92+
offset = CartesianIndex(0, 768)
93+
map(m_i -> line!(grid, m_i[1], m_i[2] + offset), matches)
94+
save("orb_example.jpg", grid); nothing # hide
95+
96+
```
97+
98+
![](orb_example.jpg)

0 commit comments

Comments
 (0)