A few weeks ago I added a seasonal colour analysis to Fring, the free wardrobe app I build on my own: you upload a selfie, you get your colour season, your undertone and six colours that suit you. It looks like a small feature. It taught me four things about putting a vision model in front of users.
1. Let the model judge, never let it invent
The tempting design is to ask the model for everything: season, undertone, and a palette. But a generated palette would change from one run to the next — plausible colours every time, and nothing the rest of the app could rely on.
So the model answers a much smaller question:
Judge the face only: skin undertone, hair and eye colour, contrast between them.
Classify into one of the four colour seasons:
spring = warm and light/bright, summer = cool and soft/light,
autumn = warm and deep/muted, winter = cool and deep/high contrast.
If no human face is clearly visible, answer null for both fields.
Respond with ONLY a JSON object of the shape
{"season":"spring|summer|autumn|winter","undertone":"warm|cool|neutral"}
The palette is a fixed table on the server, six colours per season. The model classifies; the code decides what a classification means. Anything outside the allowed values is treated as "no readable face" and the user is asked for a better photo, instead of getting a confident wrong answer.
2. Four seasons, not twelve
Colour analysts often work with twelve seasons (soft autumn, cool summer, deep winter…). A phone selfie under random indoor light cannot carry that level of detail reliably: white balance alone moves a face from "warm" to "neutral". So the app sticks to four seasons and three undertones, and says plainly that it's an estimate to check against a test with real fabric. A feature that is honest about its precision is more useful than one that pretends.
3. Features die silently
For a while the analysis called an old vision microservice. When the AI moved to a single GPU at home (a used Tesla P40 running Qwen3-VL-8B through llama.cpp's server), that service stopped running — and the colour analysis broke with no visible error, just "service unavailable" for every user. I only found it by walking through every feature by hand. Since then, every model call goes through one client module, so a backend change can't quietly orphan a feature again.
The other side of running the model at home: the selfie is processed in memory and never stored, and it never leaves the machine.
4. A result is only worth something if it's used
A palette you look at once is a curiosity. In Fring the saved colours feed the outfit suggestions (outfits in your colours score higher) and the shopping assistant flags a colour outside your palette before you buy. That's where the feature earns its place: not in the result screen, but in the decisions it nudges afterwards.
If you're curious about the colour theory side, I wrote a longer guide: seasonal color analysis, the 4 and 12 seasons and a free at-home test.
Written with AI assistance.
Top comments (0)