| |
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 |