fix: drop glare holes before the margin and never auto-pick specks
Filtering holes after the margin let -2 mm grow 1 mm specks past the 3 mm cutoff, and could drop real holes shrunk by a positive margin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
abef0f982b
commit
41baa25a01
7 files changed
+59
-25
No files matched your search
+27
-1
@@ -100,6 +100,7 @@ export function detect(cv: CV, image: RasterImage, params: DetectParams): Shape
|
||||
const lab = labels.data32S;
|
||||
const m = mask.data;
|
||||
for (let i = 0; i < lab.length; i++) m[i] = lab[i] === label ? 255 : 0;
|
||||
fillSmallHoles(cv, mask, params.minHolePx);
|
||||
return traceMask(cv, mask, params.marginPx);
|
||||
} finally {
|
||||
gray.delete();
|
||||
@@ -134,16 +135,41 @@ function pickComponent(
|
||||
}
|
||||
}
|
||||
|
||||
// Without a click, specks (dust, grain) must never pass as the piece.
|
||||
const minArea = 0.01 * width * height;
|
||||
let best: number | null = null;
|
||||
let bestArea = 0;
|
||||
for (let label = 1; label < count; label++) {
|
||||
const b = box(label);
|
||||
if (b.left === 0 || b.top === 0 || b.right === width || b.bottom === height) continue;
|
||||
const area = stat(label, cv.CC_STAT_AREA);
|
||||
if (area > bestArea) {
|
||||
if (area >= minArea && area > bestArea) {
|
||||
bestArea = area;
|
||||
best = label;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
/** Fill holes under minHolePx in both directions, before the margin can grow them. */
|
||||
function fillSmallHoles(cv: CV, mask: Mat, minHolePx: number) {
|
||||
if (minHolePx <= 0) return;
|
||||
const contours = new cv.MatVector();
|
||||
const hierarchy = new cv.Mat();
|
||||
try {
|
||||
cv.findContours(mask, contours, hierarchy, cv.RETR_CCOMP, cv.CHAIN_APPROX_SIMPLE);
|
||||
const h = hierarchy.data32S;
|
||||
for (let i = 0; i < contours.size(); i++) {
|
||||
if (h[i * 4 + 3] === -1) continue;
|
||||
const c = contours.get(i);
|
||||
const rect = cv.boundingRect(c);
|
||||
c.delete();
|
||||
if (rect.width < minHolePx && rect.height < minHolePx) {
|
||||
cv.drawContours(mask, contours, i, new cv.Scalar(255), cv.FILLED);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
contours.delete();
|
||||
hierarchy.delete();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user