Skip to content

Commit 4362bbf

Browse files
annimesh2809timholy
authored andcommitted
Performance fix for hough_transform_standard (#34)
1 parent 13e34f3 commit 4362bbf

File tree

2 files changed

+42
-26
lines changed

2 files changed

+42
-26
lines changed

src/houghtransform.jl

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,100 @@
11
using Images
2+
23
"""
34
```
45
lines = hough_transform_standard(image, ρ, θ, threshold, linesMax)
56
```
67
7-
Returns an vector of tuples corresponding to the tuples of (r,t) where r and t are parameters for normal form of line:
8-
x*cos(t) + y*sin(t) = r
8+
Returns a vector of tuples corresponding to the tuples of (r,t)
9+
where r and t are parameters for normal form of line:
10+
`x \* cos(t) + y \* sin(t) = r`
911
10-
r = length of perpendicular from (1,1) to the line
11-
t = angle between perpendicular from (1,1) to the line and x-axis
12+
- `r` = length of perpendicular from (1,1) to the line
13+
- `t` = angle between perpendicular from (1,1) to the line and x-axis
1214
1315
The lines are generated by applying hough transform on the image.
1416
1517
Parameters:
16-
image = Image to be transformed (eltype should be `Bool`)
17-
ρ = Discrete step size for perpendicular length of line
18-
θ = List of angles for which the transform is computed
19-
threshold = No of points to pass through line for considering it valid
20-
linesMax = Maximum no of lines to return
18+
- `image` = Image to be transformed (eltype should be `Bool`)
19+
- `ρ` = Discrete step size for perpendicular length of line
20+
- `θ` = List of angles for which the transform is computed
21+
- `threshold` = Accumulator threshold for line detection
22+
- `linesMax` = Maximum no of lines to return
23+
24+
# Example
25+
```julia
26+
julia> img = load("line.jpg");
27+
28+
julia> img_edges = canny(img, (Percentile(0.99), Percentile(0.97)), 1);
2129
30+
julia> lines = hough_transform_standard(img_edges, 1, linspace(0,π,30), 40, 5)
31+
5-element Array{Tuple{Float64,Float64},1}:
32+
(45.0,1.73329)
33+
(1.0,1.73329)
34+
(32.0,1.73329)
35+
(209.0,0.649985)
36+
(-9.0,2.49161)
37+
```
2238
"""
2339

2440
function hough_transform_standard{T<:Union{Bool,Gray{Bool}}}(
2541
img::AbstractArray{T,2},
26-
ρ::Number, θ::Range,
42+
ρ::Real, θ::Range,
2743
threshold::Integer, linesMax::Integer)
2844

2945

3046
#function to compute local maximum lines with values > threshold and return a vector containing them
31-
function findlocalmaxima(accumulator_matrix::Array{Integer,2},threshold::Integer)
32-
validLines = Vector{CartesianIndex}(0)
47+
function findlocalmaxima!{T<:Integer}(validLines::AbstractVector{CartesianIndex{2}}, accumulator_matrix::Array{Int,2}, threshold::T)
3348
for val in CartesianRange(size(accumulator_matrix))
34-
if accumulator_matrix[val] > threshold &&
35-
accumulator_matrix[val] > accumulator_matrix[val[1],val[2] - 1] &&
49+
if accumulator_matrix[val] > threshold &&
50+
accumulator_matrix[val] > accumulator_matrix[val[1],val[2] - 1] &&
3651
accumulator_matrix[val] >= accumulator_matrix[val[1],val[2] + 1] &&
37-
accumulator_matrix[val] > accumulator_matrix[val[1] - 1,val[2]] &&
52+
accumulator_matrix[val] > accumulator_matrix[val[1] - 1,val[2]] &&
3853
accumulator_matrix[val] >= accumulator_matrix[val[1] + 1,val[2]]
3954
push!(validLines,val)
4055
end
4156
end
42-
validLines
4357
end
4458

4559
ρ > 0 || error("Discrete step size must be positive")
4660

47-
height, width = size(img)
61+
indsy, indsx = indices(img)
4862
ρinv = 1 / ρ
4963
numangle = length(θ)
50-
numrho = round(Integer,(2(width + height) + 1)*ρinv)
64+
numrho = round(Int,(2(length(indsx) + length(indsy)) + 1)*ρinv)
5165

52-
accumulator_matrix = zeros(Integer, numangle + 2, numrho + 2)
66+
accumulator_matrix = zeros(Int, numangle + 2, numrho + 2)
5367

5468
#Pre-Computed sines and cosines in tables
5569
sinθ, cosθ = sin.(θ).*ρinv, cos.(θ).*ρinv
5670

5771
#Hough Transform implementation
58-
constadd = round(Integer,(numrho -1)/2)
72+
constadd = round(Int,(numrho -1)/2)
5973
for pix in CartesianRange(size(img))
6074
if img[pix]
6175
for i in 1:numangle
62-
dist = round(Integer, pix[1] * sinθ[i] + pix[2] * cosθ[i])
76+
dist = round(Int, pix[1] * sinθ[i] + pix[2] * cosθ[i])
6377
dist += constadd
6478
accumulator_matrix[i + 1, dist + 1] += 1
6579
end
6680
end
6781
end
6882

6983
#Finding local maximum lines
70-
validLines = findlocalmaxima(accumulator_matrix, threshold)
84+
validLines = Vector{CartesianIndex{2}}(0)
85+
findlocalmaxima!(validLines, accumulator_matrix, threshold)
7186

7287
#Sorting by value in accumulator_matrix
73-
sort!(validLines, by = (x)->accumulator_matrix[x], rev = true)
88+
@noinline sort_by_votes(validLines, accumulator_matrix) = sort!(validLines, lt = (a,b)-> accumulator_matrix[a]>accumulator_matrix[b])
89+
sort_by_votes(validLines, accumulator_matrix)
7490

7591
linesMax = min(linesMax, length(validLines))
7692

77-
lines = Vector{Tuple{Number,Number}}(0)
93+
lines = Vector{Tuple{Float64,Float64}}(0)
7894

7995
#Getting lines with Maximum value in accumulator_matrix && size(lines) < linesMax
8096
for l in 1:linesMax
81-
lrho = ((validLines[l][2]-1) - (numrho - 1)*0.5)*ρ
97+
lrho = ((validLines[l][2]-1) - (numrho-1)*0.5)*ρ
8298
langle = θ[validLines[l][1]-1]
8399
push!(lines,(lrho,langle))
84100
end

test/houghtransform.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ using ImageFeatures
5050
end
5151
end
5252

53-
img_edges = canny(img, 1, 0.2, 0.1, percentile=false)
53+
img_edges = canny(img, (0.2, 0.1) ,1)
5454
dx, dy=imgradients(img, KernelFactors.ando3)
5555
img_phase = phase(dx, dy)
5656

0 commit comments

Comments
 (0)