Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental Parametric RANSAC solver #1820

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]) > kσ
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 with $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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this to a test file?

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