How
from a street photo to a life on record
Work in progress. This is the shape of the system as currently designed, not a finished spec — expect it to change as we run the first pilots.
In one sentence: Namma Indies is open-set individual re-identification of free-ranging dogs, from opportunistic, crowdsourced, uncontrolled imagery — using a strong geographic and temporal prior plus human confirmation to produce two outputs: a bias-corrected population estimate over time, and a persistent longitudinal record for each individual dog.
Two consumers, one pipeline, two thresholds
The same stream of photos feeds two different products, and they tolerate error very differently.
- The population layer asks how many dogs are there? It runs on loose, aggregate match signal — a mark-and-resight estimate with honest confidence intervals. Individual mistakes wash out on average.
- The individual layer asks is this Kaju? It needs a high-confidence match, ideally confirmed by a human — a neighbour or a clinic — because a single wrong link corrupts a dog's whole history.
Every sighting begins anonymous and points at an individual slot that may stay empty for months, until the model earns confidence or someone who knows the dog fills it in. That empty-slot-waiting-to-be-named is the emotional and architectural centre of the system: a sighting can always be linked to an individual later, even if it starts life as a nameless street photo.
Why it's hard
This is an open-set matching problem, not closed-set classification. The gallery of known dogs is unbounded, most individuals appear only once or twice, and for each new photo the system must decide not "which of these N dogs is this" but "is this any dog we've seen before, or a new one." Three difficulties compound:
- Weak appearance signal. Indian landrace dogs have low visual variance between individuals and high variance within one — season, weight, wet coat, injury, pose, lighting. Appearance alone is only weakly discriminative.
- No labels to start from. Identities don't exist a priori, which is a cold-start problem: there's nothing to train an embedding on until the system has already been running.
- The base-rate trap. At city-scale gallery sizes, even a highly specific matcher accumulates false matches, simply because there are so many non-matches to test against.
The design response: re-ID as fusion
So the design doesn't lean on appearance alone. Dogs are territorial and their home ranges are small, so a geo and time prior collapses the candidate set from the whole city down to maybe ten nearby dogs before appearance is scored at all. That goes straight at the base-rate problem, and it means a weak appearance signal only has to tell ten dogs apart, not ten thousand.
In practice the whole retrieval is close to a single query — a geographic and temporal prefilter, then a vector ranking on a learned appearance embedding:
SELECT s.individual_id, i.name,
s.embedding <=> :query AS visual_distance
FROM sightings s
JOIN individuals i ON i.id = s.individual_id
WHERE ST_DWithin(s.geog, :location, 300) -- geo prior: ~300m
AND s.captured_at > now() - interval '30 days' -- time prior
AND s.species = :species -- dogs match dogs, cats match cats
AND s.individual_id IS NOT NULL
ORDER BY visual_distance
LIMIT 10;
The embeddings come from an animal re-identification foundation model (MegaDescriptor and/or DINOv2), with room to move to calibrated global-plus-local fusion later. And the same prior that narrows the search also hands us training pairs for free.
Routing, and the confirmation loop
Once a new sighting is embedded, its match confidence routes it down one of three paths:
- Very close visual match → auto-link to the existing individual (a high bar).
- Middling / uncertain → mark it proposed and route it to a neighbour whose home patch covers the sighting. Geography picks the right person automatically — whoever is most likely to actually know this dog.
- No candidate → open a new individual slot (or leave it unmatched; the population layer still counts it either way).
When a neighbour says "that's Kaju," that's recognition-as-love and recognition-as-label at once — the same event in the data model. Every confirmation is also a labelled training pair that sharpens the embedding on the next round. The people who know the dogs end up teaching the model to see, without doing anything they weren't already doing.
Bootstrapping without labels
To beat the cold-start problem before anyone has confirmed anything, the same spatiotemporal structure that narrows search also mines pseudo-labels:
- Two sightings within ~50m and a few hours of each other are probably the same dog — a free hard-positive pair across changes in light, pose, and time of day.
- Sightings far apart and visually dissimilar are probably different dogs — a negative pair.
These are noisy but abundant, and they directly attack cold start: enough signal to fine-tune the embedding before humans are in the loop, with human confirmations then supervising on top.
Honest population estimates
Opportunistic crowdsourcing is biased sampling: it over-represents friendly, photogenic, high-footfall dogs and under-counts the shy ones on the quiet lane. So the population estimate can't be a raw sighting count. The real research task is to model where we looked — capture effort and coverage per area, estimate detection probability, then stratify and weight accordingly. The minimum viable signal is "sightings plus a defensible model of where we looked," run per species so dogs and cats are counted separately. And the estimate always carries its uncertainty: the system never returns a point population number without a confidence interval attached.
Principles
- Open code, restricted data. The software is meant to be open source; the data is a separate decision. Nothing that resolves a vulnerable individual animal's whereabouts goes public.
- Aggregate-only public surface. The public map shows density, not dogs. Precise, recent, individual locations stay internal and access-controlled.
- Uncertainty is not optional. Population figures ship with confidence intervals, always.
- People-safe by default. Phone-backed identity is stored hashed, not raw; people's faces, plates, and house numbers are avoided where feasible.
Planned architecture
For the pilot, deliberately boring plumbing — so that effort concentrates on the one genuinely hard part, re-identification. A single small server, a single Postgres database doing triple duty (relational, spatial via PostGIS, and vector search via pgvector), and Python end-to-end. The flow:
- Intake — a photo arrives over WhatsApp with location and timestamp; the image goes to object storage, a
sightingrow is created — tagged with species (dog, cat, or the occasional other) from the first photo — and an embedding job is queued. - Embed — a background worker computes the appearance embedding (async, CPU is fine at pilot volume — no GPU on day one).
- Retrieve — the geo-and-time prefilter plus vector ranking finds candidate individuals.
- Route — the threshold decision auto-links, proposes it to a neighbour, or opens a new slot.
- Confirm — a neighbour's verdict links the sighting and becomes a training label.
- Estimate — a separate job consumes the resight signal to produce population estimates with intervals; a public map renders aggregate density only.
Everything resists premature scale — no microservices, no GPU, no separate search cluster — until the first experiment tells us how much of the work appearance can actually carry, and how much load the geographic prior must bear.
References
- Belsare, A. & Vanak, A. T. (2020). Modelling the challenges of managing free-ranging dog populations. Scientific Reports, 10, 18874. The denominator and rebound problem.
- Gibson et al. (2022), Nature Communications — the Goa rabies-elimination and coordination model.
- WildlifeDatasets / MegaDescriptor (WACV 2024) — an animal re-identification foundation model.
- WildFusion (2024) — calibrated fusion of deep similarity and local matching for zero-shot re-ID.
- iNaturalist — the community-identification pattern this borrows from.