<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pankaj Ashok Magadum</title>
    <description>The latest articles on DEV Community by Pankaj Ashok Magadum (@pmagadum).</description>
    <link>https://dev.to/pmagadum</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4245255%2F7acd27bb-4ed7-41ab-8f79-d2d39ffcb559.png</url>
      <title>DEV Community: Pankaj Ashok Magadum</title>
      <link>https://dev.to/pmagadum</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pmagadum"/>
    <language>en</language>
    <item>
      <title>Unmute: reading silent lips for ICU patients who can't make a sound (offline, on a laptop)</title>
      <dc:creator>Pankaj Ashok Magadum</dc:creator>
      <pubDate>Sun, 15 Nov 2026 17:27:52 +0000</pubDate>
      <link>https://dev.to/pmagadum/unmute-reading-silent-lips-for-icu-patients-who-cant-make-a-sound-offline-on-a-laptop-ji4</link>
      <guid>https://dev.to/pmagadum/unmute-reading-silent-lips-for-icu-patients-who-cant-make-a-sound-offline-on-a-laptop-ji4</guid>
      <description>&lt;p&gt;After a tracheostomy or throat surgery, an ICU patient can be awake, alert, and completely silent. A tube in the neck means no air reaches the voice box. But their lips still move. So they mouth words at the nurse, and the nurse guesses. "Water? Pain? Your family?" When the guess is wrong, the patient tries again, gets tired, and gives up.&lt;/p&gt;

&lt;p&gt;We spent HackUMass building Unmute: an ordinary laptop on the bed table that reads those silent lips, says the sentence out loud, and gets the nurse when it matters. No setup, no internet, no special hardware.&lt;/p&gt;

&lt;p&gt;What we Built&lt;br&gt;
The patient silently mouths a sentence at the laptop camera. Unmute shows the 3 most likely of 20 bedside sentences as big cards ("I need water", "I am in pain", "Call my family", "I cannot breathe"...). The patient confirms one with whatever they can still move, and the laptop speaks it.&lt;/p&gt;

&lt;p&gt;No calibration for a new patient. An open-source lip reader plus other people's recordings works from minute one.&lt;br&gt;
Confirm with a touch, a nod, one switch, or a long blink. The nurse sets it up with one question: "What can this patient do?" There's also a hands-free mode: recording starts when the lips move and stops when they rest.&lt;br&gt;
Urgent sentences don't wait. When the lip reader is sure the patient said "I cannot breathe", a 2-second countdown starts. Then the screen turns red, an alarm sounds, and the nurse's phone buzzes, unless the patient stops it. A misread alarm is cancelled with one tap, and the nurse is told.&lt;br&gt;
Always a way out. A draggable touch button opens every sentence as a big button. Every correction is saved as a sample of the patient's own lips, so the mistake teaches it.&lt;br&gt;
The video never leaves the laptop. The server listens on 127.0.0.1 only. With Wi-Fi off, everything still works except the phone push.&lt;br&gt;
How it works&lt;br&gt;
camera&lt;br&gt;
  -&amp;gt; MediaPipe face tracking, in the browser (~108 numbers per frame + a small mouth crop)&lt;br&gt;
  -&amp;gt; local FastAPI server (127.0.0.1 only)&lt;br&gt;
       -&amp;gt; DTW matcher over everyone's recordings&lt;br&gt;
       -&amp;gt; Auto-AVSR lip reader on the laptop's GPU (PyTorch, Apple MPS)&lt;br&gt;
       -&amp;gt; blend -&amp;gt; top 5 -&amp;gt; Gemini reorders using bedside context (optional, text only)&lt;br&gt;
  -&amp;gt; 3 cards -&amp;gt; touch / nod / switch / blink&lt;br&gt;
  -&amp;gt; spoken aloud + Nurse page + ntfy push to the nurse's phone (urgent only)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A matcher with no training. Every recording becomes a template: a sequence of lip shapes, centred on the mouth, head tilt removed, scaled by eye distance. A new recording is compared with every template by dynamic time warping, so mouthing fast or slow doesn't matter. Every sentence the patient confirms becomes a new template, so it learns their lips (swollen, taped, lopsided) just from being used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A real lip reader, asked the right question. Auto-AVSR (Imperial College London, Apache 2.0) is a 250M-parameter model trained on 3,291 hours of video. It runs offline on the laptop's GPU. The trick that made it work for us: don't ask it "what did they say?" Ask it "how likely is each of these 20 sentences?" Scoring a fixed list (decoder + CTC) was far more reliable than free-text transcription. We blend the two:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;log P(phrase) = w · log P_lipreader + (1 − w) · log P_matcher        (w = 0.25, measured)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gemini as a careful second opinion. Gemini gets the top 5 candidates, the time of day, the last 5 requests, and an optional care note ("post-surgery, nil by mouth"). It may reorder them to break near-ties. It may not invent a sentence. In testing, it once dropped "I need water" because water had "just been given". So the safety rule lives in code, not in the prompt:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;must = []&lt;br&gt;
for c in [candidates[0]] + [c for c in candidates[:3] if c["phrase"] in URGENT]:&lt;br&gt;
    if c["phrase"] not in must:&lt;br&gt;
        must.append(c["phrase"])&lt;br&gt;
for m in must:&lt;br&gt;
    if m in out:&lt;br&gt;
        continue&lt;br&gt;
    for i in range(len(out) - 1, -1, -1):  # replace Gemini's lowest pick that isn't protected&lt;br&gt;
        if out[i] not in must:&lt;br&gt;
            out[i] = m&lt;br&gt;
            break&lt;br&gt;
The lip reader's top match, and any urgent sentence it put in its top 3, can never be removed. If Gemini takes more than 3 seconds, or there's no network, Unmute uses the lip-reading order and shows an "offline mode" badge.&lt;/p&gt;

