Skip to content

Commit d11f4a0

Browse files
authored
Merge pull request #19 from JuliaImages/adddocs
BRISK tutorial
2 parents 7f1b514 + fe273d8 commit d11f4a0

File tree

5 files changed

+100
-4
lines changed

5 files changed

+100
-4
lines changed

docs/src/function_reference.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@ Below `[]` in an argument list means an optional argument.
55
## Types
66

77
```@docs
8+
Feature
9+
Features
810
Keypoint
911
Keypoints
1012
BRIEF
1113
ORB
1214
FREAK
15+
BRISK
1316
```
1417

1518
## Corners

docs/src/tutorials/brisk.md

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,97 @@ BRISK achieves rotation invariance by trying the measure orientation of the keyp
99
`g(pi, pj) = (pi - pj) . I(pj, j) -I(pj, j)pj - pi2`
1010

1111
All local gradients between long pairs and then summed and the `arctangent(gy/gx)` between `y` and `x` components of the sum is taken as the angle of the keypoint. Now, we only need to rotate the short pairs by that angle to help the descriptor become more invariant to rotation.
12-
The descriptor is built using intensity comparisons. For each short 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.
12+
The descriptor is built using intensity comparisons. For each short 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+
14+
## Example
15+
16+
Let us take a look at a simple example where the BRISK 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.
17+
18+
First, lets define warping functions to transform and rotate the image.
19+
20+
```@example 4
21+
function _warp(img, transx, transy)
22+
res = zeros(eltype(img), size(img))
23+
for i in 1:size(img, 1) - transx
24+
for j in 1:size(img, 2) - transy
25+
res[i + transx, j + transy] = img[i, j]
26+
end
27+
end
28+
res = shareproperties(img, res)
29+
res
30+
end
31+
32+
function _warp(img, angle)
33+
cos_angle = cos(angle)
34+
sin_angle = sin(angle)
35+
res = zeros(eltype(img), size(img))
36+
cx = size(img, 1) / 2
37+
cy = size(img, 2) / 2
38+
for i in 1:size(res, 1)
39+
for j in 1:size(res, 2)
40+
i_rot = ceil(Int, cos_angle * (i - cx) - sin_angle * (j - cy) + cx)
41+
j_rot = ceil(Int, sin_angle * (i - cx) + cos_angle * (j - cy) + cy)
42+
if checkbounds(Bool, img, i_rot, j_rot) res[i, j] = bilinear_interpolation(img, i_rot, j_rot) end
43+
end
44+
end
45+
res = shareproperties(img, res)
46+
res
47+
end
48+
nothing # hide
49+
```
50+
51+
Now, let us create the two images we will match using BRISK.
52+
53+
```@example 4
54+
55+
using ImageFeatures, TestImages, Images, ImageDraw
56+
57+
img = testimage("lighthouse")
58+
img_array_1 = convert(Array{Images.Gray}, img)
59+
img_temp_2 = _warp(img_array_1, 5 * pi / 6)
60+
img_array_2 = _warp(img_temp_2, 50, 40)
61+
nothing # hide
62+
```
63+
64+
To calculate the descriptors, we first need to get the keypoints. For this tutorial, we will use the FAST corners to generate keypoints (see [`fastcorners`](@ref).
65+
66+
```@example 4
67+
features_1 = Features(fastcorners(img_array_1, 12, 0.35))
68+
features_2 = Features(fastcorners(img_array_2, 12, 0.35))
69+
nothing # hide
70+
```
71+
72+
To create the BRISK descriptor, we first need to define the parameters by calling the [`BRISK`](@ref) constructor.
73+
74+
```@example 4
75+
brisk_params = BRISK()
76+
nothing # hide
77+
```
78+
79+
Now pass the image with the keypoints and the parameters to the [`create_descriptor`](@ref) function.
80+
81+
```@example 4
82+
desc_1, ret_features_1 = create_descriptor(img_array_1, features_1, brisk_params)
83+
desc_2, ret_features_2 = create_descriptor(img_array_2, features_2, brisk_params)
84+
nothing # hide
85+
```
86+
87+
The obtained descriptors can be used to find the matches between the two images using the [`match_keypoints`](@ref) function.
88+
89+
```@example 4
90+
matches = match_keypoints(Keypoints(ret_features_1), Keypoints(ret_features_2), desc_1, desc_2, 0.1)
91+
nothing # hide
92+
```
93+
94+
We can use the [ImageDraw.jl](https://github.com/JuliaImages/ImageDraw.jl) package to view the results.
95+
96+
```@example 4
97+
98+
grid = hcat(img_array_1, img_array_2)
99+
offset = CartesianIndex(0, 768)
100+
map(m_i -> line!(grid, m_i[1], m_i[2] + offset), matches)
101+
save("brisk_example.jpg", grid); nothing # hide
102+
103+
```
104+
105+
![](brisk_example.jpg)

docs/src/tutorials/freak.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ keypoints_2 = Keypoints(fastcorners(img_array_2, 12, 0.35))
6565
nothing # hide
6666
```
6767

68-
To create the BRIEF descriptor, we first need to define the parameters by calling the [`BRIEF`](@ref) constructor.
68+
To create the FREAK descriptor, we first need to define the parameters by calling the [`FREAK`](@ref) constructor.
6969

7070
```@example 3
7171
freak_params = FREAK()

src/brisk.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ function _brisk_tables(pattern_scale::Float64)
7979
pattern_table, smoothing_table
8080
end
8181

82-
function create_descriptor{T<:Gray}(img::AbstractArray{T, 2}, features::Array{Feature}, params::BRISK)
82+
function create_descriptor{T<:Gray}(img::AbstractArray{T, 2}, features::Features, params::BRISK)
8383
int_img = integral_image(img)
8484
descriptors = BitArray{1}[]
8585
ret_features = Feature[]

test/freak.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,6 @@ end
7272
desc_2, ret_keypoints_2 = create_descriptor(img_array_2, keypoints_2, freak_params)
7373
matches = match_keypoints(ret_keypoints_1, ret_keypoints_2, desc_1, desc_2, 0.1)
7474
reverse_keypoints_1 = [_reverserotate(m[1], pi / 4, (256, 256)) + CartesianIndex(10, 20) for m in matches]
75-
@fact sum(isapprox(rk[1], m[2][1], atol = 4) && isapprox(rk[2], m[2][2], atol = 4) for (rk, m) in zip(reverse_keypoints_1, matches)) + 2 --> length(matches)
75+
@fact isapprox(sum(isapprox(rk[1], m[2][1], atol = 4) && isapprox(rk[2], m[2][2], atol = 4) for (rk, m) in zip(reverse_keypoints_1, matches)), length(matches), atol = 2) --> true
7676
end
7777
end

0 commit comments

Comments
 (0)