AR: sub-pixel corner refinement, ROI-first detection, anchor coplanarity check

This commit is contained in:
jessikitty committed 2026-10-12 13:07:46 +11:00
1 parent 7947eb61a0
commit 7fc2b02e6a
13 files changed
+1160 -10

No files matched your search

+22 -1
View File
@@ -13,8 +13,21 @@ export function createDetector() {
* rawIds tells you what the camera actually saw.
*/
export function detectMarkers(detector, imageData, knownIds) {
const raw = detector.detect(imageData).filter(m => quadArea(m.corners) > 100);
return finaliseMarkers(detectRaw(detector, imageData), knownIds);
}
/* Raw decode over whatever image you hand it — a full detection frame or an ROI
* crop. Split out from detectMarkers so roi.js can run the same decode on a crop
* and have the results finalised together with everything else. The area floor
* is in the pixels of THIS image, which is what we want: a crop is higher
* resolution, so a marker that scrapes past the floor in a full frame clears it
* comfortably in a crop. */
export function detectRaw(detector, imageData) {
return detector.detect(imageData).filter(m => quadArea(m.corners) > 100);
}
/* Dedupe, filter to the scene, attach diagnostics. */
export function finaliseMarkers(raw, knownIds) {
/* Deduplicate by id. Two quads in one frame can decode to the same id — a
* misread of a different crest under blur or glare. That is poison for the
* board solve: both quads are handed the SAME world corners, so solvePnP gets
@@ -36,6 +49,14 @@ export function detectMarkers(detector, imageData, knownIds) {
return usable;
}
/* Centre of a quad — used to merge markers that the same crest produced in two
* overlapping ROI crops. */
export function quadCentre(c) {
let x = 0, y = 0;
for (let i = 0; i < 4; i++) { x += c[i].x; y += c[i].y; }
return { x: x / 4, y: y / 4 };
}
export function quadArea(c) {
// shoelace
let a = 0;