Skip to content

Commit 1ef2c49

Browse files
committed
Update the documentation
Main changes: - Change to Documenter's native HTML output - Update to the new ImageDraw API - Exploit ImageTransformations and CoordinateTransformations in demos - Update path specification in links (perhaps Documenter's rules changed?) - Fix package installation and deployment rules
1 parent b1c8086 commit 1ef2c49

File tree

11 files changed

+130
-250
lines changed

11 files changed

+130
-250
lines changed

.travis.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ notifications:
1010
script:
1111
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
1212
- julia -e 'Pkg.clone(pwd()); Pkg.build("ImageFeatures")'
13-
- julia -e 'Pkg.test("ImageFeatures", coverage=false)'
13+
# used in tests and Documentation (just install once)
14+
- julia -e 'Pkg.add("TestImages")'
15+
- julia -e 'if is_linux() Pkg.add("ImageMagick") end'
16+
- julia -e 'Pkg.test("ImageFeatures", coverage=true)'
1417
after_success:
15-
# - if [ $TRAVIS_OS_NAME = "linux" ]; then
16-
# julia -e 'cd(Pkg.dir("ImageFeatures")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())';
17-
# fi
18+
- - julia -e 'cd(Pkg.dir("ImageFeatures")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
1819
- julia -e 'Pkg.add("Documenter")'
19-
- julia -e 'Pkg.clone("https://github.com/JuliaImages/ImageDraw.jl")' # Needed for Docs
20+
- julia -e 'Pkg.add("ImageDraw.jl")' # Needed for Docs
2021
- julia -e 'cd(Pkg.dir("ImageFeatures")); include(joinpath("docs", "make.jl"))'

docs/make.jl

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
using Documenter, ImageFeatures
22

3-
makedocs()
3+
makedocs(format = :html,
4+
sitename = "ImageFeatures",
5+
pages = ["Home" => "index.md",
6+
"Tutorials" => [
7+
"BRIEF" => "tutorials/brief.md",
8+
"ORB" => "tutorials/orb.md",
9+
"BRISK" => "tutorials/brisk.md",
10+
"FREAK" => "tutorials/freak.md",
11+
"Gray level co-occurence matrix" => "tutorials/glcm.md",
12+
"Local binary patterns" => "tutorials/lbp.md",
13+
],
14+
"Function reference" => "function_reference.md",
15+
],
16+
)
417

5-
deploydocs(deps=Deps.pip("mkdocs", "mkdocs-material"),
6-
repo="github.com/JuliaImages/ImageFeatures.jl.git",
7-
osname="linux"
8-
)
18+
deploydocs(repo = "github.com/JuliaImages/ImageFeatures.jl.git",
19+
julia = "0.6",
20+
target = "build",
21+
deps = nothing,
22+
make = nothing,
23+
)

docs/mkdocs.yml

Lines changed: 0 additions & 48 deletions
This file was deleted.

docs/src/index.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,25 @@
22

33
## Introduction
44

