This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass
What I Built
Noticed is a quiet photo diary that runs entirely on your own computer. Once a day you step outside, take one photo of whatever catches your eye, and add it to the app. A local open-source vision model (Gemma 3 through Ollama) writes a one-line caption, and over time you build a gallery of small moments instead of a feed to scroll
Demo
Noticed runs locally, so here’s what it looks like.

You can only add one photo per day
Code
Being-RAYtastic
/
noticed
A private photo diary that captions your daily walk photo with a local open-source AI model (via Ollama).
Noticed
Outside for a minute. Noticed for a day.
Noticed is a small photo diary that runs on your own computer. You add a photo from your walk, and a local open-source vision model (Gemma 3 through Ollama) writes a short caption for it.
Once a day, step outside and take one photo of whatever catches your eye. Noticed keeps it with a short caption, so you build a gallery of small moments instead of a feed to scroll.
Built for the Hacktoberfest Open-Source AI Challenge, Week 1 ("Touch Grass").
TechStack I used:
- Model: Gemma 3 4B (open-weight vision model), run locally with Ollama
- Backend: Python, Flask (routes and Jinja templates)
- Frontend: plain HTML, CSS, and a little JavaScript, with no frameworks
- Storage: photos in a folder and entries in a JSON file, with no database
Why it's local
- Photos and captions never leave your computer.
- Location data (EXIF/GPS) is…
How I Built It
TechStack I used:
- Model: Gemma 3 4B (open-weight vision model), run locally with Ollama
- Backend: Python, Flask (routes and Jinja templates)
- Frontend: plain HTML, CSS, and a little JavaScript, with no frameworks
- Storage: photos in a folder and entries in a JSON file, with no database
Noticed is three small pieces wired together by Flask.
Noticed is built around one rule: one photo a day, as a check-in. Each day starts with an empty tile for today’s date. Filling it is the whole habit, and once it’s filled the tile disappears until tomorrow. There’s no feed and no upload button to keep tapping, so the diary can only grow by one entry per day.
Cleaning the photo: When you add a photo, Pillow straightens it, shrinks it to at most 2560 px, and saves a fresh JPG with no metadata, so GPS data from the phone never reaches the diary. It also shrinks the image to a single pixel to get its average color, which feeds the strip at the top of the page.
Writing the caption: The cleaned photo goes to Gemma 3 4B through Ollama, with a short prompt asking for one dreamy or witty line that only mentions what’s visible. A small cleanup step trims the reply, and if the model isn’t running, the entry is still saved with an empty caption instead of crashing.
Showing the diary: Entries are stored in a plain JSON file and rendered with Jinja templates. There’s no database and no framework on the front end: just HTML, CSS, and a few lines of JavaScript. Today’s upload button is an empty tile at the start of the grid, and it locks while the model works so you can’t send a second photo mid-caption. Each entry shows its date and caption, and the strip of colors at the top turns your days into a quick visual summary.
Why Does Open Innovation Matter?
A diary is about the most personal thing you can build an AI feature for. Photos from your walks show where you go and when, and a caption model has to look at every one of them. That’s why I wanted the model to run on my own machine.
Because Gemma 3 is open-weight, Noticed can do that:
- Your photos stay with you. Captioning happens locally through Ollama, so no photo is uploaded to any service. The app also saves a fresh copy of each photo with its metadata removed, so GPS data from the phone never lands in the diary.
- No accounts, keys, or per-photo costs. One photo a day is a tiny workload, but even tiny workloads cost money on a hosted API and need an account. Here, once the model is downloaded, a caption costs nothing.
-
MODEL is replaceable. The model is a single line in
caption.py. If a better open vision model appears, or you want a different tone for captions, you swap the name and the rest of the app is unchanged. - You can inspect and fix it. When the first small model I tried was too weak for the job, I could try a larger one and tune the prompt myself, rather than being limited to whatever a hosted service decides to offer.
Two honest limits: the model needs a one-time download, and the page loads its fonts from Google Fonts. Everything else, including your photos and captions, stays on your machine. Captions come from a small 4B model, so they’re sometimes off
Prize Categories
Best Use of Gemma: Noticed runs Gemma 3 4B locally through Ollama to write a caption for each day’s photo.
Top comments (0)