One value per pixel, row-major, on a 0-255 scale.
Image width in pixels.
Image height in pixels.
Region of interest; clipped to the image.
Which image axis the tube runs along: 'x' sums columns,
'y' sums rows.
See AxialFluxOptions.
The normalised profile and its percentiles. insidePixels and
samples are 0 for an empty, out-of-image or all-background region,
and the percentiles are then 0 — a value that fails a > 0.9 guard
loudly instead of reading as clean. The same holds when more than half
the profile is empty, which leaves the median at zero and the profile
unnormalisable.
Profile the tube's total flux along its axis — the smooth-dip detector.
For every position along
axisthe above-cutoff luminance of the perpendicular cross-section is summed, then the whole profile is divided by its own median so the result is a relative "how much of the tube is here" curve centred on1.0. A tube that renders at uniform brightness gives a dead-flat profile; the #780 bead chain — every interior joint dimmed to 50% over a width-sized, perfectly smooth ramp — leaves measureLocalMedianOutliers at zero outliers while draggingp05from 1.0 down toward 0.7. That asymmetry is the entire reason this second metric exists.Only the LEADING and TRAILING all-background runs are trimmed — the case where the region overhangs the ends of the tube. An all-background position in the INTERIOR is a hole in the tube and is recorded as
0, counted in AxialFluxResult.emptySamples. Skipping interior holes instead (the obvious implementation) is catastrophic: a tube missing every other 8-pixel run — half the line gone — closes back up into a perfectly flat profile ofp05 = p95 = 1and zero median outliers, so every assertion an acceptance spec could make would pass on a renderer that lost half the geometry.