<?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: Ankita</title>
    <description>The latest articles on DEV Community by Ankita (@ankita562).</description>
    <link>https://dev.to/ankita562</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%2F4156633%2F667b8360-b0d7-47c6-a94e-5e1595956c5e.jpg</url>
      <title>DEV Community: Ankita</title>
      <link>https://dev.to/ankita562</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ankita562"/>
    <language>en</language>
    <item>
      <title>I Built a Ghost That Shows You Your Future as a Comic Book (100% on My Laptop, Wi-Fi Off) 🎃🕯️</title>
      <dc:creator>Ankita</dc:creator>
      <pubDate>Sun, 01 Nov 2026 05:56:06 +0000</pubDate>
      <link>https://dev.to/ankita562/i-built-a-ghost-that-shows-you-your-future-as-a-comic-book-100-on-my-laptop-wi-fi-off-35oa</link>
      <guid>https://dev.to/ankita562/i-built-a-ghost-that-shows-you-your-future-as-a-comic-book-100-on-my-laptop-wi-fi-off-35oa</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week4-2026-10-26"&gt;Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On Día de los Muertos, we build an &lt;em&gt;ofrenda&lt;/em&gt; for the people we miss. I wondered what it would look like to build one for a &lt;strong&gt;future that hasn't happened yet&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ofrenda of Maybe&lt;/strong&gt; turns a wish into a comic book, entirely on my own laptop.&lt;/p&gt;

&lt;p&gt;You whisper a future you hope for ("I have a big garden full of sunflowers and a small cottage in the hills"), and the app gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📖 &lt;strong&gt;A 4-panel comic page.&lt;/strong&gt; Three panels tell your wish as a cheerful cartoon story.&lt;/li&gt;
&lt;li&gt;👻 &lt;strong&gt;A ghost panel.&lt;/strong&gt; The ghost is &lt;em&gt;you, from that future&lt;/em&gt;. It remembers the very first small step that started it all.&lt;/li&gt;
&lt;li&gt;🕯️ &lt;strong&gt;The ghost's offering:&lt;/strong&gt; one small, real thing you can do today. My favorite so far: &lt;em&gt;"Buy one sunflower seed today."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;🎬 &lt;strong&gt;A narrated film&lt;/strong&gt; of the same story, with four narrator voices (including a ghostly whisper).&lt;/li&gt;
&lt;li&gt;🎃 &lt;strong&gt;A Halloween UI:&lt;/strong&gt; cobwebs, a dangling spider, a flickering title, and a ghost that may &lt;strong&gt;jump out while you type&lt;/strong&gt; (you can switch it off in Settings).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I took the theme two ways at once. &lt;em&gt;Halloween&lt;/em&gt; is the spooky wrapper (the ghost, the webs, the jump scare). &lt;em&gt;Día de los Muertos&lt;/em&gt; is the heart: an offering, a way of remembering, but pointed at the future instead of the past. The "ghost in the machine" here is a friendly one, a future you living inside a model on your own GPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

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

&lt;p&gt;Everything in the video runs on one laptop with the Wi-Fi turned off.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmnvnlszhsvas3p8aja9m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmnvnlszhsvas3p8aja9m.png" alt="Main page" width="799" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx8xqaf1e1ncu1snes9nl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx8xqaf1e1ncu1snes9nl.png" alt="The comic page" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fudcsw3ayrsw8pkjkaj6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fudcsw3ayrsw8pkjkaj6a.png" alt="A shot of the video" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&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/Ankita562" rel="noopener noreferrer"&gt;
        Ankita562
      &lt;/a&gt; / &lt;a href="https://github.com/Ankita562/ofrenda-of-maybe" rel="noopener noreferrer"&gt;
        ofrenda-of-maybe
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Describe a future you hope for. A friendly ghost turns it into a candlelit animated story, entirely on your own laptop with open models.
    &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;🎃 Ofrenda of Maybe&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Whisper a future you hope for. A friendly ghost from that future turns it into a short cartoon film, entirely on your own laptop.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Built for the &lt;a href="https://dev.to/challenges/hacktoberfest-week4-2026-10-26" rel="nofollow"&gt;Hacktoberfest Open-Source AI Challenge, Week 4: Ghost in the Machine&lt;/a&gt;.&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="js-render-enrichment-target"&gt;
    &lt;div class="render-plaintext-hidden"&gt;
      &lt;pre&gt;flowchart LR
    subgraph L["💻 Your laptop (no cloud, works offline)"]
        direction LR
        A["💭 Your wish"] --&amp;gt; B["🧠 Gemma&amp;lt;br/&amp;gt;writes 4 scenes"]
        B --&amp;gt; C["🎨 SD-Turbo&amp;lt;br/&amp;gt;draws them"]
        C --&amp;gt; D["🎙️ Piper&amp;lt;br/&amp;gt;narrates"]
        D --&amp;gt; E["🎬 Cartoon film"]
        B --&amp;gt; F["🕯️ The ghost's offering:&amp;lt;br/&amp;gt;one small first step"]
    end
