Face-Glow Overlay
Draw the thermal face-mesh glow on the live camera with circadify.ui.render_face_glow, then build your own scan UI around it.
circadify.ui ships the camera / face-glow pipeline — the thermal face-mesh glow that makes a Circadify scan recognizable — and nothing else of the UI. You render the glow on each captured frame with render_face_glow, get the frames from the on_frame callback, and build whatever window, sidebar, or web view you want around it.
This mirrors how the Web and iOS SDKs expose their glow as a presentation layer over a headless core — except in Python you own the surrounding UI, so the glow drops cleanly into a desktop window, a Streamlit app, a Jupyter notebook, or a web stream. A complete example window (camera + glow + a vitals/quality/progress sidebar) lives in demo_gui.py in the Python SDK test app.
render_face_glow(...)
Draw the thermal glow onto a frame, in place, then display it however you like:
import cv2
from circadify import CircadifyClient
from circadify.ui import render_face_glow
def on_frame(ev):
bgr = cv2.cvtColor(ev.rgb, cv2.COLOR_RGB2BGR) # on_frame gives RGB
render_face_glow(bgr, ev.landmarks, t=ev.collected / 30.0,
scanning=(ev.phase.value == "capturing"))
cv2.imshow("scan", bgr)
cv2.waitKey(1)
client = CircadifyClient(api_key="ck_live_your_key_here", on_frame=on_frame)
result = client.measure_vitals()
print(result.heart_rate, result.confidence)python| Parameter | Type | Default | Description |
|---|---|---|---|
frame_bgr | numpy.ndarray | — | Required. A BGR uint8 [H, W, 3] image (OpenCV-native). on_frame gives RGB — convert first with cv2.cvtColor(ev.rgb, cv2.COLOR_RGB2BGR). |
landmarks | Sequence[(x, y)] | None | — | Required. Per-vertex pixel coordinates aligned to frame_bgr (from ev.landmarks; ≥468 points). Scale them if you resized the frame. None/too few → no-op. |
t | float | 0.0 | Time in seconds — drives the forehead→cheek sweep animation. |
scanning | bool | True | True during capture (brighter); False for the calmer idle look. |
theme | GlowTheme | THERMAL | The thermal color ramp. See Recoloring. |
Returns the same frame_bgr array with the glow composited in. When no face is detected (landmarks is None or has fewer than 468 points) the frame is returned unchanged.
render_face_glow is a pure render helper — no window, no global state. It works anywhere you can show a NumPy image: a cv2 window, Streamlit st.image, a Jupyter cell, an MJPEG/JPEG web stream, or a Qt QImage.
What the glow looks like
- The full 468-point / 880-triangle MediaPipe face mesh.
- A 4-stop thermal ramp (amber → orange → red core) that sweeps region-by-region across the forehead and cheeks while capturing.
- Face-bbox-normalised, so it looks the same whether the face fills the frame or not.
It faithfully reproduces the Web SDK's heat-glow shader.
Recoloring
Pass a GlowTheme to change the ramp (colors are BGR, OpenCV-native):
from circadify.ui import GlowTheme, render_face_glow
# A cool cyan ramp instead of the default thermal one (BGR tuples).
cool = GlowTheme(glow_core=(255, 230, 80), glow_hot=(255, 210, 80),
glow_warm=(230, 180, 70), glow_cool=(200, 150, 60))
render_face_glow(bgr, ev.landmarks, t=t, theme=cool)pythonGlowTheme holds the four ramp stops glow_core / glow_hot / glow_warm / glow_cool. The default instance is THERMAL.
Build a full window
The SDK deliberately doesn't ship a window or sidebar — you own those. The test app's demo_gui.py is a complete, copy-pasteable example: it runs measure_vitals on a worker thread, composites the camera + render_face_glow + a vitals/quality/progress sidebar with OpenCV on the main thread, and handles cancellation. Use it as a starting point for a desktop tool, or adapt the on_frame pattern above for a web/Streamlit/Qt front end.
Requirements
render_face_glow needs the [camera] extra (pip install "circadify[camera]", for OpenCV). It is a pure draw call — no display required — so it also runs headless (server, notebook, web backend); just show the returned frame however your stack does. Only the live camera capture (measure_vitals) needs an actual webcam.
Next Steps
- Camera & Input — webcam, video files, and your own frames feeding the same engine.
- Methods — the
on_framecallback and the rest ofCircadifyClient. - Configuration — callbacks and capture options.