&lt;p&gt;Demo&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/DGXa0fMd8vI" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Code: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/2004Hrishikesh" rel="noopener noreferrer"&gt;
        2004Hrishikesh
      &lt;/a&gt; / &lt;a href="https://github.com/2004Hrishikesh/unmute" rel="noopener noreferrer"&gt;
        unmute
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Unmute&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Unmute helps hospital patients who can't make a sound, such as ICU patients with a breathing tube or a tracheostomy, talk again.&lt;/strong&gt;
The patient silently mouths a sentence at a laptop camera. Unmute reads their lips and shows the 3 most likely
sentences. The patient nods to confirm one and the laptop says it out loud. Urgent requests ("I cannot breathe") turn
the screen red and buzz the nurse's phone.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The one tool that exists understands 40 fixed phrases. Patients have more to say than that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unmute is a communication aid. It is not a medical device and it does not diagnose anything.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt; Browser (web/)                                         Python backend (server/, FastAPI)
 ┌──────────────────────────────────────┐               ┌───────────────────────────────────────────┐
 │ webcam → MediaPipe Face Landmarker   │   frames of   │ /api/predict                              │
 │   per frame: 28 mouth blendshapes +  │   numbers     │   z-normalise with this user's stats      │
 │   40 lip points (centred, de-rolled, │&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/2004Hrishikesh/unmute" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The numbers (measured, not guessed)&lt;br&gt;
We tested on people the system had never seen, with no calibration: 240 silent recordings of the 20 sentences. Chance is 5% for the first card and 15% for the 3 cards.&lt;/p&gt;

&lt;p&gt;Brand-new patient, no calibration   First card  In the 3 cards&lt;br&gt;
Matcher alone (other people's recordings)   37.9%   65.0%&lt;br&gt;
Lip reader alone, zero-shot 66.7%   83.3%&lt;br&gt;
Lip reader + matcher (what ships)   71.3%   87.1%&lt;br&gt;
After the patient has used it + lip reader  78.3%   93.8%&lt;br&gt;
The automatic alarm fired on about 6 in 10 urgent sentences, and wrongly on 1 of 180 others. Caveats, said out loud: only 2 people in that test, and the blend weight was picked on those same recordings.&lt;/p&gt;

&lt;p&gt;Partner Technologies&lt;br&gt;
Google Gemini API. Gemini is the bedside-context layer: it turns "the lips look like water or cold" into the right first card when the care note and the last few requests make one more likely. Things that mattered in practice:&lt;/p&gt;

&lt;p&gt;Structured output, then distrust it. Gemini answers in JSON, and every choice is checked against the candidate list before anything reaches the screen.&lt;br&gt;
Free-tier reality. Free keys can get as few as 20 requests a day per model. The server lists the Flash models the key can use (this costs no quota) and prefers the fast "lite" ones: about 0.5–1.3 s per call, against 1.3–7 s for the full models. A model that returns 429, 503, or 404 rests (until its quota resets, 60 s, or a week), and the next one is tried within the same 3-second budget.&lt;br&gt;
Optional by design. The core path, lips to cards to speech, never waits on the network. A test captures everything sent to Gemini and checks that it holds no picture, no face numbers, and no name.&lt;br&gt;
Hackathon Experience&lt;br&gt;
Our git log tells the story better than we can:&lt;/p&gt;

&lt;p&gt;Saturday 13:32: the whole pipeline worked end to end: calibrate, recognise, Gemini, nod, alert. Accuracy: 19% first card, with chance at 10%.&lt;br&gt;
15:15: centre each recording on its own mean, add lip velocity, trim still frames. 19% → 40%. Then a hubness correction (it stops short phrases like "Yes" from soaking up wrong answers) took it to 47.5%.&lt;br&gt;
17:22: the question that changed the design: "A sick patient can't sit through calibration." We made a shared starter model over everyone's recordings, and learning from every confirmed sentence.&lt;br&gt;
20:21: we trained our own small neural network on volunteers' recordings. With 2 people it beat the matcher. With 4, measured leave-one-person-out, it didn't, so our training script switched it off by itself. It hurt, and it was the right call.&lt;br&gt;
20:38: Auto-AVSR running on the laptop GPU. Nobody could tell us if a model trained on people talking would read silent mouthing. So we measured it: 83.3% in the 3 cards, zero-shot.&lt;br&gt;
21:17 → 23:02: our own rule for showing the lip reader's free text was wrong. It would have put a wrong sentence on card 1 in 124 of 240 recordings, because its reading is usually a near miss ("called my family"). The new rule hides near misses: 4 of 240.&lt;br&gt;
Sunday 02:23: urgent sentences raise the alarm by themselves when the lip reader is sure.&lt;br&gt;
What we'd tell another team:&lt;/p&gt;

&lt;p&gt;Test on people your model has never seen. Testing on the same person flattered every number we had.&lt;br&gt;
Ask a big model to choose, not to generate. "Which of these 20?" beat "what did they say?" by a mile.&lt;br&gt;
Put the LLM where it's safe, and write the safety rule in code, not in the prompt.&lt;br&gt;
Accessibility is the last step. For a weak patient, picking a card is harder than the AI is for us.&lt;br&gt;
Measure the thing that proves you wrong. Two of our proudest moments were numbers that killed our own ideas.&lt;br&gt;
What's next&lt;br&gt;
Test with speech-language pathologists and real tracheostomy patients, record more volunteers, add sentences the care team can set for each patient, and connect to hospital nurse-call systems.&lt;/p&gt;

&lt;p&gt;Unmute is a communication aid. It is not a medical device, and it does not diagnose anything.&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
