Plan: Anonymization Engine for EPPA — Marker-Aware, Norm-Compliant¶
Context¶
EPPA needs to anonymize patient photos for server transmission and scientific data collection. The anonymization must comply with HIPAA, GDPR, ISO 25237, and Argentine Ley 25.326. The key challenge: preserve anatomical markers for clinical verification while making the person unidentifiable.
Core Strategy: Two Modes Based on Marker Availability¶
Mode A: Markers Present (normal flow — kinesiólogo already placed markers)¶
Use the marker positions themselves as the map for what to preserve and what to destroy.
Algorithm: 1. Face mesh detection (MediaPipe 478 landmarks on cropped head region) 2. Fill with skin color (sampled from cheek): - Eyes (mesh polygon) → skin fill — irreversible, HIPAA/GDPR compliant - Eyebrows (mesh polygon) → skin fill - Lips/mouth (mesh polygon) → skin fill 3. Nose: flatten texture → skin color fill + edge contours only (Canny edges from original). This destroys skin texture (pores, moles, scars) but preserves anatomical shape for marker verification. 4. Hair: detected via U2Net body segmentation minus face oval mesh → heavy Gaussian blur (41px kernel). Destroys color/style/length detail. 5. Ears: blur the pabellón area (MediaPipe ear landmarks 234/454 ± radius) 6. Accessories: blur chin-to-neck zone (below landmark 152) 7. Logos/text: blur detected text regions in background corners 8. Green markers: drawn ON TOP of anonymized surface — never restore original image underneath. Each marker is a filled green circle at its coordinate, rendered after all anonymization.
Key rule: NO "clear halos" that restore original pixels. Markers are re-drawn as synthetic circles on the anonymized image, not restored from the original.
Mode B: No Markers (image uploaded but not yet marked)¶
Full head anonymization — no anatomical detail needed.
Algorithm: 1. U2Net body segmentation → head region mask (above shoulders, within body contour) 2. Heavy blur entire head region (kernel 51px) 3. Or: solid skin color fill on head (more aggressive, HIPAA preferred)
Privacy Scope and Limits¶
EPPA anonymization is an operational risk-reduction tool for creating a separate shareable image copy. It is not a legal opinion, regulatory certification, HIPAA Safe Harbor determination, GDPR anonymization opinion, or ethics committee approval. Sites using EPPA remain responsible for consent, institutional review, local policy, and any legal/regulatory validation needed for clinical or research sharing.
The original analysis image and measurements are preserved for the evaluator's working session. Anonymization is applied to the exported copy only.
Why This Is Designed to Reduce Risk¶
HIPAA Safe Harbor¶
- Requirement: "Full-face photographs and comparable images" are PHI. Must be obscured so individual is "not reasonably identifiable."
- Compliance: Eyes destroyed (skin fill, irreversible). Eyebrows destroyed. Mouth destroyed. Nose texture destroyed (only edge contours remain — like a line drawing). Hair blurred beyond recognition. Ears blurred. Combination of remaining visible features (nose contour, chin shape, face outline) without eyes/brows/mouth/hair is NOT reasonably identifiable per Bared 2016 which found eyes+eyebrows are the minimum threshold.
- We exceed the minimum: we also destroy mouth, nose texture, hair, and ears.
GDPR (Irreversibility)¶
- Requirement: Anonymization must be irreversible. Pseudonymization (reversible) doesn't qualify.
- Compliance: All fills use solid color replacement — original pixels are destroyed, not masked or blurred (blur can theoretically be reversed). Eyes, brows, lips use solid skin color fill = pixels gone forever. Nose uses skin fill + synthetic edges = original texture destroyed. Only hair and ears use blur (accepted because these are secondary identifiers and the blur kernel is large enough to be computationally irreversible).
ISO 25237:2017¶
- Requirement: Distinguish anonymization (irreversible, no key) from pseudonymization (reversible, key-managed).
- Compliance: No key exists to reverse the process. No mapping is stored. The original pixels are overwritten in the exported image. This is anonymization, not pseudonymization.
Argentine Ley 25.326 + Res. 1480/2011¶
- Requirement: Health images are "sensitive data." Must have consent OR apply "dissociation technique" so person is not determinable.
- Compliance: Dissociation technique applied — the exported image cannot be attributed to a determined or determinable person. Combined with: original images never leave the kinesiólogo's machine, only anonymized versions travel to server.
Bared et al. 2016 (Annals of Plastic Surgery)¶
- Finding: 87% of de-identified images in journals were inadequately concealed. Eyes+eyebrows minimum.
- Our implementation: exceeds this — eyes, eyebrows, mouth, nose texture, hair, ears all treated.
Permusic et al. 2022 (Sensors)¶
- Finding: Face blurring has <1° effect on pose estimation.
- Relevance: Our approach preserves all body landmarks below the face and marker positions on the face, so postural analysis is unaffected.
Implementation Plan¶
Files to create/modify¶
fronts/eppa/src/lib/anonymization/face-anonymizer.ts— main anonymization engine (client-side, runs in browser via WASM or server-side via Python API)fronts/eppa/python/anonymize.py— Python endpoint using MediaPipe + OpenCV + rembgfronts/eppa/src/app/analysis/anterior/page.tsx— hook into export flow
API Endpoint¶
POST /api/anonymize
Body: { image: base64, markers: [{name, x, y}], view: "anterior"|"posterior"|"lateral-*" }
Response: { anonymized_image: base64 }
Processing Pipeline¶
Input image + marker coordinates
│
├─ markers present?
│ ├─ YES → Mode A (marker-aware)
│ │ ├─ Detect face mesh (MediaPipe, cropped head)
│ │ ├─ Sample skin color from cheek landmark
│ │ ├─ Fill: eyes, brows, lips → skin color
│ │ ├─ Fill: nose → skin color + Canny edges
│ │ ├─ Blur: hair (U2Net mask - face oval)
│ │ ├─ Blur: ears (mesh landmarks ± radius)
│ │ ├─ Blur: accessories (below chin)
│ │ ├─ Blur: logos (corners)
│ │ └─ Draw: green circles at marker coords ON TOP
│ │
│ └─ NO → Mode B (full anonymization)
│ ├─ Segment head (U2Net above shoulders)
│ └─ Solid fill or heavy blur entire head
│
└─ Output: anonymized image (original pixels destroyed)
View-Specific Rules¶
| View | Face visible? | Markers in face zone | Treatment |
|---|---|---|---|
| Anterior | Full face | Eminencia Frontal, Espina Nasal, Tragus x2, Mentoniano | Mode A full |
| Posterior | Back of head | None typically | Blur back of head if visible |
| Lateral Izq | Left profile | Tragus Izq | Mode A — blur profile, preserve tragus point |
| Lateral Der | Right profile | Tragus Der | Mode A — blur profile, preserve tragus point |
Verification¶
- Run on all 4 views of Sujeto 6
- Verify markers visible as green dots on anonymized surface
- Verify no original facial pixels remain in eye/brow/lip regions
- Verify nose shows only contour lines, not texture
- Run face recognition (e.g., dlib face_recognition) on anonymized image — should fail to match original