Small isolated artifacts (e.g. a room corner the photo caught past the black
sheet) survived the flood-fill as separate slab islands and carried into the
rest of the workflow. After the border flood-fill, label the 4-connected slab
components and keep only the largest, with a 0.5%-of-frame area floor that
also drops speckles. Adds keepLargestComponent + unit tests proving an
isolated blob and a corner artifact are dropped while the main slab is kept.
The green/black-sheet luminance threshold could not separate the slab from
the 'black' sheet, which in real photos reads at lum ~50 and overlaps the
slab's bark/shadow tones (measured on the user's samples: 0% green, 60-80%
dark, no brightness gap) - it removed 100% of the image. Replace the mask
pass with connectivity-based background removal: sample the sheet tone from
the border, flood-fill from the border marking sheet-connected pixels as
background, keep the connected remainder as the slab. Robust to tonal
overlap. Adds bgRemoval.ts (removeBackground + sampleSheetTone) with unit
tests proving a sheet-toned slab pixel survives via enclosure.
Lower the axial body threshold while retaining fringe rejection, minimize length-only tip inset, and make sheet sensitivity curves testable and conservative at zero.