What a line segment's own fit statistics say about how well it was located — measured on a real frame, and what consuming them is worth downstream.
N and the two eigenvalues λmax ≥ λmin of their covariance. So
I = N·λmax/λmin estimates the directional information the segment carries, and
w = √I is a per-segment weight with no tuning parameters. Most detectors compute
something like those numbers and then throw them away.Below is one real frame with the segments a detector found on it. Click any highlighted
segment to see what the measurement does to it: a cross-section every pixel along its
dominant axis, a search along the normal for the gradient ridge, a parabola through the
peak, and the scatter of the accepted ridge points — which is λmin.
Segment brightness is its weight under the selected rule. clickable too short to be worth walking selected
Click a segment on the left.
Gradient magnitude at nine samples across the normal, on a 0.5 px grid, with the parabola-refined sub-pixel ridge.
Segment-local coordinates, lateral axis blown up. Their lateral
spread is λmin, and the weight follows from it.
The same detector, the same 1976 frames of one EuRoC sequence, the same estimator — the only thing that changes is the per-segment weight. Error is the angle between the estimated gravity direction and the rig's ground truth.
A precision weight is a statement about how well each member of a set is measured. It presumes the set is the right set. Where the estimator's inlier band is heavily contaminated, precision is not what limits it, and the weight buys nothing.
| regime | axis-consistent fraction of the band | what the weight is worth |
|---|---|---|
| EuRoC machine hall | 0.79–0.82 | 9.4 to 15.1% better, every held-out cell |
| TUM-VI | 0.74–0.81 | improves and degrades in equal measure |
| EuRoC Vicon rooms | 0.50–0.58 | essentially inert |
| single-image Manhattan triads | 0.39–0.65 | beats unit votes, only ties with length |
SweepLSD supplies the three statistics natively — it accumulates the moments inside its streaming labeller, so they cost no extra image pass. LineUQ is the other half: it re-measures the same statistics for detectors that do not supply them, from the image and the reported endpoints alone, and consumes them in a weighted vanishing-point / Manhattan fit.
import lineuq
st = lineuq.measure(image, segments) # any detector's endpoints
w = st.sqrt_fisher() # the weight used above