|
1 #################################################################### |
|
2 # Predictive online PDPS for optical flow with known velocity field |
|
3 #################################################################### |
|
4 |
|
5 __precompile__() |
|
6 |
|
7 module AlgorithmProximal |
|
8 |
|
9 identifier = "pdps_known_proximal" |
|
10 |
|
11 using Printf |
|
12 |
|
13 using AlgTools.Util |
|
14 import AlgTools.Iterate |
|
15 using ImageTools.Gradient |
|
16 |
|
17 using ..OpticalFlow: ImageSize, |
|
18 Image, |
|
19 pdflow! |
|
20 |
|
21 ######################### |
|
22 # Iterate initialisation |
|
23 ######################### |
|
24 |
|
25 function init_rest(x::Image) |
|
26 imdim=size(x) |
|
27 |
|
28 y = zeros(2, imdim...) |
|
29 Δx = copy(x) |
|
30 Δy = copy(y) |
|
31 x̄ = copy(x) |
|
32 |
|
33 return x, y, Δx, Δy, x̄ |
|
34 end |
|
35 |
|
36 function init_iterates(xinit::Image) |
|
37 return init_rest(copy(xinit)) |
|
38 end |
|
39 |
|
40 function init_iterates(dim::ImageSize) |
|
41 return init_rest(zeros(dim...)) |
|
42 end |
|
43 |
|
44 ############ |
|
45 # Algorithm |
|
46 ############ |
|
47 |
|
48 function step_lengths(params, γ, R_K²) |
|
49 ρ̃₀, τ₀, σ₀, σ̃₀ = params.ρ̃₀, params.τ₀, params.σ₀, params.σ̃₀ |
|
50 δ = params.δ |
|
51 ρ = isdefined(params, :phantom_ρ) ? params.phantom_ρ : params.ρ |
|
52 Λ = params.Λ |
|
53 Θ = params.dual_flow ? Λ : 1 |
|
54 |
|
55 τ = τ₀/γ |
|
56 @assert(1+γ*τ ≥ Λ) |
|
57 σ = σ₀*min(1/(τ*R_K²), 1/max(0, τ*R_K²/((1+γ*τ-Λ)*(1-δ))-ρ)) |
|
58 q = δ*(1+σ*ρ)/Θ |
|
59 if 1 ≥ q |
|
60 σ̃ = σ̃₀*σ/q |
|
61 #ρ̃ = ρ̃₀*max(0, ((Θ*σ)/(2*δ*σ̃^2*(1+σ*ρ))+1/(2σ)-1/σ̃)) |
|
62 ρ̃ = max(0, (1-q)/(2*σ)) |
|
63 else |
|
64 σ̃ = σ̃₀*σ/(q*(1-√(1-1/q))) |
|
65 ρ̃ = 0 |
|
66 end |
|
67 |
|
68 println("Step length parameters: τ=$(τ), σ=$(σ), σ̃=$(σ̃), ρ̃=$(ρ̃)") |
|
69 |
|
70 return τ, σ, σ̃, ρ̃ |
|
71 end |
|
72 |
|
73 function solve( :: Type{DisplacementT}; |
|
74 dim :: ImageSize, |
|
75 iterate = AlgTools.simple_iterate, |
|
76 params::NamedTuple) where DisplacementT |
|
77 |
|
78 ################################ |
|
79 # Extract and set up parameters |
|
80 ################################ |
|
81 |
|
82 α, ρ = params.α, params.ρ |
|
83 R_K² = ∇₂_norm₂₂_est² |
|
84 γ = 1 |
|
85 τ, σ, σ̃, ρ̃ = step_lengths(params, γ, R_K²) |
|
86 |
|
87 ###################### |
|
88 # Initialise iterates |
|
89 ###################### |
|
90 |
|
91 x, y, Δx, Δy, x̄ = init_iterates(dim) |
|
92 init_data = (params.init == :data) |
|
93 |
|
94 #################### |
|
95 # Run the algorithm |
|
96 #################### |
|
97 |
|
98 v = iterate(params) do verbose :: Function, |
|
99 b :: Image, |
|
100 v_known :: DisplacementT, |
|
101 🚫unused_b_next :: Image |
|
102 |
|
103 ################## |
|
104 # Prediction step |
|
105 ################## |
|
106 if init_data |
|
107 x .= b |
|
108 init_data = false |
|
109 end |
|
110 |
|
111 pdflow!(x, Δx, y, Δy, v_known, params.dual_flow) |
|
112 |
|
113 # Proximal step |
|
114 ∇₂!(Δy, x) |
|
115 @. y = (y + σ̃*Δy)/(1 + σ̃*(ρ̃+ρ/α)) |
|
116 proj_norm₂₁ball!(y, α) |
|
117 |
|
118 |
|
119 ############ |
|
120 # PDPS step |
|
121 ############ |
|
122 |
|
123 ∇₂ᵀ!(Δx, y) # primal step: |
|
124 @. x̄ = x # | save old x for over-relax |
|
125 @. x = (x-τ*(Δx-b))/(1+τ) # | prox |
|
126 @. x̄ = 2x - x̄ # over-relax |
|
127 ∇₂!(Δy, x̄) # dual step: y |
|
128 @. y = (y + σ*Δy)/(1 + σ*ρ/α) # | |
|
129 proj_norm₂₁ball!(y, α) # | prox |
|
130 |
|
131 ################################ |
|
132 # Give function value if needed |
|
133 ################################ |
|
134 v = verbose() do |
|
135 ∇₂!(Δy, x) |
|
136 value = norm₂²(b-x)/2 + params.α*γnorm₂₁(Δy, params.ρ) |
|
137 value, x, [NaN, NaN], nothing |
|
138 end |
|
139 |
|
140 v |
|
141 end |
|
142 |
|
143 return x, y, v |
|
144 end |
|
145 |
|
146 end # Module |
|
147 |
|
148 |