5-
The ideal keypoint detector finds salient image regions such that they are repeatably detected despite change of viewpoint and more generally it is robust to all possible image transformations. Similarly, the ideal keypoint descriptor captures the most important and distinctive information content enclosed in the detected salient regions, such that the same structure can be recognized if encountered.
5+
[ImageFeatures](https://github.com/JuliaImages/ImageFeatures.jl) is a
6+
package for identifying and characterizing "keypoints" (salient
7+
features) in images. Collections of keypoints can be matched between
8+
two images. Consequently, keypoints can be useful in many
9+
applications, such as object localization and image registration.
10+
11+
The ideal keypoint detector finds salient image regions such that they
12+
are repeatably detected despite change of viewpoint and more generally
13+
it is robust to all possible image transformations. Similarly, the
14+
ideal keypoint descriptor captures the most important and distinctive
15+
information content enclosed in the detected salient regions, such
16+
that the same structure can be recognized if encountered.
617

718
## Installation
819

9-
Installing the package is extremely easy with julia's package manager -
20+
Installing the package is extremely easy with julia's package manager -
1021

1122
```julia
12-
Pkg.clone("https://github.com/JuliaImages/ImageFeatures.jl")
23+
Pkg.add("ImageFeatures.jl")
1324
```
1425

15-
ImageFeatures.jl requires [Images.jl](https://github.com/timholy/Images.jl).
16-
26+
ImageFeatures.jl requires [Images.jl](https://github.com/JuliaImages/Images.jl).

docs/src/tutorials/brief.md

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,46 +12,30 @@ In ImageFeatures.jl we have five methods to determine the vectors `X` and `Y` :
1212

1313
As with all the binary descriptors, BRIEF’s distance measure is the number of different bits between two binary strings which can also be computed as the sum of the XOR operation between the strings.
1414

15-
BRIEF is a very simple feature descriptor and does not provide scale or rotation invariance (only translation invariance). To achieve those, see [ORB](orb), [BRISK](brisk) and [FREAK](freak).
15+
BRIEF is a very simple feature descriptor and does not provide scale or rotation invariance (only translation invariance). To achieve those, see [ORB](orb.md), [BRISK](brisk.md) and [FREAK](freak.md).
1616

17-
## Example
17+
## Example
1818

1919
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 `(100, 200)` pixels. We will use the `lena_gray` image from the [TestImages](https://github.com/timholy/TestImages.jl) package for this example.
2020

2121

22-
First, let us define a warping function to transform the image.
23-
24-
```@example 1
25-
function _warp(img, transx, transy)
26-
res = zeros(eltype(img), size(img))
27-
for i in 1:size(img, 1) - transx
28-
for j in 1:size(img, 2) - transy
29-
res[i + transx, j + transy] = img[i, j]
30-
end
31-
end
32-
res = shareproperties(img, res)
33-
res
34-
end
35-
nothing # hide
36-
```
37-
3822
Now, let us create the two images we will match using BRIEF.
3923

4024
```@example 1
25+
using ImageFeatures, TestImages, Images, ImageDraw, CoordinateTransformations
4126
42-
using ImageFeatures, TestImages, Images, ImageDraw
43-
44-
img = testimage("lena_gray_512")
45-
img_array_1 = convert(Array{Images.Gray}, img)
46-
img_array_2 = _warp(img_array_1, 100, 200)
27+
img = testimage("lena_gray_512");
28+
img1 = Gray.(img);
29+
trans = Translation(-100, -200)
30+
img2 = warp(img1, trans, indices(img1));
4731
nothing # hide
4832
```
4933

5034
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).
5135

5236
```@example 1
53-
keypoints_1 = Keypoints(fastcorners(img_array_1, 12, 0.4))
54-
keypoints_2 = Keypoints(fastcorners(img_array_2, 12, 0.4))
37+
keypoints_1 = Keypoints(fastcorners(img1, 12, 0.4))
38+
keypoints_2 = Keypoints(fastcorners(img2, 12, 0.4))
5539
nothing # hide
5640
```
5741

@@ -65,8 +49,8 @@ nothing # hide
6549
Now pass the image with the keypoints and the parameters to the [`create_descriptor`](@ref) function.
6650

6751
```@example 1
68-
desc_1, ret_keypoints_1 = create_descriptor(img_array_1, keypoints_1, brief_params)
69-
desc_2, ret_keypoints_2 = create_descriptor(img_array_2, keypoints_2, brief_params)
52+
desc_1, ret_keypoints_1 = create_descriptor(img1, keypoints_1, brief_params);
53+
desc_2, ret_keypoints_2 = create_descriptor(img2, keypoints_2, brief_params);
7054
nothing # hide
7155
```
7256

@@ -81,11 +65,11 @@ We can use the [ImageDraw.jl](https://github.com/JuliaImages/ImageDraw.jl) packa
8165

8266
```@example 1
8367
84-
grid = hcat(img_array_1, img_array_2)
85-
offset = CartesianIndex(0, 512)
86-
map(m_i -> line!(grid, m_i[1], m_i[2] + offset), matches)
87-
save("brief_example.jpg", grid); nothing # hide
88-
68+
grid = hcat(img1, img2)
69+
offset = CartesianIndex(0, size(img1, 2))
70+
map(m -> draw!(grid, LineSegment(m[1], m[2] + offset)), matches)
71+
save("brief_example.jpg", grid) # hide
72+
nothing # hide
8973
```
9074

9175
![](brief_example.jpg)

docs/src/tutorials/brisk.md

Lines changed: 18 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,42 @@
1-
The *BRISK* descriptor has a predefined sampling pattern as compared to [BRIEF](brief) or [ORB](orb). Pixels are sampled over concentric rings. For each sampling point, a small patch is considered around it. Before starting the algorithm, the patch is smoothed using gaussian smoothing.
1+
The *BRISK* descriptor has a predefined sampling pattern as compared to [BRIEF](brief.md) or [ORB](orb.md). Pixels are sampled over concentric rings. For each sampling point, a small patch is considered around it. Before starting the algorithm, the patch is smoothed using gaussian smoothing.
22

3-
![BRISK Sampling Pattern](/img/brisk_pattern.png = 50x50)
3+
![BRISK Sampling Pattern](../img/brisk_pattern.png)
44

55
Two types of pairs are used for sampling, short and long pairs. Short pairs are those where the distance is below a set threshold distmax while the long pairs have distance above distmin. Long pairs are used for orientation and short pairs are used for calculating the descriptor by comparing intensities.
66

77
BRISK achieves rotation invariance by trying the measure orientation of the keypoint and rotating the sampling pattern by that orientation. This is done by first calculating the local gradient `g(pi,pj)` between sampling pair `(pi,pj)` where `I(pj, pj)` is the smoothed intensity after applying gaussian smoothing.
88

99
`g(pi, pj) = (pi - pj) . I(pj, j) -I(pj, j)pj - pi2`
1010

11-
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.
11+
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.
1212
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.
1313

14-
## Example
14+
## Example
1515

1616
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.
1717

18-
First, lets define warping functions to transform and rotate the image.
18+
First, let us create the two images we will match using BRISK.
1919

2020
```@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.
5221
53-
```@example 4
54-
55-
using ImageFeatures, TestImages, Images, ImageDraw
22+
using ImageFeatures, TestImages, Images, ImageDraw, CoordinateTransformations
5623
5724
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)
25+
img1 = Gray.(img)
26+
rot = recenter(RotMatrix(5pi/6), [size(img1)...] .÷ 2) # a rotation around the center
27+
tform = rot ∘ Translation(-50, -40)
28+
img2 = warp(img1, tform, indices(img1))
6129
nothing # hide
6230
```
6331

6432
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).
6533

6634
```@example 4
67-
features_1 = Features(fastcorners(img_array_1, 12, 0.35))
68-
features_2 = Features(fastcorners(img_array_2, 12, 0.35))
35+
features_1 = Features(fastcorners(img1, 12, 0.35))
36+
features_2 = Features(fastcorners(img2, 12, 0.35))
6937
nothing # hide
7038
```
71-
39+
7240
To create the BRISK descriptor, we first need to define the parameters by calling the [`BRISK`](@ref) constructor.
7341

7442
```@example 4
@@ -79,8 +47,8 @@ nothing # hide
7947
Now pass the image with the keypoints and the parameters to the [`create_descriptor`](@ref) function.
8048

8149
```@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)
50+
desc_1, ret_features_1 = create_descriptor(img1, features_1, brisk_params)
51+
desc_2, ret_features_2 = create_descriptor(img2, features_2, brisk_params)
8452
nothing # hide
8553
```
8654

@@ -95,9 +63,9 @@ We can use the [ImageDraw.jl](https://github.com/JuliaImages/ImageDraw.jl) packa
9563

9664
```@example 4
9765
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)
66+
grid = hcat(img1, img2)
67+
offset = CartesianIndex(0, size(img1, 2))
68+
map(m -> draw!(grid, LineSegment(m[1], m[2] + offset)), matches)
10169
save("brisk_example.jpg", grid); nothing # hide
10270
10371
```

0 commit comments

Comments
 (0)