realtime-capture
Source: realtime-capture.js:17
Everything that decides whether a frame is good enough to believe.
The baseline is captured once and every number for the rest of the session is measured against it, so it is worth being slow and picky about. The prototype took the first frame that returned a descriptor — no confidence check, no framing check, no pose check — which meant a blurred half-turned frame could silently become the reference for an hour of work.
The same gate is reused for spike captures, for the same reason: a single frame at 0.50 is as likely to be motion blur as a result, and "the makeup is working" is not a claim you want resting on a photo of someone moving.
Instance Methods
median()
Returns the median finite value from a list, or zero for an empty list.
createScratch(size: number): Object
Creates a reusable scratch canvas for crop analysis.
Parameters
size(number) — Square edge length in pixels.
Returns
Object— Scratch surface.
analyseCrop(
video: HTMLVideoElement,
box: Object,
scratch: Object,
): Object
Measures relative sharpness and exposure of a face crop.
Sharpness is gradient energy and is used only for RANKING candidates against each other, never against a fixed floor — an absolute threshold would be one more magic number that varies with every camera and lighting setup.
Parameters
video(HTMLVideoElement) — Source video element.box(Object) — Face box in video pixels.scratch(Object) — Scratch surface.
Returns
Object— Crop statistics.
analyseAmbientLuma(
video: HTMLVideoElement,
box: Object,
scratch: Object,
): number
Estimates illumination from pixels outside the detected face box. Makeup can legitimately darken the face crop; using the surrounding frame makes the light comparison less likely to erase the very intervention being studied.
Parameters
video(HTMLVideoElement) — Source video element.box(Object) — Face box.scratch(Object) — Scratch surface.
Returns
number— Mean normalized luma outside the face box.
evaluate(detection: *, options?: object): Object
Judges one detection against every framing and quality rule.
Parameters
detection(*) — face-api detection with landmarks and descriptor.options(object, optional) — Evaluation mode.options.allowAppearanceChanges(boolean, optional, default: false) — Do not let face-crop exposure or detector-score changes reject an intervention frame.
Returns
Object— Verdict.
start(): void
Begins a fresh collection run.
Returns
void
cancel(): void
Ends the current run without producing a baseline.
Returns
void
isActive(): boolean
Reports whether a run is in progress.
Returns
boolean— True while collecting.
offer(
verdict: object,
descriptor: Float32Array | Array.<number>,
observation?: object,
): object
Offers one gated frame to the collector.
Parameters
verdict(object) — Quality gate verdict.descriptor(Float32Array | Array.<number>) — Descriptor for the frame.observation(object, optional) — Source timing and identity.observation.sourceTimeMs(number, optional) — Media time for a local video.observation.id(string | number, optional) — Stable id for one source frame.
Returns
object— Collector progress and, when complete, the temporal medoid.
reset(): void
Clears session state after a new baseline is set.
Returns
void
noteCapture(value: number): void
Marks a capture as taken so the cooldown applies.
Parameters
value(number) — Distance at capture time.
Returns
void
update(value: number): Object
Feeds one live distance reading to the detector.
Parameters
value(number) — Live distance for this frame.
Returns
Object— Verdict.
clear(): void
Empties the buffer.
Returns
void
push(sharpness: number, distance: number): void
Records the current video frame with its measured sharpness.
Parameters
sharpness(number) — Relative sharpness of this frame.distance(number) — Distance reading at this frame.
Returns
void
best(): Object | null
Returns the sharpest retained frame.
Returns
Object | null— Best frame.
Static Methods
summarizeConditions(readings: Array.<object>): object | null
Averages the capture conditions accepted during one temporal window.
Parameters
readings(Array.<object>) — Per-frame 2D pose, framing and light metrics.
Returns
object | null— Mean condition profile, or null when unavailable.
summarizeGuides(guides: Array.<object>): object | null
Builds one robust, normalized 2D reference guide from accepted frames. This geometry is deliberately separate from the descriptor medoid: it is only a visual alignment aid and never participates in distance arithmetic.
Parameters
guides(Array.<object>) — Per-frame normalized face boxes and 68 landmarks.
Returns
object | null— Coordinate-wise median guide.
compareConditions(
baseline: object | null,
current: object | null,
overrides?: object,
): Object
Checks whether a live frame is comparable with the baseline conditions. This is deliberately a 2D nuisance gate, not pose correction: rejected frames are omitted rather than mathematically transformed into a result.
Parameters
baseline(object | null) — Baseline condition profile.current(object | null) — Current frame conditions.overrides(object, optional) — Partial tolerance overrides.
Returns
Object— Comparison verdict.
euclidean(
a: Float32Array | Array.<number>,
b: Float32Array | Array.<number>,
): number
Euclidean distance between two descriptors.
Kept local rather than reaching for the global faceapi so this module can be imported and unit tested without the vendor bundle present.
Parameters
a(Float32Array | Array.<number>) — First descriptor.b(Float32Array | Array.<number>) — Second descriptor.
Returns
number— Euclidean distance.
medoid(
descriptors: Array.<(Float32Array|Array.<number>)>,
): Object
Picks the medoid of a descriptor set and reports its spread.
The medoid — the member with the smallest summed distance to the others — is used rather than the mean because it stays a real point in the embedding. Averaging near-unit vectors that are not perfectly aligned yields something slightly shorter than its inputs, which bakes a small systematic offset into every distance measured for the rest of the session.
The returned spread is the session's NOISE FLOOR: how far the descriptor moves when nothing about the face has changed. It is the only empirical reference line this tool draws.
Parameters
descriptors(Array.<(Float32Array|Array.<number>)>) — Collected descriptors.
Returns
Object— Medoid result.
createQualityGate(
video: HTMLVideoElement,
overrides?: object,
): Object
Creates the frame quality gate.
Parameters
video(HTMLVideoElement) — Source video element.overrides(object, optional) — Partial gate threshold overrides.
Returns
Object— Quality gate.
createBaselineCollector(options: object): object
Creates the baseline collector.
Progress advances on ACCEPTED samples only, never on elapsed time. A stalled ring means frames are being rejected, and the reason is reported alongside — so the control diagnoses itself instead of silently timing out.
Parameters
options(object) — Collector options.options.targetSamples(number) — Accepted samples required.options.minDurationMs(number) — Floor on capture duration.options.timeoutMs(number) — Abandon threshold.options.maxSpread(number) — Largest acceptable noise floor.
Returns
object— Baseline collector.
createSpikeDetector(options: object): object
Creates the sustained-spike detector.
Capture triggers on a reading that HOLDS, not on an instantaneous value, and the frame written to disk is the sharpest one observed across the sustain window rather than whichever frame happened to trip the trigger.
Two conditions fire a capture: personal best — a new session maximum by a real margin, which is what you iterate against between makeup passes crossing — the first time the run clears the cited match threshold
Parameters
options(object) — Detector options.options.sustainMs(number) — Time a reading must hold.options.bestMargin(number) — Margin over the session best.options.threshold(number) — Cited match threshold.options.cooldownMs(number) — Minimum spacing between captures.
Returns
object— Spike detector.
createFrameBuffer(
video: HTMLVideoElement,
slots: number,
maxWidth: number,
): object
Creates a rotating buffer of full video frames.
Snapshots are only taken while a spike candidate is live, so the buffer costs nothing during ordinary tracking.
Parameters
video(HTMLVideoElement) — Source video element.slots(number) — Number of frames retained.maxWidth(number) — Longest edge written to a snapshot.
Returns
object— Frame buffer.
Other
LM_LEFT_EYE_OUTER
Landmark indices in face-api's 68-point model.