test: add a self-contained MAGSAC++ benchmark suite (synthetic + real datasets) - #50
Draft
f-dy wants to merge 1 commit into
Draft
test: add a self-contained MAGSAC++ benchmark suite (synthetic + real datasets)#50f-dy wants to merge 1 commit into
f-dy wants to merge 1 commit into
Conversation
f-dy
force-pushed
the
feature/benchmarks
branch
15 times, most recently
from
June 2, 2026 16:46
2c72827 to
7c10b28
Compare
… datasets)
Adds benchmarks/ — accuracy benchmarks for pymagsac with synthetic ground truth
and real-dataset loaders, A/B (--compare) of builds or backends on identical data,
and a paper-reproduction script.
Estimators/backends are resolved at runtime and skipped if absent, so the same
command runs on upstream master and on builds that add estimators (e.g. findPlane3D).
- synthetic.py : GT generators + metrics for fundamental, homography, line2d,
plane3d. Reports inlier residual (err), inlier F1, failure rate, time_ms, and
gt_err (estimate vs GT model: SGD for F, reprojection for H, normal angle for
line/plane). Hard regimes (up to 70% outliers) + optional spatially-coherent inliers.
- datasets.py : pre-computed loaders (AdelaideRMF/kusvod2 .mat; homogr/EVD/Oxford
.corr+.H) + optional OpenCV image-pair loader (SIFT + 3x3 GT H).
- run_benchmark.py : --task {fundamental,homography,line2d,plane3d,all};
--backend magsac++/magsac/cv2:NAME (OpenCV RANSAC/LMEDS/USAC baselines);
--sweep-sigma (threshold sensitivity); --sampler (incl. 2=P-NAPSAC) + --coherent.
- reproduce_paper.py : renders the paper's Table 1 with its published reference
rows + our reproduced rows, and the CDF (Fig 3/4) + error-vs-threshold (Fig 5)
figures with the paper's method legend (matplotlib-gated).
- test_datasets.py : loader unit tests on tiny fixtures.
numpy only for synthetic; scipy for .mat; opencv-python for cv2 backends/images;
matplotlib for figures. A parallel pygcransac benchmark could be added in gcransac.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
test: add a self-contained MAGSAC++ benchmark suite (synthetic + real datasets)
What
A
benchmarks/directory with accuracy benchmarks forpymagsac, plus an A/Bmode to compare two builds on identical data (handy whenever the scoring or
weighting is changed). Baselined on
master; entirely additive (no changes tothe library or build).
Estimators (resolved by name in
pymagsacat runtime, so unavailable onesare detected and skipped):
fundamental(DoF 4),homography(DoF 2),line2d(DoF 1) — all on master — and
plane3d(DoF 1,findPlane3D), which is not onmaster but present in builds that add it.
essential(findEssentialMatrix) isalso covered for real data — matching
examples/cpp_example.cpp, which has no GTfor essential, it reports the estimated-E inlier ratio + time.
--task allrunswhatever the build provides. This lets the same command benchmark the upstream
masterbuild and an improved build (e.g. one addingfindPlane3D) and--comparethem directly.--no-mppselects MAGSAC (fixed-σ baseline) instead of MAGSAC++, so a compare ofthe two is a MAGSAC-vs-MAGSAC++ A/B; the synthetic sweep includes hard regimes
(up to 70% outliers) where the difference is most visible. For each problem the
suite reports — over the ground-truth inliers —
err, the RMSE of theestimated model's residual (the same metric as the repo's
examples/cpp_example.cpp,sqrt(mean(squaredResidual over GT inliers))), the inlier-maskF1, and theno-model failure fraction (
none).Backends, metrics, sweeps
--backend:magsac++(default),magsac(the in-repo baseline),py:MODULE(any pymagsac-compatiblepure-python module, e.g.
py:garfield_sfm.magsac, for A/B vs the C++ binding — use--seed), orcv2:NAME— OpenCVfind{FundamentalMat,Homography}withmethod=cv2.NAME(
cv2:RANSAC,cv2:LMEDS,cv2:USAC_MAGSAC, …), reproducing the paper'sRANSAC/LMedS/USAC baselines.
--comparea baseline CSV againstmagsac++.gt_err— theestimate vs the GT model: SGD (symmetric epipolar distance) for F,
reprojection for H, normal angle for line/plane (the paper's metrics) — plus
time_ms.--sweep-sigma: threshold-sensitivity sweep (the paper's key plot — MAGSAC++stays accurate across a wide threshold range while fixed-threshold baselines
degrade).
--coherent+--sampler 2: spatially-clustered inliers + P-NAPSAC, toexercise the sampler advantage (lower
time_ms).Layout
synthetic.py— ground-truth generators + metrics. The synthetic GT model isthe reference, so the metrics are exact (no external oracle).
datasets.py— real-dataset loaders:<scene>_pts.txt(annotated correspondences + label, thecpp_example.cppformat — kusvod2/AdelaideRMF/Multi-H for F, homogr/EVD for H); essential
<scene>_pts.txt(count +x1 y1 x2 y2, no labels) +<scene>1.K/<scene>2.Kintrinsics; AdelaideRMF / kusvod2
*.mat(data+label); and homogr / EVD /Oxford
<stem>.corr+<stem>.H. Discovery is filtered by--task(a mixedfolder won't cross-load) and works out-of-the-box on the bundled
data/(47 fundamental, 16 homography, 1 essential scene).
<stem>A/<stem>B+<stem>_model.txt(3×3 GT H); SIFT + Lowe ratio test build the matches — the same recipe as the
example notebooks. Skipped with a hint if OpenCV is absent.
run_benchmark.py— unified runner:--task, synthetic sweep /--data DIR/--compare A.csv B.csv.test_datasets.py— loader unit tests on tiny synthetic fixtures (no download).reproduce_paper.py— renders the paper's Table 1 with its published reference rows + our reproduced rows, and the CDF (Fig 3/4) + error-vs-threshold (Fig 5) figures with the paper's legend (matplotlib-gated). Runs on the bundleddata/homographydirectly (top-level=homogr,extremeview/=EVD);--sigmadefaults tocpp_example.cpp's σ_max (homography 50, fundamental 5). The H reproduction matches the paper — MAGSAC++ homogr 1.5px (paper 1.3), EVD 5.6px (12.6); LMedS EVD ~94px vs 89.9 (LMedS fails on EVD in both); homogr median is flat at 1.3–1.7px across σ_max 3→100 (the paper's threshold-insensitivity).Usage
python run_benchmark.py --task all --quick python run_benchmark.py --task homography --data /path/to/homogr --gt-thresh 3 # A/B upstream master vs an improved build on identical data: PYTHONPATH=/build_master python run_benchmark.py --task all --out master.csv PYTHONPATH=/build_improved python run_benchmark.py --task all --out improved.csv python run_benchmark.py --compare master.csv improved.csvDependencies
numpy(synthetic),scipy(.matloaders),opencv-python(image-pair loaderonly). Datasets are downloaded separately (URLs in
benchmarks/README.md); noneare vendored.
Note: a gcransac counterpart
This suite drives
pymagsac. An analogous benchmark could be added tograph-cut-ransac driving
pygcransac(same estimators), reusing thesegenerators and loaders, to additionally cover gcransac's own scoring path. Happy
to open that as a companion PR if useful.