fix(photos): preserve tapered tips and dark live edge (#73 #74)

Lower the axial body threshold while retaining fringe rejection, minimize length-only tip inset, and make sheet sensitivity curves testable and conservative at zero.
This commit is contained in:
2026-09-16 15:18:06 +00:00
parent 037a4b870a
commit 03d3fcf460
5 changed files with 281 additions and 36 deletions
+2 -21
View File
@@ -1,32 +1,13 @@
import { minAreaRect, slabBounds } from '../geometry/rect';
import type { MaskParams, WorkerIn, WorkerOut } from '../capture/capture.types';
import { decodeOrientedBitmap } from '../decodeOrientedBitmap';
import { greenKeep, blackKeep, autoPickSheet } from '../mask/sheetKeep';
let bitmap: ImageBitmap | null = null;
let data: Uint8ClampedArray | null = null;
let w = 0, h = 0;
let current = 0; // highest job id issued by main; older replies are dropped
// Keep slab pixels; remove the sheet. Higher sensitivity widens the sheet match.
const greenKeep = (r: number, g: number, b: number, s: number): boolean => {
const t = s / 100;
const isSheet = g - Math.max(r, b) > 10 + 35 * t;
return !isSheet;
};
const blackKeep = (r: number, g: number, b: number, s: number): boolean => {
const lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
const isSheet = lum < 40 + 140 * (s / 100);
return !isSheet;
};
const autoPick = (samples: { r: number; g: number; b: number }[]): 'green' | 'black' => {
let gr = 0, gl = 0;
for (const p of samples) {
if (p.g - Math.max(p.r, p.b) > 20) gr++;
if (0.2126 * p.r + 0.7152 * p.g + 0.0722 * p.b < 70) gl++;
}
return gl >= gr ? 'black' : 'green';
};
function runMask(params: MaskParams, id: number): WorkerOut {
if (!data) return { id, kind: 'failed', reason: 'no source decoded' };
let sheet = params.sheet;
@@ -37,7 +18,7 @@ function runMask(params: MaskParams, id: number): WorkerOut {
const i = (y * w + x) * 4;
samples.push({ r: data[i], g: data[i + 1], b: data[i + 2] });
}
sheet = autoPick(samples);
sheet = autoPickSheet(samples);
}
const keep = sheet === 'green' ? greenKeep : blackKeep;
const s = Math.max(0, Math.min(100, params.sensitivity));