feat: run manual polygons through the shared margin pipeline

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
immortaly007andClaude Opus 5.5 committed 2026-10-15 14:44:35 +02:00
1 parent 9e48c5d762
commit fad7deed5d
2 files changed
+63

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
import type { Mat } from '@techstark/opencv-js';
import { traceMask } from './detect';
import type { CV } from './opencv-loader';
import type { Point, Shape } from './types';
export function shapeFromPolygons(cv: CV, width: number, height: number, polygons: Shape, marginPx: number): Shape | null {
if (polygons.outer.length < 3) return null;
const mask = cv.Mat.zeros(height, width, cv.CV_8UC1) as Mat;
try {
fill(cv, mask, [polygons.outer], 255);
fill(cv, mask, polygons.holes.filter((h) => h.length >= 3), 0);
return traceMask(cv, mask, marginPx);
} finally {
mask.delete();
}
}
function fill(cv: CV, mask: Mat, rings: Point[][], value: number) {
if (rings.length === 0) return;
const mats = rings.map((ring) =>
cv.matFromArray(ring.length, 1, cv.CV_32SC2, ring.flatMap((p) => [Math.round(p.x), Math.round(p.y)])),
);
const vector = new cv.MatVector();
try {
mats.forEach((m) => vector.push_back(m));
cv.fillPoly(mask, vector, new cv.Scalar(value));
} finally {
vector.delete();
mats.forEach((m) => m.delete());
}
}