1
- # This implements the solver for Eq. (8) in the Ojala 2002 as lookup table.
2
- # Computing the encoding table using naive implementation is time-consuming,
3
- # since it's read-only, we simply cache the encoding table.
4
- const _rotation_invariant_encoding_tables = Dict ()
5
1
const SupportedEncodingTypes = Union{UInt8, UInt16}
6
- function build_rotation_invariant_encoding_table (:: Type{T} ) where T<: SupportedEncodingTypes
7
- d = _rotation_invariant_encoding_tables
8
- haskey (d, T) && return d[T]
9
- d[T] = _freeze (T, _build_inverse_table (_bitrotate_quotation_space (T)))
10
- return d[T]
2
+ const _LBP_encoding_table = Dict ()
3
+ function build_LBP_encoding_table (:: Type{T} ;
4
+ rotation:: Bool ,
5
+ uniform_degree:: Union{Nothing,Int} = nothing
6
+ ) where T<: SupportedEncodingTypes
7
+
8
+ d = _LBP_encoding_table
9
+ p = (T, rotation, uniform_degree)
10
+ haskey (d, p) && return d[p]
11
+
12
+ identity_lookup = identity .(typemin (T): typemax (T))
13
+ rot_lookup = rotation ? _build_inverse_table (_bitrotate_quotation_space (T)) : identity_lookup
14
+ uniform_lookup = ! isnothing (uniform_degree) ? _uniform_encoding_table (T, uniform_degree) : identity_lookup
15
+
16
+ # Chaining multiple encoding passes into one lookup table so that we can move as
17
+ # much computation to warm-up phase as we can.
18
+ lookup = d[p] = _freeze (T, uniform_lookup[rot_lookup.+ 1 ])
19
+ return lookup == identity_lookup ? nothing : lookup
11
20
end
12
21
13
- # Mathematically, this is the quotation space under circular bitshift of the N-bits binary
14
- # pattern space. For instance, 0b00001101 and 0b01000011 belong to the same equivalance
15
- # class.
16
- # TODO (johnnychen94): maybe support UInt32 and beyond by providing a more efficient implementation
17
22
function _bitrotate_quotation_space (:: Type{T} ) where T<: SupportedEncodingTypes
23
+ # Mathematically, this is the quotation space under circular bitshift of the N-bits binary
24
+ # pattern space. For instance, 0b00001101 and 0b01000011 belong to the same equivalance
25
+ # class.
26
+ # TODO (johnnychen94): maybe support UInt32 and beyond by providing a more efficient implementation
27
+
28
+ # This implements the solver for Eq. (8) in the Ojala 2002 as lookup table.
29
+ # Computing the encoding table using naive implementation is time-consuming,
30
+ # since it's read-only, we simply cache the encoding table.
18
31
s = Vector{T}[]
19
32
for x in typemin (T): typemax (T)
20
33
# without the following skipping mechanism actually runs faster
@@ -23,6 +36,18 @@ function _bitrotate_quotation_space(::Type{T}) where T<:SupportedEncodingTypes
23
36
end
24
37
Dict (minimum (c) => c for c in unique! (s))
25
38
end
39
+
40
+ function _uniform_encoding_table (:: Type{T} , degree:: Int ) where T<: SupportedEncodingTypes
41
+ function _count_bit_transitions (x)
42
+ count_ones (x << 7 & typemax (typeof (x))) + count_ones (x ⊻ (x >> 1 ))
43
+ end
44
+ # Eq. (9) for Ojala 2002
45
+ map (typemin (T): typemax (T)) do x
46
+ n = _count_bit_transitions (x)
47
+ ifelse (n > degree, 8 sizeof (T)+ 1 , x)
48
+ end
49
+ end
50
+
26
51
function _build_inverse_table (d:: Dict{T,<:AbstractVector{T}} ) where {T}
27
52
id = Vector {T} (undef, typemax (T)- typemin (T)+ 1 )
28
53
for k in keys (d)
0 commit comments