import type { ROI } from "./frameSource.js"; /** * Face ROI geometry + a canvas debug overlay. * * {@link computeFaceRoiRects} maps face-mesh landmarks to the pixel rectangles * sampled for the pulse signal (the single source of truth shared with the * sampler), and {@link drawFaceOverlay} renders the mesh tessellation plus those * ROI boxes over a camera canvas so it is visually obvious which pixels feed the * estimate, with box brightness tracking each region's live fusion weight. * * This module has no MediaPipe dependency: landmarks are plain normalized * {x, y} points and the tessellation connection list (if any) is passed in by * the caller — e.g. `FaceLandmarker.FACE_LANDMARKS_TESSELATION` from * `@mediapipe/tasks-vision`. */ export type LandmarkLike = { x: number; y: number; }; export type FaceRoiName = "forehead" | "leftCheek" | "rightCheek" | "centralFace" | "broadFace"; /** [x0, y0, x1, y1] as fractions of the face bounding box. */ export declare const FACE_ROI_FRACTIONS: Record; /** * The forehead + cheek regions fused for the pulse signal — also the default * regions drawn by the overlay, so what is sampled is exactly what is shown. */ export declare const FUSION_ROI_NAMES: readonly FaceRoiName[]; /** * Pixel rectangles for each named face ROI, derived from the 5th/95th-percentile * bounding box of the landmarks. Returns an empty object when there are no * landmarks or the canvas has no area. */ export declare function computeFaceRoiRects(landmarks: LandmarkLike[], width: number, height: number, fractions?: Partial>): Partial>; /** * Ordered list of the forehead + cheek sub-ROIs sampled for the pulse signal — * the exact rectangles {@link drawFaceOverlay} draws. A frame source should use * this to populate `frame.rois` so the sampled pixels match the overlay (and so * the ROI geometry has a single source of truth). Regions whose rect collapses * to nothing (e.g. a degenerate landmark cloud) are omitted. */ export declare function computeFusionSubRois(landmarks: LandmarkLike[], width: number, height: number): ROI[]; export interface MeshConnection { start: number; end: number; } export interface DrawFaceOverlayOptions { /** * Mesh tessellation connections (e.g. * `FaceLandmarker.FACE_LANDMARKS_TESSELATION`). When omitted, only the ROI * boxes are drawn. */ tessellation?: ReadonlyArray; /** Which ROIs to box (default forehead + both cheeks). */ rois?: readonly FaceRoiName[]; /** Live per-ROI fusion weights (0..1); drives box brightness + labels. */ weights?: Partial>; /** * Set when the canvas is CSS-mirrored to match a flipped selfie video, so * labels are counter-flipped to render the right way round (default true). */ mirrored?: boolean; } /** * Draw the face mesh tessellation + the rPPG ROI boxes onto a 2D canvas * context. Box stroke/fill brightness is proportional to each region's current * fusion weight (equal weighting when none is supplied). */ export declare function drawFaceOverlay(ctx: CanvasRenderingContext2D, landmarks: LandmarkLike[], width: number, height: number, options?: DrawFaceOverlayOptions): void; //# sourceMappingURL=faceRoiOverlay.d.ts.map