Skip to content

Commit

Permalink
Experimental Parametric RANSAC solver
Browse files Browse the repository at this point in the history
  • Loading branch information
Affie committed Mar 7, 2024
1 parent a962e9c commit ee7ea75
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/IncrementalInference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ include("parametric/services/ParametricCSMFunctions.jl")
include("parametric/services/ParametricUtils.jl")
include("parametric/services/ParametricOptim.jl")
include("parametric/services/ParametricManopt.jl")
include("parametric/services/ParametricRANSAC.jl")
include("services/MaxMixture.jl")

#X-stroke
Expand Down
122 changes: 122 additions & 0 deletions src/parametric/services/ParametricRANSAC.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@

#TODO upstream to DFG
function listNeighborhood(fg, variableFactorLabels, distance; filterOrphans=true)
allvarfacs = getNeighborhood(fg, variableFactorLabels, distance)
variableLabels = intersect(listVariables(fg), allvarfacs)
factorLabels = intersect(listFactors(fg), allvarfacs)
if filterOrphans
filter!(factorLabels) do lbl
issubset(getVariableOrder(fg, lbl), variableLabels)

Check warning on line 9 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L3-L9

Added lines #L3 - L9 were not covered by tests
end
end
return variableLabels, factorLabels

Check warning on line 12 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L12

Added line #L12 was not covered by tests
end

function calcResidualInliers(subfg, faclabels; kσ=1)
varlabels = setdiff(getNeighborhood(subfg, faclabels, 1), faclabels)

Check warning on line 16 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L15-L16

Added lines #L15 - L16 were not covered by tests

vars = getVariable.(subfg, varlabels)
M, varTypes, vartypeslist = IIF.buildGraphSolveManifold(vars)
varIntLabel, varlabelsAP = IIF.getVarIntLabelMap(vartypeslist)

Check warning on line 20 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L18-L20

Added lines #L18 - L20 were not covered by tests

p0 = map(varlabelsAP) do label
getVal(subfg, label, solveKey = :parametric)[1]

Check warning on line 23 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L22-L23

Added lines #L22 - L23 were not covered by tests
end

# create an ArrayPartition{CalcFactorResidual} for faclabels
calcfacs = IIF.CalcFactorResidualAP(subfg, faclabels, varIntLabel)

Check warning on line 27 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L27

Added line #L27 was not covered by tests

# remember res = cf.sqrt_iΣ * factor res with calcfacs, so should be sigma scaled
res = reduce(vcat, map(f -> f(p0), Vector(calcfacs)))

Check warning on line 30 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L30

Added line #L30 was not covered by tests
# findfirst(==(median(res)), res)

res_labels = getproperty.(Vector(calcfacs), :faclbl)

Check warning on line 33 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L33

Added line #L33 was not covered by tests
# findfirst(==(:cD1l2000cD1l2000_cD1l5611f1), res_labels)

# 3
inlierlabels = deepcopy(res_labels)
for (i,l) in (enumerate(faclabels))
if abs(res[i]) >
setdiff!(inlierlabels, [l])

Check warning on line 40 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L37-L40

Added lines #L37 - L40 were not covered by tests
end
end

Check warning on line 42 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L42

Added line #L42 was not covered by tests

return res_labels.=>res, inlierlabels

Check warning on line 44 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L44

Added line #L44 was not covered by tests
end

function solveGraphParametricRansac!(

Check warning on line 47 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L47

Added line #L47 was not covered by tests
fg,
comb_on_fac_labels,
min_factors = 3,
include_vars = Symbol[];
n_iters = 50,
stop_ratio = 0.7,
kwargs...
)
# intersect!(comb_on_fac_labels, listNeighbors(fg, ls(fg, r"^x")[1]))
all_fac_combinations = combinations(comb_on_fac_labels, min_factors)

Check warning on line 57 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L57

Added line #L57 was not covered by tests

do_combinations = length(all_fac_combinations) < n_iters ?

Check warning on line 59 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L59

Added line #L59 was not covered by tests
collect(all_fac_combinations) : rand(collect(all_fac_combinations), n_iters)
# collect(all_fac_combinations) : all_fac_combinations[rand(1:length(all_fac_combinations), n_iters)]

best_ratio = 0.0
best_inlierlabels = Symbol[]
for (i, maybe_inliers) = enumerate(do_combinations)

Check warning on line 65 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L63-L65

Added lines #L63 - L65 were not covered by tests

solveVariableLabels, solveFactorLabels = listNeighborhood(fg, union(include_vars, maybe_inliers), 2)

Check warning on line 67 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L67

Added line #L67 was not covered by tests

# TODO do better
subfg = deepcopy(fg)

Check warning on line 70 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L70

Added line #L70 was not covered by tests
# @info solveFactorLabels
# M, v, r, Σ = IIF.solve_RLM(fg, variableLabels, factorLabels;
try
IIF.solveGraphParametric!(subfg, solveVariableLabels, solveFactorLabels; kwargs...)

Check warning on line 74 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L73-L74

Added lines #L73 - L74 were not covered by tests
# IIF.solveGraphParametric!(subfg, kwargs...)
catch er
@warn "Error on iter $i" er
continue

Check warning on line 78 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L77-L78

Added lines #L77 - L78 were not covered by tests
end

residuals, inlierlabels = calcResidualInliers(subfg, comb_on_fac_labels)

Check warning on line 81 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L81

Added line #L81 was not covered by tests

ratio_inliers = length(inlierlabels) ./ length(comb_on_fac_labels)

Check warning on line 83 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L83

Added line #L83 was not covered by tests

if ratio_inliers > best_ratio
best_ratio = ratio_inliers
@info "new best $best_ratio"
best_inlierlabels = inlierlabels

Check warning on line 88 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L85-L88

Added lines #L85 - L88 were not covered by tests
end
if ratio_inliers > stop_ratio
@info "stop ratio met $best_ratio"
break

Check warning on line 92 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L90-L92

Added lines #L90 - L92 were not covered by tests
end
# res_vals = last.(residuals)

end
try
solveVariableLabels, solveFactorLabels = listNeighborhood(fg, union(include_vars, best_inlierlabels), 2)
IIF.solveGraphParametric!(fg, solveVariableLabels, solveFactorLabels; kwargs...)

Check warning on line 99 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L96-L99

Added lines #L96 - L99 were not covered by tests
catch er
@error "solveGraphParametric of inliers failed" er

Check warning on line 101 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L101

Added line #L101 was not covered by tests
end

return best_inlierlabels

Check warning on line 104 in src/parametric/services/ParametricRANSAC.jl

View check run for this annotation

Codecov / codecov/patch

src/parametric/services/ParametricRANSAC.jl#L104

Added line #L104 was not covered by tests
end

if false
## get factor residuals to solve with
comb_on_fac_labels = lsfTypesDict(subfg)[:Pose2Point2Bearing]
# intersect!(faclabels, listNeighbors(subfg, ls(subfg, r"^cD1l\d+$")[1]))
stopping_criterion=StopAfterIteration(100) | StopWhenGradientNormLess(1e-12) | StopWhenStepsizeLess(1e-12)

inlierlabels = solveGraphParametricRansac!(subfg, comb_on_fac_labels;
n_iters = 500,
stopping_criterion,
# debug,
is_sparse=false,
damping_term_min=1e-12,
finiteDiffCovariance=true
)

end

0 comments on commit ee7ea75

Please sign in to comment.