From cf4aa0e632071627f798af139bbe2b843d0ed1a2 Mon Sep 17 00:00:00 2001 From: Stephan Hilb <stephan@ecshi.net> Date: Sun, 30 Jan 2022 16:38:02 +0100 Subject: [PATCH] refactor optflow examples --- scripts/run_experiments.jl | 98 +++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/scripts/run_experiments.jl b/scripts/run_experiments.jl index 477c081..f2e80e9 100644 --- a/scripts/run_experiments.jl +++ b/scripts/run_experiments.jl @@ -1051,6 +1051,7 @@ function optflow(ctx) size(ctx.params.imgf0) == size(ctx.params.imgf1) || throw(ArgumentError("non-matching image sizes")) + project_image! = project_l2_lagrange! tol_newton = 1e-5 # cauchy criterion for inner newton loop m = 2 # range dim of vector field @@ -1073,14 +1074,15 @@ function optflow(ctx) ctx.params.gamma1, ctx.params.gamma2) function warp!() + println("warp and reproject ...") # warp image into imgfw / fw imgfw = warp_backwards(imgf1, sample(st.u)) - project_l2_pixel!(fw, imgfw) + project_image!(fw, imgfw) # recompute optflow operator T based on u0 and fw - # TODO: investigate what julia does for singular matrices here function tdata_optflow(x; u0_deriv, nablafw) - res = nablafw / (I + u0_deriv') + #res = nablafw / (I + u0_deriv') + res = nablafw all(isfinite, res) || throw(DivideError("singular optflow matrix")) return res end @@ -1088,15 +1090,17 @@ function optflow(ctx) u0_deriv = nabla(st.u), nablafw = nabla(fw)) # recompute optflow data g + # note that it is important here that the space of g is general enough + # to avoid any information loss that could screw up image warping g_optflow(x; u0, f0, fw, tdata) = - #-(fw - f0) st.T(tdata, u0) - (fw - f0) interpolate!(st.g, g_optflow; u0 = st.u, f0, fw, st.tdata) end function interpolate_image_data!() - project_l2_pixel!(f0, imgf0) - project_l2_pixel!(f1, imgf1) + println("interpolate image data ...") + project_image!(f0, imgf0) + project_image!(f1, imgf1) end @@ -1104,55 +1108,59 @@ function optflow(ctx) output(st, joinpath(ctx.outdir, "output_$(lpad(i, 5, '0')).vtu"), st.g, st.u, st.p1, st.p2, st.est, f0, f1, fw) - i = 0 pvd = paraview_collection(joinpath(ctx.outdir, "output.pvd")) do pvd - pvd[i] = save_step(i) + interpolate_image_data!() + warp!() # in the first step just to fill st.g + pvd[0] = save_step(0) - #norm_g_old = norm_l2(st.g) - - for j in 1:5 - println("interpolate image data ...") - interpolate_image_data!() - println("warp ...") - warp!() # in the first step just to fill st.g - i += 1 + i = 0 + k = 0 + while true + step!(st) + k += 1 + #estimate_pd!(st) - # interior newton loop - norm_step_ = Inf - k = 0 - while norm_step_ > tol_newton && k < 20 - k += 1 - println() - step!(st) - #estimate_pd!(st) + norm_step_ = norm_step(st) / sqrt(mesh_area) + println("norm_step = $norm_step_") - norm_step_ = norm_step(st) / sqrt(mesh_area) - println("norm_step = $norm_step_") + # residual is basically unusable: takes long to compute and + # oscillates + #norm_residual_ = norm_residual(st) / sqrt(mesh_area) + #println("norm_residual = $norm_residual_") - # residual is basically unusable: takes long to compute and - # oscillates - #norm_residual_ = norm_residual(st) / sqrt(mesh_area) - #println("norm_residual = $norm_residual_") + #display(plot(colorflow(to_img(sample(st.u)); ctx.params.maxflow))) - #display(plot(colorflow(to_img(sample(st.u)); ctx.params.maxflow))) - end + # interior newton stop criterion + norm_step_ > tol_newton && k < 10 && continue + k = 0 display(plot(colorflow(to_img(sample(st.u)); ctx.params.maxflow))) - estimate_res!(st) + i += 1 pvd[i] = save_step(i) - println("refine ...") - marked_cells = mark(st; theta = 0.5) - #marked_cells = Set(axes(mesh.cells, 2)) - mesh, fs = refine(mesh, marked_cells; - st.est, st.g, st.u, st.p1, st.p2, st.du, st.dp1, st.dp2, - st.tdata, f0, f1, fw) - st = L1L2TVState(mesh, st.d, st.m, st.T, fs.tdata, st.S, - st.alpha1, st.alpha2, st.beta, st.lambda, st.gamma1, st.gamma2, - fs.est, fs.g, fs.u, fs.p1, fs.p2, fs.du, fs.dp1, fs.dp2) - f0, f1, fw = (fs.f0, fs.f1, fs.fw) + # warping stop criterion + warp!() + if i > 10 + break + end + + # refinement stop criterion + if false + println("refine ...") + estimate_res!(st) + marked_cells = mark(st; theta = 0.5) + #marked_cells = Set(axes(mesh.cells, 2)) + mesh, fs = refine(mesh, marked_cells; + st.est, st.g, st.u, st.p1, st.p2, st.du, st.dp1, st.dp2, + st.tdata, f0, f1, fw) + st = L1L2TVState(mesh, st.d, st.m, st.T, fs.tdata, st.S, + st.alpha1, st.alpha2, st.beta, st.lambda, st.gamma1, st.gamma2, + fs.est, fs.g, fs.u, fs.p1, fs.p2, fs.du, fs.dp1, fs.dp2) + f0, f1, fw = (fs.f0, fs.f1, fs.fw) + interpolate_image_data!() + end end end #display(plot(colorflow(to_img(sample(st.u)); ctx.params.maxflow))) @@ -1167,9 +1175,11 @@ end function experiment_optflow_middlebury(ctx) imgf0 = loadimg(joinpath(ctx.indir, "frame10.png")) imgf1 = loadimg(joinpath(ctx.indir, "frame11.png")) - maxflow = 4.6157 # Dimetrodon + gtflow = FileIO.load(joinpath(ctx.indir, "flow10.flo")) + maxflow = OpticalFlowUtils.maxflow(gtflow) ctx = Util.Context(ctx; imgf0, imgf1, maxflow) + mkpath(ctx.outdir) return optflow(ctx) end -- GitLab