feat: trim textured background (wood grain) touching a smooth piece

Keep the piece's smooth core, then grow it back to restore the true edges.
Removes the wood-knot and grain leaks on the MDF-on-floor photo. Pieces that
are textured themselves are left untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
immortaly007andClaude Opus 5.5 committed 2026-10-15 15:25:53 +02:00
1 parent 077c3cc31d
commit e925ce66d5
4 files changed
+112 -11

No files matched your search

+22 -2
View File
@@ -1,5 +1,5 @@
import { beforeAll, describe, expect, it } from 'vitest';
import { detect, detectPrepared, otsuThreshold, prepareImage, preparedThreshold } from '../src/lib/detect';
import { detect, detectPrepared, disposePrepared, otsuThreshold, prepareImage, preparedThreshold } from '../src/lib/detect';
import { bounds } from '../src/lib/geometry';
import { loadOpenCV, type CV } from '../src/lib/opencv-loader';
import type { DetectParams } from '../src/lib/types';
@@ -126,7 +126,27 @@ describe('detect', () => {
expect(reused.holes).toHaveLength(direct.holes.length);
}
} finally {
prepared.gray.delete();
disposePrepared(prepared);
}
});
it('cuts off textured background (wood grain) that touches a smooth piece', () => {
// Smooth dark piece x 150..449, y 100..299 on a light floor, with a dark grainy knot touching its top-left.
const knotted = grayImage(600, 450, (x, y) => {
if (inRect(x, y, 150, 100, 450, 300)) return 80;
if (inRect(x, y, 90, 50, 170, 110)) return Math.floor(x / 3) % 2 ? 40 : 110;
return 200;
});
const b = bounds(detect(cv, knotted, params({ threshold: 140 }))!.outer);
expect(b.minX).toBeGreaterThanOrEqual(144);
expect(b.minY).toBeGreaterThanOrEqual(94);
near(b.maxX, 449); near(b.maxY, 299);
});
it('keeps a piece that is itself textured (e.g. plywood grain)', () => {
const plywood = grayImage(600, 450, (x, y) =>
inRect(x, y, 150, 100, 450, 300) ? (Math.floor(x / 3) % 2 ? 40 : 110) : 200);
const b = bounds(detect(cv, plywood, params({ threshold: 140 }))!.outer);
near(b.minX, 150); near(b.maxX, 449); near(b.minY, 100); near(b.maxY, 299);
});
});
+2 -2
View File
@@ -4,7 +4,7 @@
"threshold": null,
"seed": null,
"pxPerMm": 1,
"expected": { "widthMm": 1714, "heightMm": 675 },
"toleranceMm": 60
"expected": { "widthMm": 1712, "heightMm": 675, "holes": 0 },
"toleranceMm": 20
}
]