&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;span class="js-render-enrichment-loader d-flex flex-justify-center flex-items-center width-full"&gt;
    &lt;span&gt;
      &lt;span class="sr-only"&gt;Loading&lt;/span&gt;
&lt;/span&gt;
  &lt;/span&gt;


&lt;p&gt;Scenes 1-3 tell your wish as a cheerful story. Scene 4 is the &lt;strong&gt;ghost&lt;/strong&gt;: your future self, who remembers the first small step that started it all. That step also appears as its own card, so a daydream becomes something you can do today.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🎬 4-scene cartoon film with captions and slow zoom&lt;/li&gt;
&lt;li&gt;🕯️ "The ghost's offering": one…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Ankita562/ofrenda-of-maybe" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; 💭 your wish
    │
    ▼
 🧠 Gemma 3 (4B, via Ollama) ── writes 4 scenes + the "first small step" (JSON)
    │
    ▼
 🎨 SD-Turbo (diffusers) ────── draws one cartoon picture per scene
    │              │
    ▼              ▼
 🎙️ Piper TTS     📖 Pillow ─── lays out the comic page (captions, speech bubble)
    │
    ▼
 🎬 MoviePy ─────────────────── narrated film
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 4B&lt;/strong&gt; (through Ollama) writes the storyboard. I force a JSON schema, so it always returns exactly the fields I need: scenes, narration, image prompts and the first step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SD-Turbo&lt;/strong&gt; (🤗 diffusers) paints each scene. Gemma is unloaded from the GPU before the image model runs, which is how the whole thing fits in &lt;strong&gt;4 GB of VRAM&lt;/strong&gt; (RTX 3050 Laptop).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Piper&lt;/strong&gt; gives the narration, locally, with a voice picker.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pillow&lt;/strong&gt; draws the comic page and &lt;strong&gt;MoviePy&lt;/strong&gt; builds the film. &lt;strong&gt;Gradio&lt;/strong&gt; is the UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What broke along the way
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A version mismatch.&lt;/strong&gt; &lt;code&gt;AttributeError: module 'torch' has no attribute 'accelerator'&lt;/code&gt;. The newest &lt;code&gt;diffusers&lt;/code&gt; wanted a newer PyTorch than the CUDA 12.1 build I had installed. Moving to the cu126 build fixed it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;My own prompt leaked.&lt;/strong&gt; I had written "the bakery, the pastries" as examples in the system prompt. A 4B model copied them, so my famous singer ended up performing in a bakery. Deleting the examples fixed it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crowds became blobs.&lt;/strong&gt; SD-Turbo can't draw an audience, so "cheering crowd" turned into round circles, and my first "ghost" was just a round blob. I now tell Gemma to avoid crowds, faces and hands, and I describe the ghost as "a cartoon ghost made of a white bedsheet".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The ghost had no point.&lt;/strong&gt; Version one just repeated the story. I changed it into your future self, who remembers the first small step, and gave that step its own card.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your hopes stay yours.&lt;/strong&gt; People type very personal wishes. With local models they never touch a server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works with the Wi-Fi off.&lt;/strong&gt; I filmed the demo that way. No API key, no account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's free to run&lt;/strong&gt;, and the pieces are swappable: the storyboard model is one line (&lt;code&gt;LLM = "gemma3:4b"&lt;/code&gt;), the art style is a prompt string, and new narrator voices are just downloaded files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control over memory.&lt;/strong&gt; On a 4 GB GPU, being able to load and unload models myself is what made this possible at all. A closed API wouldn't let me.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Spirit of It
&lt;/h2&gt;

&lt;p&gt;My favorite moment came from the sunflower wish. The ghost didn't repeat the story back to me. It said, &lt;em&gt;"I remember when you planted that first seed,"&lt;/em&gt; and handed me a step I could take that same day: &lt;em&gt;"Buy one sunflower seed today."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's the idea behind an ofrenda: an offering that keeps something alive. This one just keeps a future alive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your turn:&lt;/strong&gt; what future would you ask the ghost about? Drop a wish in the comments and I'll run it and reply with the ghost's first small step. 🕯️&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔮 &lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Gemma 3 4B runs locally through Ollama and writes the storyboard, the narration lines and the first small step as structured JSON.&lt;/li&gt;
&lt;li&gt;🔊 &lt;strong&gt;Best Use of ElevenLabs:&lt;/strong&gt; the voice-over in my demo video was generated with ElevenLabs. (The app itself narrates with local Piper.)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Built an Offline Face Finder So My Friends Can Stop Scrolling the Group Chat.</title>
      <dc:creator>Ankita</dc:creator>
      <pubDate>Sun, 04 Oct 2026 14:46:15 +0000</pubDate>
      <link>https://dev.to/ankita562/i-built-an-offline-face-finder-so-my-friends-can-stop-scrolling-the-group-chat-31gf</link>
      <guid>https://dev.to/ankita562/i-built-an-offline-face-finder-so-my-friends-can-stop-scrolling-the-group-chat-31gf</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;We took a one-day trip to Mangalore, and the moment we got back, the photos started flooding the group chat. My friend let's name her Poo wanted to post a few on Instagram, but first she had to scroll through all of our pictures to find the ones she was in. It took about two hours.&lt;/p&gt;

