|
1 #################################################################### |
|
2 # Predictive online PDPS for optical flow with known velocity field |
|
3 #################################################################### |
|
4 |
|
5 __precompile__() |
|
6 |
|
7 module AlgorithmFB |
|
8 |
|
9 identifier = "fb_known" |
|
10 |
|
11 using Printf |
|
12 |
|
13 using AlgTools.Util |
|
14 import AlgTools.Iterate |
|
15 using ImageTools.Gradient |
|
16 |
|
17 using ..OpticalFlow: Image, |
|
18 ImageSize, |
|
19 flow! |
|
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 ỹ = copy(y) |
|
32 y⁻ = copy(y) |
|
33 |
|
34 return x, y, Δx, Δy, ỹ, y⁻ |
|
35 end |
|
36 |
|
37 function init_iterates(xinit::Image) |
|
38 return init_rest(copy(xinit)) |
|
39 end |
|
40 |
|
41 function init_iterates(dim::ImageSize) |
|
42 return init_rest(zeros(dim...)) |
|
43 end |
|
44 |
|
45 ############ |
|
46 # Algorithm |
|
47 ############ |
|
48 |
|
49 function solve( :: Type{DisplacementT}; |
|
50 dim :: ImageSize, |
|
51 iterate = AlgTools.simple_iterate, |
|
52 params::NamedTuple) where DisplacementT |
|
53 |
|
54 ################################ |
|
55 # Extract and set up parameters |
|
56 ################################ |
|
57 |
|
58 α, ρ = params.α, params.ρ |
|
59 τ₀, τ̃₀ = params.τ₀, params.τ̃₀ |
|
60 |
|
61 R_K² = ∇₂_norm₂₂_est² |
|
62 τ̃ = τ̃₀/R_K² |
|
63 τ = τ₀ |
|
64 |
|
65 ###################### |
|
66 # Initialise iterates |
|
67 ###################### |
|
68 |
|
69 x, y, Δx, Δy, ỹ, y⁻ = init_iterates(dim) |
|
70 init_data = (params.init == :data) |
|
71 |
|
72 #################### |
|
73 # Run the algorithm |
|
74 #################### |
|
75 |
|
76 v = iterate(params) do verbose :: Function, |
|
77 b :: Image, |
|
78 v_known :: DisplacementT, |
|
79 🚫unused_b_next :: Image |
|
80 |
|
81 ################## |
|
82 # Prediction step |
|
83 ################## |
|
84 |
|
85 if init_data |
|
86 x .= b |
|
87 init_data = false |
|
88 else |
|
89 # Δx is a temporary storage variable of correct dimensions |
|
90 flow!(x, v_known, Δx) |
|
91 end |
|
92 |
|
93 ################################################################## |
|
94 # We need to do forward–backward step on min_x |x-b|^2/2 + α|∇x|. |
|
95 # The forward step is easy, the prox requires solving the predual |
|
96 # problem of a problem similar to the original. |
|
97 ################################################################## |
|
98 |
|
99 @. x = x-τ*(x-b) |
|
100 |
|
101 ############## |
|
102 # Inner FISTA |
|
103 ############## |
|
104 |
|
105 t = 0 |
|
106 # Move step length from proximal quadratic term into L1 term. |
|
107 α̃ = α*τ |
|
108 @. ỹ = y |
|
109 for i=1:params.fb_inner_iterations |
|
110 ∇₂ᵀ!(Δx, ỹ) |
|
111 @. Δx .-= x |
|
112 ∇₂!(Δy, Δx) |
|
113 @. y⁻ = y |
|
114 @. y = (ỹ - τ̃*Δy)/(1 + τ̃*ρ/α̃) |
|
115 proj_norm₂₁ball!(y, α̃) |
|
116 t⁺ = (1+√(1+4*t^2))/2 |
|
117 @. ỹ = y+((t-1)/t⁺)*(y-y⁻) |
|
118 t = t⁺ |
|
119 end |
|
120 |
|
121 ∇₂ᵀ!(Δx, y) |
|
122 @. x = x - Δx |
|
123 |
|
124 ################################ |
|
125 # Give function value if needed |
|
126 ################################ |
|
127 v = verbose() do |
|
128 ∇₂!(Δy, x) |
|
129 value = norm₂²(b-x)/2 + α*γnorm₂₁(Δy, ρ) |
|
130 value, x, [NaN, NaN], nothing |
|
131 end |
|
132 |
|
133 v |
|
134 end |
|
135 |
|
136 return x, y, v |
|
137 end |
|
138 |
|
139 end # Module |
|
140 |
|
141 |