Enrolment image capture

The face you submit to biofrq.enroll becomes the reference every future identify and verify call is compared against. Every quality issue in that one image follows you for the lifetime of the subject — bad reference, persistent misses.

This page is the standard operating procedure for capturing enrolment images. Probe images (the ones you submit at identify / verify time) follow the same rules, but the bar is highest at enrol.

The one rule that beats everything else

Inspect quality before you enrol. Call biofrq.detect with returnQuality: true first, read the response, and only call biofrq.enroll if the metrics pass the gates below. The detect call costs a fraction of an enrol and saves you from poisoning your gallery with a reference you can't trust.

bash
# 1. Pre-flight: detect + quality
curl -X POST https://api.biofrq.com/v1/face/execute \
  -H "X-Api-Key: bfq_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "biofrq.detect",
    "params": {
      "images": [{ "kind": "image", "bytes": "<base64>", "contentType": "image/jpeg" }],
      "returnQuality": true
    }
  }'

# 2. Only if quality passes -> biofrq.enroll

The quality block lives at data.results[0].value.faces[0].quality.

Quality fields

FieldRangeWhat it measures
overallScore0.0 – 1.0Composite — use this as your headline gate.
sharpnessScore0.0 – 1.0Edge contrast / focus. Low = motion blur or out-of-focus.
brightnessScore0.0 – 1.0Exposure. Low = under- or over-exposed.
faceBoxConfidence0.0 – 1.0How sure the detector is this is a face.
facePixelWidthpxWidth of the face bounding box in source pixels.
facePixelHeightpxHeight of the face bounding box.
yawDegrees±90Head turn left / right.
pitchDegrees±90Head tilt up / down.
rollDegrees±90Head roll (clockwise / anti-clockwise).
poseSupportedboolfalse when the current model build doesn't estimate yaw/pitch/roll.
MetricEnrol minimumProbe minimumRationale
overallScore≥ 0.80≥ 0.35Enrolment is the moment to be strict — a reference at 0.45 looks "good enough" but sits near the cluster centroid and acts as a "magnet" that wrongly attracts unrelated probes downstream. Aim for 0.80 or re-capture. Probes are scored against the gallery either way, so a lower probe bar is fine.
facePixelWidth≥ 112≥ 112The embedding model takes a 112-pixel-wide aligned crop. Sub-112 input is up-sampled (interpolated), losing identity signal.
sharpnessScore≥ 0.40≥ 0.30Motion blur destroys high-frequency face features.
brightnessScore≥ 0.35≥ 0.30Under-exposed faces collapse into noise; over-exposed lose skin tone variation.
faceBoxConfidence≥ 0.85≥ 0.80Low confidence means the detector isn't sure it's a face — embedding will be unstable.
pose (when supported)`yaw,

These are recommendations, not hard limits the service imposes — you choose the policy that matches your operating environment.

Framing the face

The face needs to dominate the crop you send. A small face inside a wide frame wastes resolution; a face cropped tight to the chin loses the forehead and ears the embedding relies on.

Target: face fills 60–80% of the shorter dimension, centred, with margin on all sides.

Properly framed enrolment portrait: face centred, eyes near mid-frame, even lighting, hair and chin both visible, no obstruction.

Good: face fills the height of the crop, eyes near the mid-line, even ambient light.

What to avoid:

  • Face too small in frame — sourced from a wide shot or full-body capture. facePixelWidth will likely fall below 112 and the embedding will be unstable. Re-crop closer or capture at a shorter distance.
  • Face crop too tight — forehead, ears, or chin clipped. The detector aligns on those landmarks; missing any of them degrades the embedding quality.
  • Off-centre — face crammed against one edge. Centre the face before cropping.

Pose tolerance

The embedding is sensitive to head pose. Frontal works best. Acceptable for enrol when poseSupported is true: |yaw| ≤ 20°, |pitch| ≤ 20°, |roll| ≤ 20°.

Frontal portrait, eyes directly at camera.

Slight three-quarter turn, still acceptable for an additional reference.

Full profile — not suitable for enrolment.

Left: frontal (yaw ≈ 0°) — primary reference. Centre: slight angle (yaw ≈ 15°) — fine as an additional reference. Right: profile (yaw ≈ 90°) — do not enrol.

If poseSupported: false is returned, the current model build did not estimate angles for this face. Fall back to a visual check — the subject should be looking close to the camera, not in profile.

Lighting

ConditionEffect
Even, diffuse, front-of-face lightBest.
Single hard light from one sideHalf the face goes dark — embedding becomes that lighting, not that person.
Backlit (window behind subject)Face goes silhouette — brightnessScore plummets.
Heavy shadows under eyes / noseHides landmarks the detector aligns on.
Direct overhead lightEye sockets shadow over; reduces sharpness on the most identifying region.

Aim for a setup the operator can replicate every day. Inconsistent lighting across captures of the same person degrades the embedding average over time.

Capture distance and lens

SetupOutcome
Smartphone selfie, ~50 cmGood. Plenty of resolution; minor lens distortion.
Webcam, ~60 cmUsually fine if the webcam is ≥ 720p.
Surveillance camera, > 3 m, wide-angleOften produces sub-112-pixel face crops. Re-crop closer or use a higher-resolution stream.
Phone camera at arm's length, ultra-wide lensWide-angle distortion stretches face features. Use the standard lens.

Multiple references per identity

Identify scores the probe against every reference attached to a subject and reports the highest. The more reference embeddings a subject has, covering more poses / lighting / expressions, the more chances any single probe has to score above your match threshold.

Reference 1: frontal, even indoor light.

Reference 2: slight angle, same room.

Reference 3: different lighting.

Reference N: later capture, different day.

Multiple references for one externalId. Identify returns the max score across all of them — so a probe only needs to match one reference well to surface.

Add a new reference by calling biofrq.enroll again with the same externalId and mode: "addReference". The service attaches the new reference to the existing subject; identify takes the maximum across all of them.

json
{
  "action": "biofrq.enroll",
  "params": {
    "externalId": "emp-4421",
    "groupName": "employees",
    "mode": "addReference",
    "images": [ { "kind": "image", "bytes": "...base64..." } ]
  }
}

Default mode is "create", which rejects a repeat externalId with CONFLICT — that's the right behaviour for first enrolment, not for adding references. forceEnroll: true is a different flag: it only bypasses the duplicate-face dedup gate (the check that prevents enrolling the same person twice under different externalIds); it does not change the create-vs-add behaviour. Use both flags together only when you're adding a reference to an existing person whose new image happens to sit very close to another subject's embedding.

When to add a reference:

  • The subject's appearance changes meaningfully — new haircut, glasses, weight change, beard.
  • You captured a higher-quality image than the original.
  • Identify on a known-correct probe scores below your match threshold — the existing reference no longer represents the person well.

Common pitfalls

PitfallSymptomFix
Re-enrolling the same low-quality cropReference stays poor; identify keeps under-scoring.Capture a fresh frame at higher resolution; gate on quality.
Enrolling from CCTV crops without re-croppingfacePixelWidth < 100, identify fails on most probes.Pull from a higher-resolution stream, or capture the enrolment image out-of-band (phone, kiosk).
Surveillance frame with two peopleMULTIPLE_FACES_DETECTED.Crop to a single face before submitting.
Sunglasses or face mask on enrolmentEmbedding represents the obstruction, not the person.Require an unobstructed reference.
Profile / 90° turnDetector may pass but pose is unrecoverable for identify.Re-capture frontal.
Mixing operator devices for the same personInconsistent colour and white balance shift the embedding.Standardise the capture device per site.

Checklist before enrolling

□  Subject is looking close to the camera (not profile)
□  Eyes, nose, mouth, chin, forehead all visible
□  No sunglasses, no face mask, no hand covering the face
□  Even lighting on both sides of the face
□  Face fills 60-80% of the shorter dimension of the frame
□  detect returned faceBoxConfidence >= 0.85
□  detect returned overallScore >= 0.80
□  detect returned facePixelWidth >= 112
□  No motion blur (sharpnessScore >= 0.40)
□  Exposure looks right (brightnessScore >= 0.35)
□  pose within ±20° (when poseSupported is true)

If every box is checked, submit biofrq.enroll. If any box fails, re-capture; don't lower the bar.

What's next