| |
1 ######################################################## |
| |
2 # Basic TV denoising via primal–dual proximal splitting |
| |
3 ######################################################## |
| |
4 |
| |
5 __precompile__() |
| |
6 |
| |
7 module Denoise |
| |
8 |
| |
9 using AlgTools.Util |
| |
10 import AlgTools.Iterate |
| |
11 using ImageTools.Gradient |
| |
12 |
| |
13 ############## |
| |
14 # Our exports |
| |
15 ############## |
| |
16 |
| |
17 export denoise_pdps |
| |
18 |
| |
19 ############# |
| |
20 # Data types |
| |
21 ############# |
| |
22 |
| |
23 ImageSize = Tuple{Integer,Integer} |
| |
24 Image = Array{Float64,2} |
| |
25 Primal = Image |
| |
26 Dual = Array{Float64,3} |
| |
27 |
| |
28 ######################### |
| |
29 # Iterate initialisation |
| |
30 ######################### |
| |
31 |
| |
32 function init_rest(x::Primal) |
| |
33 imdim=size(x) |
| |
34 |
| |
35 y = zeros(2, imdim...) |
| |
36 Δx = copy(x) |
| |
37 Δy = copy(y) |
| |
38 x̄ = copy(x) |
| |
39 |
| |
40 return x, y, Δx, Δy, x̄ |
| |
41 end |
| |
42 |
| |
43 function init_iterates(xinit::Image, b) |
| |
44 return init_rest(copy(xinit)) |
| |
45 end |
| |
46 |
| |
47 function init_iterates(xinit::Nothing, b :: Image) |
| |
48 return init_rest(zeros(size(b)...)) |
| |
49 end |
| |
50 |
| |
51 ############ |
| |
52 # Algorithm |
| |
53 ############ |
| |
54 |
| |
55 function denoise_pdps(b :: Image; |
| |
56 xinit :: Union{Image,Nothing} = nothing, |
| |
57 iterate = AlgTools.simple_iterate, |
| |
58 params::NamedTuple) where DisplacementT |
| |
59 |
| |
60 ################################ |
| |
61 # Extract and set up parameters |
| |
62 ################################ |
| |
63 |
| |
64 α, ρ = params.α, params.ρ |
| |
65 τ₀, σ₀ = params.τ₀, params.σ₀ |
| |
66 |
| |
67 R_K = ∇₂_norm₂₂_est |
| |
68 γ = 1 |
| |
69 |
| |
70 @assert(τ₀*σ₀ < 1) |
| |
71 σ = σ₀/R_K |
| |
72 τ = τ₀/R_K |
| |
73 |
| |
74 ###################### |
| |
75 # Initialise iterates |
| |
76 ###################### |
| |
77 |
| |
78 x, y, Δx, Δy, x̄ = init_iterates(xinit, b) |
| |
79 |
| |
80 #################### |
| |
81 # Run the algorithm |
| |
82 #################### |
| |
83 |
| |
84 v = iterate(params) do verbose :: Function |
| |
85 ω = params.accel ? 1/√(1+2*γ*τ) : 1 |
| |
86 |
| |
87 ∇₂ᵀ!(Δx, y) # primal step: |
| |
88 @. x̄ = x # | save old x for over-relax |
| |
89 @. x = (x-τ*(Δx-b))/(1+τ) # | prox |
| |
90 @. x̄ = (1+ω)*x - ω*x̄ # over-relax: x̄ = 2x-x_old |
| |
91 ∇₂!(Δy, x̄) # dual step: y |
| |
92 @. y = (y + σ*Δy)/(1 + σ*ρ/α) # | |
| |
93 proj_norm₂₁ball!(y, α) # | prox |
| |
94 |
| |
95 if params.accel |
| |
96 τ, σ = τ*ω, σ/ω |
| |
97 end |
| |
98 |
| |
99 ################################ |
| |
100 # Give function value if needed |
| |
101 ################################ |
| |
102 v = verbose() do |
| |
103 ∇₂!(Δy, x) |
| |
104 value = norm₂²(b-x)/2 + params.α*γnorm₂₁(Δy, params.ρ) |
| |
105 value, x |
| |
106 end |
| |
107 |
| |
108 v |
| |
109 end |
| |
110 |
| |
111 return x, y, v |
| |
112 end |
| |
113 |
| |
114 end # Module |
| |
115 |
| |
116 |