| 1 #################################################################### |
|
| 2 # Predictive online PDPS for optical flow with known velocity field |
|
| 3 #################################################################### |
|
| 4 |
|
| 5 __precompile__() |
|
| 6 |
|
| 7 module AlgorithmGreedy |
|
| 8 |
|
| 9 identifier = "pdps_known_greedy" |
|
| 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 Greedy |
|
| 21 |
|
| 22 ######################### |
|
| 23 # Iterate initialisation |
|
| 24 ######################### |
|
| 25 |
|
| 26 function init_rest(x::Image) |
|
| 27 imdim=size(x) |
|
| 28 |
|
| 29 y = zeros(2, imdim...) |
|
| 30 Δx = copy(x) |
|
| 31 Δy = copy(y) |
|
| 32 x̄ = copy(x) |
|
| 33 |
|
| 34 return x, y, Δx, Δy, x̄ |
|
| 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 R_K² = ∇₂_norm₂₂_est² |
|
| 60 γ = 1.0 |
|
| 61 Λ = params.Λ |
|
| 62 τ₀, σ₀ = params.τ₀, params.σ₀ |
|
| 63 |
|
| 64 τ = τ₀/γ |
|
| 65 @assert(1+γ*τ ≥ Λ) |
|
| 66 σ = σ₀*1/(τ*R_K²) |
|
| 67 |
|
| 68 println("Step length parameters: τ=$(τ), σ=$(σ)") |
|
| 69 |
|
| 70 ###################### |
|
| 71 # Initialise iterates |
|
| 72 ###################### |
|
| 73 |
|
| 74 x, y, Δx, Δy, x̄ = init_iterates(dim) |
|
| 75 init_data = (params.init == :data) |
|
| 76 |
|
| 77 #################### |
|
| 78 # Run the algorithm |
|
| 79 #################### |
|
| 80 |
|
| 81 v = iterate(params) do verbose :: Function, |
|
| 82 b :: Image, |
|
| 83 v_known :: DisplacementT, |
|
| 84 🚫unused_b_next :: Image |
|
| 85 |
|
| 86 ################## |
|
| 87 # Prediction step |
|
| 88 ################## |
|
| 89 if init_data |
|
| 90 x .= b |
|
| 91 init_data = false |
|
| 92 end |
|
| 93 |
|
| 94 pdflow!(x, Δx, y, Δy, v_known, Greedy()) |
|
| 95 |
|
| 96 ############ |
|
| 97 # PDPS step |
|
| 98 ############ |
|
| 99 |
|
| 100 ∇₂ᵀ!(Δx, y) # primal step: |
|
| 101 @. x̄ = x # | save old x for over-relax |
|
| 102 @. x = (x-τ*(Δx-b))/(1+τ) # | prox |
|
| 103 @. x̄ = 2x - x̄ # over-relax |
|
| 104 ∇₂!(Δy, x̄) # dual step: y |
|
| 105 @. y = (y + σ*Δy)/(1 + σ*ρ/α) # | |
|
| 106 proj_norm₂₁ball!(y, α) # | prox |
|
| 107 |
|
| 108 ################################ |
|
| 109 # Give function value if needed |
|
| 110 ################################ |
|
| 111 v = verbose() do |
|
| 112 ∇₂!(Δy, x) |
|
| 113 value = norm₂²(b-x)/2 + params.α*γnorm₂₁(Δy, params.ρ) |
|
| 114 value, x, [NaN, NaN], nothing |
|
| 115 end |
|
| 116 |
|
| 117 v |
|
| 118 end |
|
| 119 |
|
| 120 return x, y, v |
|
| 121 end |
|
| 122 |
|
| 123 end # Module |
|
| 124 |
|
| 125 |
|