{"version":3,"file":"detection.cjs","names":[],"sources":["../../../src/vision/postprocess/detection.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Detection head postprocessing: anchor-free YOLO decoding + non-maximum suppression.\n *\n * The shared {@link decodeYoloAnchors} helper does the per-anchor work that\n * is identical for plain detection and segmentation (transpose, xywh→xyxy,\n * letterbox unmap, per-class NMS, sort & cap). {@link decodeYolo} is a thin\n * wrapper around it; the segmentation module ({@link ./segmentation.js})\n * calls the helper directly so it can also recover the per-anchor mask\n * coefficients.\n *\n * Works for any YOLO export with the post-v8 anchor-free head:\n * **YOLOv8 / v9 / v10 / v11 / v12** detect heads, all of which share the\n * `[1, 4 + nc, N]` output layout.\n */\n\nimport { BoundingBox } from \"../types\";\n\n/**\n * Greedy non-maximum suppression on axis-aligned bounding boxes.\n *\n * Mirrors `torchvision.ops.nms` (keeps boxes with the highest score, drops\n * any subsequent box whose IoU exceeds the threshold).\n *\n * @param boxes Flat array of length `4 * N` in xyxy order: `[x1,y1,x2,y2, ...]`.\n * @param scores Detection score per box, length `N`.\n * @param iouThreshold Boxes with IoU above this threshold relative to a kept box are suppressed.\n * @returns Indices of kept boxes, in descending score order. Boxes tied on\n *   score are visited lowest-index first, so the survivor of a tie is\n *   deterministic and matches both `torchvision` and the Python SDK.\n */\nexport function nms(boxes: Float32Array, scores: Float32Array, iouThreshold: number): Int32Array {\n    const n = scores.length;\n    if (n === 0) return new Int32Array(0);\n\n    const areas = new Float32Array(n);\n    for (let i = 0; i < n; i++) {\n        const x1 = boxes[i * 4] as number;\n        const y1 = boxes[i * 4 + 1] as number;\n        const x2 = boxes[i * 4 + 2] as number;\n        const y2 = boxes[i * 4 + 3] as number;\n        areas[i] = Math.max(0, x2 - x1) * Math.max(0, y2 - y1);\n    }\n\n    const order = new Array<number>(n);\n    for (let i = 0; i < n; i++) order[i] = i;\n    order.sort((a, b) => (scores[b] as number) - (scores[a] as number) || a - b);\n\n    const suppressed = new Uint8Array(n);\n    const keep: number[] = [];\n\n    for (let oi = 0; oi < order.length; oi++) {\n        const i = order[oi] as number;\n        if (suppressed[i]) continue;\n        keep.push(i);\n\n        const ax1 = boxes[i * 4] as number;\n        const ay1 = boxes[i * 4 + 1] as number;\n        const ax2 = boxes[i * 4 + 2] as number;\n        const ay2 = boxes[i * 4 + 3] as number;\n        const ai = areas[i] as number;\n\n        for (let oj = oi + 1; oj < order.length; oj++) {\n            const j = order[oj] as number;\n            if (suppressed[j]) continue;\n\n            const bx1 = boxes[j * 4] as number;\n            const by1 = boxes[j * 4 + 1] as number;\n            const bx2 = boxes[j * 4 + 2] as number;\n            const by2 = boxes[j * 4 + 3] as number;\n\n            const ix1 = Math.max(ax1, bx1);\n            const iy1 = Math.max(ay1, by1);\n            const ix2 = Math.min(ax2, bx2);\n            const iy2 = Math.min(ay2, by2);\n            const iw = Math.max(0, ix2 - ix1);\n            const ih = Math.max(0, iy2 - iy1);\n            const inter = iw * ih;\n            const union = ai + (areas[j] as number) - inter;\n            const iou = union > 0 ? inter / union : 0;\n            if (iou > iouThreshold) suppressed[j] = 1;\n        }\n    }\n\n    return Int32Array.from(keep);\n}\n\n/**\n * Per-class NMS — boxes are suppressed only by other boxes of the same class.\n *\n * Mirrors `torchvision.ops.batched_nms`.\n *\n * @param boxes Flat array of length `4 * N` in xyxy order.\n * @param scores Detection score per box, length `N`.\n * @param idxs Class index per box, length `N`. Boxes with different `idxs`\n *   never suppress each other.\n * @param iouThreshold IoU threshold for suppression within a class.\n * @returns Indices of kept boxes, sorted by descending score across all\n *   classes. Survivors from different classes that are tied on score are\n *   ordered lowest-index first — an explicit tie-break, because the order the\n *   per-class loop emits them in is an implementation detail (here, `Map`\n *   insertion order; in Python, sorted class order).\n */\nexport function batchedNms(\n    boxes: Float32Array,\n    scores: Float32Array,\n    idxs: Int32Array,\n    iouThreshold: number,\n): Int32Array {\n    if (scores.length === 0) return new Int32Array(0);\n\n    const byClass = new Map<number, number[]>();\n    for (let i = 0; i < idxs.length; i++) {\n        const c = idxs[i] as number;\n        const list = byClass.get(c);\n        if (list === undefined) byClass.set(c, [i]);\n        else list.push(i);\n    }\n\n    const keep: number[] = [];\n    for (const indices of byClass.values()) {\n        const m = indices.length;\n        const subBoxes = new Float32Array(m * 4);\n        const subScores = new Float32Array(m);\n        for (let k = 0; k < m; k++) {\n            const i = indices[k] as number;\n            subBoxes[k * 4] = boxes[i * 4] as number;\n            subBoxes[k * 4 + 1] = boxes[i * 4 + 1] as number;\n            subBoxes[k * 4 + 2] = boxes[i * 4 + 2] as number;\n            subBoxes[k * 4 + 3] = boxes[i * 4 + 3] as number;\n            subScores[k] = scores[i] as number;\n        }\n        const subKeep = nms(subBoxes, subScores, iouThreshold);\n        for (let k = 0; k < subKeep.length; k++) {\n            keep.push(indices[subKeep[k] as number] as number);\n        }\n    }\n\n    keep.sort((a, b) => (scores[b] as number) - (scores[a] as number) || a - b);\n    return Int32Array.from(keep);\n}\n\nexport interface DecodeYoloAnchorsOptions {\n    /** Number of class-score channels following the 4 box channels. */\n    readonly numClasses: number;\n    readonly originalWidth: number;\n    readonly originalHeight: number;\n    readonly padLeft: number;\n    readonly padTop: number;\n    readonly scale: number;\n    readonly confThreshold: number;\n    readonly iouThreshold: number;\n    readonly maxDetections: number;\n}\n\nexport interface DecodedAnchors {\n    /** Indices into the original `numAnchors` axis, in descending confidence order. */\n    readonly anchorIndices: Int32Array;\n    /** `[k, 4]` boxes in original-image pixel coords, flat row-major xyxy. */\n    readonly boxesXyxy: Float32Array;\n    /** Predicted class id per survivor. */\n    readonly classIds: Int32Array;\n    /** Confidence per survivor. */\n    readonly confidences: Float32Array;\n}\n\n/**\n * Shared YOLO per-anchor decode used by both detection and segmentation\n * (v8 / v9 / v10 / v11 / v12).\n *\n * Only the first `4 + numClasses` channels are read; later channels (e.g.\n * mask coefficients) are ignored — callers can fetch them via the returned\n * {@link DecodedAnchors.anchorIndices}.\n *\n * @param data Flat per-anchor output, length `channels * numAnchors`.\n * @param dims Dims as reported by ORT, e.g. `[1, 84, 8400]` (det) or\n *   `[1, 116, 8400]` (seg). The leading batch dim must be 1.\n */\nexport function decodeYoloAnchors(\n    data: Float32Array,\n    dims: readonly number[],\n    options: DecodeYoloAnchorsOptions,\n): DecodedAnchors {\n    let normalized = dims;\n    if (normalized.length === 3) {\n        if (normalized[0] !== 1) {\n            throw new Error(`decodeYoloAnchors: expected batch size 1, got ${normalized[0]}.`);\n        }\n        normalized = [normalized[1] as number, normalized[2] as number];\n    }\n    if (normalized.length !== 2) {\n        throw new Error(\n            `decodeYoloAnchors: expected 2-D output after batch removal, got dims=${JSON.stringify(dims)}.`,\n        );\n    }\n    const channels = normalized[0] as number;\n    const numAnchors = normalized[1] as number;\n\n    const {\n        numClasses,\n        originalWidth,\n        originalHeight,\n        padLeft,\n        padTop,\n        scale,\n        confThreshold,\n        iouThreshold,\n        maxDetections,\n    } = options;\n\n    if (numClasses < 1 || numClasses + 4 > channels) {\n        throw new Error(\n            `decodeYoloAnchors: invalid numClasses=${numClasses} for channels=${channels}.`,\n        );\n    }\n    if (data.length !== channels * numAnchors) {\n        throw new Error(\n            `decodeYoloAnchors: data length ${data.length} does not match channels*numAnchors=${channels * numAnchors}.`,\n        );\n    }\n\n    type Candidate = {\n        anchorIdx: number;\n        x1: number;\n        y1: number;\n        x2: number;\n        y2: number;\n        classId: number;\n        confidence: number;\n    };\n    const candidates: Candidate[] = [];\n\n    for (let a = 0; a < numAnchors; a++) {\n        let bestCls = 0;\n        let bestScore = -Infinity;\n        for (let c = 0; c < numClasses; c++) {\n            const s = data[(4 + c) * numAnchors + a];\n            if (s !== undefined && s > bestScore) {\n                bestScore = s;\n                bestCls = c;\n            }\n        }\n        if (bestScore < confThreshold) continue;\n\n        const cx = data[a] as number;\n        const cy = data[numAnchors + a] as number;\n        const w = data[2 * numAnchors + a] as number;\n        const h = data[3 * numAnchors + a] as number;\n\n        let x1 = cx - w / 2;\n        let y1 = cy - h / 2;\n        let x2 = cx + w / 2;\n        let y2 = cy + h / 2;\n\n        x1 = (x1 - padLeft) / scale;\n        y1 = (y1 - padTop) / scale;\n        x2 = (x2 - padLeft) / scale;\n        y2 = (y2 - padTop) / scale;\n\n        x1 = Math.max(0, Math.min(originalWidth, x1));\n        y1 = Math.max(0, Math.min(originalHeight, y1));\n        x2 = Math.max(0, Math.min(originalWidth, x2));\n        y2 = Math.max(0, Math.min(originalHeight, y2));\n\n        candidates.push({ anchorIdx: a, x1, y1, x2, y2, classId: bestCls, confidence: bestScore });\n    }\n\n    if (candidates.length === 0) return emptyDecoded();\n\n    // Build flat arrays then delegate to batchedNms — same algorithm as before\n    // but funnelled through the public per-class NMS helper.\n    const flatBoxes = new Float32Array(candidates.length * 4);\n    const scoresArr = new Float32Array(candidates.length);\n    const idxsArr = new Int32Array(candidates.length);\n    for (let i = 0; i < candidates.length; i++) {\n        const c = candidates[i] as Candidate;\n        flatBoxes[i * 4] = c.x1;\n        flatBoxes[i * 4 + 1] = c.y1;\n        flatBoxes[i * 4 + 2] = c.x2;\n        flatBoxes[i * 4 + 3] = c.y2;\n        scoresArr[i] = c.confidence;\n        idxsArr[i] = c.classId;\n    }\n    const kept = batchedNms(flatBoxes, scoresArr, idxsArr, iouThreshold);\n    if (kept.length === 0) return emptyDecoded();\n\n    const limited = Array.from(kept).slice(0, maxDetections);\n    const k = limited.length;\n    const anchorIndices = new Int32Array(k);\n    const boxesXyxy = new Float32Array(k * 4);\n    const classIds = new Int32Array(k);\n    const confidences = new Float32Array(k);\n    for (let i = 0; i < k; i++) {\n        const c = candidates[limited[i] as number] as Candidate;\n        anchorIndices[i] = c.anchorIdx;\n        boxesXyxy[i * 4] = c.x1;\n        boxesXyxy[i * 4 + 1] = c.y1;\n        boxesXyxy[i * 4 + 2] = c.x2;\n        boxesXyxy[i * 4 + 3] = c.y2;\n        classIds[i] = c.classId;\n        confidences[i] = c.confidence;\n    }\n    return { anchorIndices, boxesXyxy, classIds, confidences };\n}\n\nfunction emptyDecoded(): DecodedAnchors {\n    return {\n        anchorIndices: new Int32Array(0),\n        boxesXyxy: new Float32Array(0),\n        classIds: new Int32Array(0),\n        confidences: new Float32Array(0),\n    };\n}\n\nexport interface DecodeYoloOptions {\n    readonly originalWidth: number;\n    readonly originalHeight: number;\n    readonly padLeft: number;\n    readonly padTop: number;\n    readonly scale: number;\n    readonly confThreshold: number;\n    readonly iouThreshold: number;\n    readonly maxDetections: number;\n}\n\nexport interface DecodedDetection {\n    readonly bbox: BoundingBox;\n    readonly classId: number;\n    readonly confidence: number;\n}\n\n/**\n * Decode an anchor-free YOLO detection output into a list of detections.\n *\n * Works for **YOLOv8 / v9 / v10 / v11 / v12** detect heads.\n *\n * Expected raw shape: `[1, 4 + numClasses, N]`. `numClasses` is inferred\n * from the channel count.\n */\nexport function decodeYolo(\n    output: Float32Array,\n    outputDims: readonly number[],\n    options: DecodeYoloOptions,\n): DecodedDetection[] {\n    const channels = outputDims.length === 3 ? outputDims[1] : outputDims[0];\n    if (channels === undefined || channels < 5) {\n        throw new Error(`decodeYolo: invalid output channel count ${channels} (expected >= 5).`);\n    }\n    const numClasses = channels - 4;\n\n    const decoded = decodeYoloAnchors(output, outputDims, {\n        numClasses,\n        ...options,\n    });\n\n    const results: DecodedDetection[] = [];\n    for (let i = 0; i < decoded.classIds.length; i++) {\n        results.push({\n            bbox: new BoundingBox(\n                decoded.boxesXyxy[i * 4] as number,\n                decoded.boxesXyxy[i * 4 + 1] as number,\n                decoded.boxesXyxy[i * 4 + 2] as number,\n                decoded.boxesXyxy[i * 4 + 3] as number,\n            ),\n            classId: decoded.classIds[i] as number,\n            confidence: decoded.confidences[i] as number,\n        });\n    }\n    return results;\n}\n"],"mappings":"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"}