&lt;p&gt;That's when I thought: what if something could do this for us? Finding "the photos with my face in them" is a job a computer is good at. But it would mean handing my friends' faces to someone else's server, and I wasn't willing to do that. So I built FaceGotcha for Poo and the rest of our group: a version that runs entirely on your own laptop and finds your photos for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FaceGotcha&lt;/strong&gt; is a "where am I in all these photos?" machine. You give it a few photos of your face and a giant pile of group photos, and it hands back only the ones you're in. Nothing is uploaded anywhere.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl49th1jzqercqozux1t8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl49th1jzqercqozux1t8.png" alt="The four steps of FaceGotcha: pick up to 5 photos of you, add a photo folder, press Find my photos, then swipe the maybes and download a zip" width="799" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The whole thing in five steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick up to 5 clear photos of yourself.&lt;/li&gt;
&lt;li&gt;Throw in the photo pile: a folder, like an unzipped WhatsApp export.&lt;/li&gt;
&lt;li&gt;Press &lt;strong&gt;Find my photos&lt;/strong&gt; (the app cheerfully announces that it's "ignoring photos of food...").&lt;/li&gt;
&lt;li&gt;Swipe through only the uncertain ones. Swipe right for "that's me" (cue the GOTCHA! stamp) and left for "nope". It's like a dating app, except every match is you.&lt;/li&gt;
&lt;li&gt;Download a zip of your photos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In my test of 55 WhatsApp photos, 26 were matched automatically, 9 needed my opinion, and 20 were ignored. Your original photos are never touched.&lt;/p&gt;

&lt;p&gt;Faces are biometric data, and these are my friends' faces. So the one rule was: nothing leaves the laptop. No accounts, no cloud, no API keys.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fehhtcbeunpiou7gi8krw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fehhtcbeunpiou7gi8krw.png" alt="The FaceGotcha start screen with a progress tracker along the top and cards for adding your photos and the photo pile" width="799" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frdl9besjq9yehzksenz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frdl9besjq9yehzksenz8.png" alt="The numbers after a search: a colour bar showing how every photo was sorted" width="680" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&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/Ankita562" rel="noopener noreferrer"&gt;
        Ankita562
      &lt;/a&gt; / &lt;a href="https://github.com/Ankita562/facegotcha" rel="noopener noreferrer"&gt;
        facegotcha
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Find the photos you're in from a group-chat photo dump. Fully local face matching with open models (OpenCV YuNet + SFace). No cloud, no uploads.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Ankita562/facegotcha/docs/banner.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FAnkita562%2Ffacegotcha%2FHEAD%2Fdocs%2Fbanner.png" width="520" alt="FaceGotcha: a polaroid seen through a smiling magnifying glass"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Find the photos you're in, from a group-chat photo dump, fully offline&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;Drop in a few photos of your face and a folder of group photos. FaceGotcha finds the ones you appear in, lets you &lt;strong&gt;swipe&lt;/strong&gt; through the uncertain ones, and gives you a zip. It runs on your own computer with open-source face models, so nobody's face data is ever uploaded anywhere.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Built for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01" rel="nofollow"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#demo" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#why-i-built-it" rel="noopener noreferrer"&gt;Why I built it&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#the-flow" rel="noopener noreferrer"&gt;The flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#how-it-works-under-the-hood" rel="noopener noreferrer"&gt;How it works under the hood&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#open-source-pieces" rel="noopener noreferrer"&gt;Open-source pieces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#why-open-and-local-matters-here" rel="noopener noreferrer"&gt;Why open and local matters here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#setup-on-your-computer" rel="noopener noreferrer"&gt;Setup on your computer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Ankita562/facegotcha#how-to-use-it" rel="noopener noreferrer"&gt;How to use it&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#getting-photos-out-of-whatsapp" rel="noopener noreferrer"&gt;Getting photos out of WhatsApp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#command-line-version" rel="noopener noreferrer"&gt;Command-line version&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#settings" rel="noopener noreferrer"&gt;Settings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#how-well-does-it-work" rel="noopener noreferrer"&gt;How well does it work?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#limitations" rel="noopener noreferrer"&gt;Limitations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#privacy" rel="noopener noreferrer"&gt;Privacy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#looking-ahead" rel="noopener noreferrer"&gt;Looking ahead&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#project-structure" rel="noopener noreferrer"&gt;Project structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#built-with" rel="noopener noreferrer"&gt;Built with&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ankita562/facegotcha#license-and-contact" rel="noopener noreferrer"&gt;License and contact&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Video: &lt;a href="https://drive.google.com/file/d/1sbdd88orENvaOkqviMm3ljYHQgyU6LAl/view?usp=sharing" rel="nofollow noopener noreferrer"&gt;Watch the demo video&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/Ankita562/facegotcha/docs/start.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FAnkita562%2Ffacegotcha%2FHEAD%2Fdocs%2Fstart.png" width="52%" alt="The start screen"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/Ankita562/facegotcha/docs/numbers.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FAnkita562%2Ffacegotcha%2FHEAD%2Fdocs%2Fnumbers.png" width="33%" alt="The numbers after a search"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why I built it&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;One friend in my group has the phone with the best camera…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Ankita562/facegotcha" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;Two small open models do the heavy lifting. Both come from the OpenCV Zoo and run on the CPU, so no GPU is needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;YuNet&lt;/strong&gt; finds every face in a photo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SFace&lt;/strong&gt; turns each face into a fingerprint of 128 numbers. Faces of the same person land close together, and faces of different people land far apart.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenCV&lt;/strong&gt; runs them, and &lt;strong&gt;Flask&lt;/strong&gt; serves a little web page at &lt;code&gt;127.0.0.1&lt;/code&gt;, so other devices on the network can't open it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scoring works like a bouncer at a door. A photo scoring 0.53 or higher walks straight in. Between 0.38 and 0.53, it gets an ID check, which means it comes to you for a swipe. Below 0.38, it's turned away.&lt;/p&gt;

&lt;p&gt;I added that middle band because OpenCV's suggested single cut-off (0.363) let the wrong people in during my first test:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Auto-matched&lt;/th&gt;
&lt;th&gt;Wrong person in it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenCV's default cut-off (0.363)&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;My cut-off with a review band (0.53 and 0.38)&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The swipe review is where I spent the most design effort. It's one photo and one gesture at a time, with undo on one key (Z). A "nope" doesn't delete anything: the photo moves to a Rejected album you can browse or download. The page also has a progress tracker along the top that ticks off each step, a scrolling reel of your matches, and a stats bar showing how every photo was sorted. Confetti appears when you find your photos, because finding your photos should feel like winning.&lt;/p&gt;

&lt;p&gt;I built this with AI assistance (Claude) for writing and explaining the code. I designed the idea, tested it on my own photos, and tuned the cut-offs from the scores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest limits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is a small test on one person's face, not a benchmark, and the cut-offs were tuned on that one sample.&lt;/li&gt;
&lt;li&gt;It missed one photo of me, a group shot that scored 0.176. No cut-off could catch it without flooding the review pile with wrong people.&lt;/li&gt;
&lt;li&gt;Small faces in compressed group shots are the hardest case.&lt;/li&gt;
&lt;li&gt;A photo counts as a match if &lt;em&gt;any&lt;/em&gt; face in it matches, which is why the review step matters.&lt;/li&gt;
&lt;li&gt;The stats bar shows how photos were sorted, not an accuracy score. The app has no answer key, so I counted the real accuracy by hand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What's next:&lt;/strong&gt; finding photos of &lt;em&gt;two&lt;/em&gt; people at once (me and my best friend, together and solo), and collecting every photo of a friend for a birthday post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;A face-sorting app has a problem most apps don't: it has to look at every one of your friends' faces. Sending the whole group chat to a cloud service just to find my face would be like photocopying everyone's face to find mine, including people who never agreed to that.&lt;/p&gt;

&lt;p&gt;Open models made a different design possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy:&lt;/strong&gt; the models run on your own machine, so face data never leaves it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; no API keys, rate limits, or per-photo charges. The only download is two small model files, and after that it works offline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control:&lt;/strong&gt; I could see what the models do, change the cut-offs, and swap in a different open model without asking anyone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reuse:&lt;/strong&gt; both models are open source (YuNet is MIT-licensed and SFace is Apache 2.0, according to their LICENSE files in OpenCV Zoo), so anyone can run, change, and build on this project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest trade-off: a big cloud service would probably be more accurate out of the box. Mine needs reference photos, a tuned cut-off, and a human to settle the borderline cases, and for photos of my friends, I'll take that deal.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
