UAT-7: fix auto key selection — prefer key that removes more background

Root cause: auto selected the key with MORE kept pixels, which always
picked the green key (it keeps 100% of dark non-green backgrounds).
The black key correctly isolates the slab on dark surfaces.

Fix:
- auto now prefers the key with FEWER kept pixels (removed more bg)
  when both are non-empty
- green key has a greenness pre-filter: non-greenish pixels pass
  through (kept) so the black key can handle them, instead of the
  green key keeping 100% of a dark surface
- added 3 regression tests: dark-bg auto selection, green-sheet auto
  selection, green-key passthrough on non-green surfaces

106/106 unit tests green.
This commit is contained in:
Ty
2026-09-14 07:41:51 -07:00
parent 88b9c47200
commit a83c9239ff
2 changed files with 77 additions and 6 deletions
+38
View File
@@ -96,6 +96,44 @@ describe('keySheet', () => {
// 12x8 = 96 pixels
expect(maskStats(mask).kept).toBe(96);
});
it('green key passes non-green pixels through (black key handles them)', () => {
// Real slab photos (sample_01..06) have a dark blue-gray background
// (e.g. rgb 26,27,29) with a bright warm slab (e.g. rgb 250,200,140).
// The green key is designed to key out a GREEN sheet only. On a dark
// (non-green) surface it passes pixels through (keeps them) so that
// the black key can remove them. The green key alone does NOT remove
// a dark background — that is the black key's job. Auto selects the
// black key in this case (see the auto test below).
const darkBg = solid(12, 8, 26, 27, 29);
withRect(darkBg, 12, 2, 2, 8, 4, 250, 200, 140);
const mask = keySheet(darkBg, { sheet: 'green', sensitivity: 50 });
const stats = maskStats(mask);
// Green key on dark bg: all pixels are non-greenish, so all are kept.
// This is BY DESIGN — the green key is a no-op on non-green surfaces,
// and auto will select the black key instead.
expect(stats.kept).toBe(96);
});
it('auto selects black key over green key on a dark-background photo', () => {
// Real photo: dark bg + bright slab. Green key keeps ~everything (bad).
// Black key keeps only the slab (good). Auto must pick black.
const darkBg = solid(12, 8, 26, 27, 29);
withRect(darkBg, 12, 2, 2, 8, 4, 250, 200, 140);
const mask = keySheet(darkBg, { sheet: 'auto', sensitivity: 50 });
const stats = maskStats(mask);
// Should keep only the slab (32 px), not the whole frame (96 px).
expect(stats.kept).toBe(32);
});
it('auto selects green key over black key on a green-sheet photo', () => {
// Green sheet + brown slab. Green key keeps slab only. Black key may
// keep slab + some sheet. Auto must pick green (fewer kept = better).
const photo = GREEN_PHOTO();
const mask = keySheet(photo, { sheet: 'auto', sensitivity: 50 });
const stats = maskStats(mask);
expect(stats.kept).toBe(32);
});
});
// --- maskStats -------------------------------------------------------------------