|
1 ################################################## |
|
2 # Simple (and fast for small filters compared to |
|
3 # ImageFiltering) image filtering |
|
4 ################################################## |
|
5 |
|
6 __precompile__() |
|
7 |
|
8 module ImFilter |
|
9 |
|
10 using OffsetArrays |
|
11 |
|
12 ########## |
|
13 # Exports |
|
14 ########## |
|
15 |
|
16 export simple_imfilter |
|
17 |
|
18 ############## |
|
19 # The routine |
|
20 ############## |
|
21 |
|
22 @inline function inside(i, aʹ, bʹ, a, b) |
|
23 return (max(a, i - aʹ) - i):(min(b, i + bʹ) - i) |
|
24 end |
|
25 |
|
26 function simple_imfilter(b::Array{Float64,2}, |
|
27 kernel::OffsetArray{Float64,2,Array{Float64,2}}) |
|
28 |
|
29 n, m = size(b) |
|
30 k, 𝓁 = size(kernel) |
|
31 o₁, o₂ = kernel.offsets |
|
32 a₁, a₂ = k + o₁, 𝓁 + o₂ |
|
33 b₁, b₂ = -1 - o₁, -1 - o₂ |
|
34 kp = kernel.parent |
|
35 |
|
36 @assert(isodd(k) && isodd(𝓁)) |
|
37 |
|
38 res = similar(b) |
|
39 |
|
40 Threads.@threads for i=1:n |
|
41 for j=1:m |
|
42 tmp = 0.0 |
|
43 it₁ = inside(i, a₁, b₁, 1, n) |
|
44 it₂ = inside(j, a₂, b₂, 1, m) |
|
45 for p=it₁ |
|
46 @simd for q=it₂ |
|
47 tmp += @inbounds(kp[p-o₁, q-o₂]*b[i+p,j+q]) |
|
48 end |
|
49 end |
|
50 res[i, j] = tmp |
|
51 end |
|
52 end |
|
53 |
|
54 return res |
|
55 end |
|
56 |
|
57 end # Module |
|
58 |