JuliaImages / ImageSegmentation.jl
1 6
makebt(i) = ()
2 6
@inline makebt(i, ind, rest...) = (i & 1 != 0, makebt(i>>1, rest...)...)
3

4 6
makert(ind::Int, start_ind::NTuple, mid_ind::NTuple, end_ind::NTuple) = ()
5 12
@inline makert(ind::Int, start_ind::NTuple, mid_ind::NTuple, end_ind::NTuple, b::Bool, rest...) =
6
    (b ? (mid_ind[ind]+1:end_ind[ind]) : (start_ind[ind]:mid_ind[ind]), makert(ind+1, start_ind, mid_ind, end_ind, rest...)...)
7

8 6
function region_tree!(rtree::Cell, img::AbstractArray{T,N}, homogeneous::Function) where T<:Union{Colorant, Real} where N
9

10 12
    if *(length.(axes(img))...) == 0
11 0
        return rtree
12
    end
13

14 12
    if homogeneous(img)
15 6
        m = mean(img)
16 6
        c = length(img)
17 12
        rtree.data = ((m,c))
18 12
        return rtree
19
    end
20

21 6
    split!(rtree)
22 6
    start_ind = first(CartesianIndices(axes(img))).I
23 6
    end_ind = last(CartesianIndices(axes(img))).I
24 6
    mid_ind = (start_ind.+end_ind)2
25

26 12
    for i in 0:2^N-1
27 6
        bt = makebt(i, start_ind...)
28 6
        rt = makert(1, start_ind, mid_ind, end_ind, bt...)
29 12
        region_tree!(rtree[(Int.(bt) .+ 1)...], view(img, rt...), homogeneous)
30
    end
31 12
    rtree
32
end
33

34
"""
35
    t = region_tree(img, homogeneous)
36

37
Creates a region tree from `img` by splitting it recursively until
38
all the regions are homogeneous.
39

40
    b = homogeneous(img)
41

42
Returns true if `img` is homogeneous.
43

44
# Examples
45

46
```jldoctest; setup = :(using Images, ImageSegmentation)
47
julia> img = 0.1*rand(6, 6);
48

49
julia> img[4:end, 4:end] .+= 10;
50

51
julia> function homogeneous(img)
52
           min, max = extrema(img)
53
           max - min < 0.2
54
       end
55
homogeneous (generic function with 1 method)
56

57
julia> t = region_tree(img, homogeneous);
58
```
59

60
"""
61 12
region_tree(img::AbstractArray{T,N}, homogeneous::Function) where {T<:Union{Colorant, Real},N} =
62
    region_tree!(Cell(SVector(first(CartesianIndices(axes(img))).I), SVector(length.(axes(img))), (0.,0)), img, homogeneous)
63

64 6
function fill_recursive!(seg::SegmentedImage, image_indexmap::AbstractArray{Int,N}, lc::Int, rtree::Cell)::Int where N
65

66 12
    if *(length.(axes(image_indexmap))...) == 0
67 0
        return lc
68
    end
69

70 12
    if isleaf(rtree)
71 12
        fill!(image_indexmap, lc)
72 6
        push!(seg.segment_labels, lc)
73 12
        seg.segment_means[lc] = rtree.data[1]
74 12
        seg.segment_pixel_count[lc] = rtree.data[2]
75 12
        return lc+1
76
    end
77

78 6
    start_ind = first(CartesianIndices(axes(image_indexmap))).I
79 6
    end_ind = last(CartesianIndices(axes(image_indexmap))).I
80 6
    mid_ind = (start_ind.+end_ind)2
81

82 6
    bv = MVector{N,Bool}(undef)
83 6
    rv = MVector{N,UnitRange{Int64}}(undef)
84 12
    for i in 0:2^N-1
85 6
        bt = makebt(i, start_ind...)
86 6
        rt = makert(1, start_ind, mid_ind, end_ind, bt...)
87 12
        lc = fill_recursive!(seg, view(image_indexmap, rt...), lc, rtree[(Int.(bt) .+ 1)...])
88
    end
89 12
    lc
90
end
91

92
"""
93
    seg = region_splitting(img, homogeneous)
94

95
Segments `img` by recursively splitting it until all the segments
96
are homogeneous.
97

98
    b = homogeneous(img)
99

100
Returns true if `img` is homogeneous.
101

102
# Examples
103

104
```jldoctest; setup = :(using Images, ImageSegmentation)
105
julia> img = 0.1*rand(6, 6);
106

107
julia> img[4:end, 4:end] .+= 10;
108

109
julia> function homogeneous(img)
110
           min, max = extrema(img)
111
           max - min < 0.2
112
       end
113
homogeneous (generic function with 1 method)
114

115
julia> seg = region_splitting(img, homogeneous);
116
```
117

118
"""
119 6
function region_splitting(img::AbstractArray{T,N}, homogeneous::Function) where T<:Union{Colorant, Real} where N
120 12
    rtree = region_tree(img, homogeneous)
121 12
    seg = SegmentedImage(similar(img, Int), Vector{Int}(), Dict{Int, meantype(T)}(), Dict{Int, Int}())
122 6
    lc = 1
123 12
    lc = fill_recursive!(seg, seg.image_indexmap, lc, rtree)
124 12
    seg
125
end

Read our documentation on viewing source code .

Loading