Facial maps
They are two different documents, and confusing them is the most common mistake about facial reading. The first is the dictionary of facial movement; the second is the grammar that combines those movements. Here they sit side by side — and beside each one is what FROID's engine actually computes from it.
The distinction
Both show the same face and use the same numbers — AU1, AU4, AU12. But they answer questions that do not substitute for each other.
Question it answers: what is each possible facial movement, on its own?
Each Action Unit (AU) is a named muscle or muscle group with an observable movement and nothing more. AU4 is the lowering of the brows (corrugator, procerus). AU12 is the upward pull of the lip corners (zygomaticus major). These are dictionary entries: none of them means an emotion, just as no single word is a sentence.
Question it answers: which AU combinations does the FACS literature associate with each emotion and each dissonance?
Here the dictionary entries become sentences. AU6+AU12 is the Duchenne smile; AU23+AU24 is the lip compression of contained hostility; AU1+AU2+AU5 is the startle signature of fear. This is the grammar — and any reading comes from it, because the combination carries meaning the single part does not.
Map 1 · The unit-by-unit explainer
The Facial Action Coding System, by Paul Ekman and Wallace Friesen, decomposes facial movement into anatomical units. The map below is the full catalogue of those units — including the ones FROID does not compute. Click to enlarge.
The patient's browser runs the MediaPipe FaceLandmarker model (ARKit) on the local video and produces 52 blendshape coefficients — values from 0 to 1 describing facial deformations. Only those 52 numbers travel: no image, no video frame, and no facial landmark leaves the clinician's equipment.
On the server, each Action Unit is the simple mean of the blendshapes that compose it. When an AU has a left and a right counterpart, both sides are averaged to give the bilateral intensity. An AU counts as active from 0.30 upward.
| AU | FACS name | Muscle | Movement | Blendshapes that compose it |
|---|---|---|---|---|
| AU1 | Inner Brow Raiser | Frontalis (pars medialis) | Raising of the inner brows | browInnerUp |
| AU2 | Outer Brow Raiser | Frontalis (pars lateralis) | Raising of the outer brows | browOuterUpLeft · browOuterUpRight |
| AU4 | Brow Lowerer | Corrugator, Depressor supercilii, Procerus | Lowering and drawing together of the brows | browDownLeft · browDownRight |
| AU5 | Upper Lid Raiser | Levator palpebrae superioris | Raising of the upper eyelid, exposing the sclera | eyeWideLeft · eyeWideRight |
| AU6 | Cheek Raiser | Orbicularis oculi (pars orbitalis) | Raising of the cheeks and crow's feet | cheekSquintLeft · cheekSquintRight |
| AU7 | Lid Tightener | Orbicularis oculi (pars palpebralis) | Tightening of the eyelids | eyeSquintLeft · eyeSquintRight |
| AU9 | Nose Wrinkler | Levator labii sup. alaeque nasi | Wrinkling of the nose and raising of the nostril wings | noseSneerLeft · noseSneerRight |
| AU10 | Upper Lip Raiser | Levator labii superioris | Raising of the upper lip | mouthUpperUpLeft · mouthUpperUpRight |
| AU12 | Lip Corner Puller | Zygomaticus major | Upward pull of the lip corners (smile) | mouthSmileLeft · mouthSmileRight |
| AU14 | Dimpler | Buccinator | Lip corners drawn inward (dimples) | mouthDimpleLeft · mouthDimpleRight |
| AU15 | Lip Corner Depressor | Depressor anguli oris | Lowering of the lip corners | mouthFrownLeft · mouthFrownRight |
| AU17 | Chin Raiser | Mentalis | Raising of the chin skin | mouthShrugLower · mouthShrugUpper |
| AU20 | Lip Stretcher | Risorius + Platysma | Horizontal stretching of the lips | mouthStretchLeft · mouthStretchRight |
| AU23 | Lip Tightener | Orbicularis oris | Narrowing and tensing of the lips | mouthRollLower · mouthRollUpper |
| AU24 | Lip Pressor | Orbicularis oris | Pressing of the lips against each other | mouthPressLeft · mouthPressRight |
| AU26 | Jaw Drop | Masseter relaxation | Dropping of the jaw | jawOpen |
The remaining 11 appear on the map and are not computed: AU8, AU11, AU13, AU16, AU18, AU19, AU21, AU22, AU25, AU27, and AU28. Neither are the Action Descriptors (AD) — gaze direction, blink, head tilt and rotation. The reason is the same in every case: MediaPipe's 52-blendshape set exposes no coefficient corresponding to those units with sufficient fidelity, and deriving them by approximation would produce a number where no measurement took place.
Four of the 16 computed — AU9, AU17, AU20, and AU26 — are measured every frame and today enter no composition rule. They exist in the computation and have no reader yet. It is recorded here because the alternative would be for this page to suggest that every computed AU takes part in the reading, and it does not.
Map 2 · The composition explainer
A single AU sustains no reading. What sustains one is co-occurrence: which units appear together, at what intensity, and whether they appear on both sides of the face or on only one. Click to enlarge.
At each facial reading, the engine checks the active AUs against six composition rules. Every rule that fires marks facial dissonance in one of the 12 Perception Zones and writes, on the professional's screen, which AUs fired it and what that pattern describes. Dissonance has a precise meaning here: the face contradicting or masking the affect — the co-occurrence of units that should not be together.
| Zone | Required combination | Pattern FROID records |
|---|---|---|
| Zone 3 | AU15 and AU12 | Masked sadness — depression of the lip corners under an effort to smile: negative affect covered over. Zone 3 — Sadness vs. Inner Peace |
| Zone 6 | AU14 active with asymmetry ≥ 0.25, or AU10 active with an asymmetric smile (AU12) ≥ 0.25 | Contempt — unilateral facial expression: masked affective distancing. It is the engine's only reading that depends on one side of the face differing from the other. Zone 6 — Conditional vs. Unconditional Love |
| Zone 7 | AU12 and (AU23 or AU24) | Aversion suppression — a social smile laid over involuntary lip compression: the face masks hostility. Zone 7 — Anger vs. Acceptance of Change |
| Zone 8 | AU1 and AU2 and AU5 | Contained fear — the brow-and-eyelid startle signature during controlled speech. Zone 8 — Fear and Overload vs. Accountability |
| Zone 9 | AU23 and AU24 and global expressivity < 0.20 | Expressive suppression — pressed, tense lips on a flattened face: holding back what would be said. Zone 9 — Suppressed Emotional Expression vs. Adequate Self-Expression |
| Zone 12 | AU4 and AU7 | Internal conflict — contracted brows with tensed eyelids: incongruence between speech and state. Zone 12 — Conflicting vs. Congruent Beliefs and Actions |
"Active" means intensity ≥ 0.30. The global expressivity in Zone 9 is the mean intensity of AU1, AU2, AU5, AU6, AU12, and AU15 — the emotional AUs. AU26 (jaw drop) is deliberately excluded from that mean because it is driven by speech, not emotion: including it inflated expressivity during talking and masked restraint exactly when it matters most.
Both thresholds are FROID product parameters, chosen as a conservative presence band over the 0–1 scale of ARKit blendshapes — they are not constants published in the FACS literature. Treat them as calibratable engineering heuristics.
The intensity assigned to a dissonance is the minimum among the AUs that compose it (the weakest one bounds the evidence); in Zone 6, the maximum between AU14 and AU10. When two rules compete for the same zone in the same frame, the higher intensity prevails — a zone holds one pattern only. The intensity is internal: it serves that prioritization and is not published in the payload, which exposes the active AUs, the pattern text, and the provenance.
No blendshapes, no AU; no AU, no facial dissonance — and the facial fields come out null with the provenance declared. There is no simulated mode: the generator was removed on 2026-09-03, and absence of measurement never becomes a number.
froid-server/froid_facs.py (conversion and rules) and froid-dashboard/src/lib/froid-face.ts (browser capture).The full chain
Seven steps separate the patient's face from a mark on the professional's panel. None of them invents a value: where no measurement occurred, the chain stops and declares that it stopped.
The model runs locally on the patient's video and produces the blendshapes. Only the coefficients are sent — image and video never leave the equipment.
Simple mean per AU, left and right sides averaged, asymmetry kept separately for AU12 and AU14.
Intensity ≥ 0.30. Below that the AU exists as a number and does not count as present — the threshold is there to discard involuntary micro-movement.
Active AUs are checked against the six combinations. Each firing marks facial dissonance in a Perception Zone.
In a marked zone, that zone's acoustic deviation is multiplied by 2.5. This is where — and only where — face and voice meet: the face does not generate a reading on its own, it weights the vocal reading.
A single-cycle spike does not become a record. Dissonance is only given as confirmed when it holds across 2 of the last 3 analysis cycles.
Binary form — there is no continuous form implemented. The 2.5 value is a FROID product parameter, not derived from a published study.
The dissonance engine receives the deviation without M_fac. Without that separation, a single facial event would fire both the facial marker and the extreme-zone marker at once — double-counting one signal, correlated by construction, inflating the confidence of the alert.
The facial reading runs at about 3 frames per second by default (minimum interval of 150 ms). It is a cadence chosen so as not to compete with audio processing or with the video call, and it bounds what is observable: see What these maps do not claim.
froid-server/froid_core.py → calculate_multimodal_deviation(). Temporal confirmation in froid-server/froid_dissonance.py. The assembly of IDM and IPM is in Technology, Step 5.The boundary
A reference map shows what FACS describes. It is not an inventory of what this software does. Where the two diverge, what stands is what is written here.
The composition map lists seven universal emotions. FROID emits none of them as a result. There is no "happiness", "surprise", or "disgust" output anywhere in the product. What comes out is a dissonance mark per zone, with the AUs that produced it. The happiness, surprise, and disgust matrices are on the chart as FACS reference and have no corresponding rule in the engine.
The three temporal phases of an expression — start, peak, and end — are a mature methodology in computer vision, and FROID does not implement them. There is no Markov model, no apex confidence, no AU duration. Each frame is evaluated on its own; the system's only temporal memory is the confirmation of dissonance across 2 of the last 3 cycles.
A microexpression lasts between 1/25 and 1/5 of a second. FROID's facial capture runs at about 3 frames per second — most of a microexpression fits between two frames. The cadence is an engineering choice, and this is its consequence: microexpressions are not an object of measurement in this system.
Dissonance is the co-occurrence of facial units that rarely travel together, crossed with the acoustic deviation of the same zone. It is a signal for the professional to look at, not a verdict on sincerity. The classic Duchenne smile hypothesis (AU6 absent = forced smile) is contested by recent research — see Science, Pillar 4.
The composition map highlights four patterns of subconscious dissonance. Set against the six implemented rules:
The divergence is published rather than corrected in the figure because the chart is a FACS document with value of its own as a reference. What must not happen is a reader leaving here believing that each box on the map corresponds to a behavior of the software.