All projects
Personal project · Android app and web dashboard

CatGuard: on-device cat recognition on a spare phone

2026Computer visionKotlinJetpack ComposeTensorFlow LiteCameraXFirebaseComputer vision

An Android app that turns an old phone into an always-on camera which recognises my own cat on the device and sends a Telegram photo alert when an unknown cat comes in, with a web dashboard for the event history. It's tuned to run all day on a low-end Android 8 phone.

The problem

A neighbour's cat kept coming in through our cat flap. I wanted to know when it happened without paying for a smart camera, and without training a model for one specific cat. An old Android phone left on charge by the door turned out to be enough.

How it recognises my cat

Instead of training a classifier, CatGuard uses few-shot recognition. During enrolment you take 12 to 25 photos of your cat, and a pretrained MobileNet-family network turns each one into an embedding, a vector describing what the cat looks like. Every later sighting is embedded the same way and compared with those vectors by cosine similarity: close enough to an enrolled cat means "known", otherwise "intruder". If it gets one wrong, tapping "That's my cat" adds that sighting to the cat's set, so it improves with use.

A pipeline built for a cheap phone

The target was a 2 GB Android 8 phone, so the expensive models only run when there's a reason to:

Detection pipeline: cheapest check first

  1. 01
    Capture
    CameraX, 640 × 480 frames, always keeping only the latest
  2. 02
    Light and motion gate
    Drop dark frames; compare a 32 × 32 brightness grid every 350 ms
  3. 03
    Burst
    On motion, collect 5 frames (or 1.5 s)
  4. 04
    Detect
    COCO detector keeps cat boxes with confidence ≥ 0.45; best crop by size × sharpness
  5. 05
    Embed and match
    L2-normalised embedding vs the enrolled cats; similarity below 0.72 means intruder
  6. 06
    Alert and sync
    Room log, 2-minute cooldown, Telegram photo, Firestore event for the dashboard
Each stage only runs when the one before it finds something, which keeps an old phone cool enough to run all day.
  • Motion gate. A 32 × 32 brightness grid is compared between frames every 350 ms; frames that are too dark are dropped.
  • Burst. When motion trips, it grabs a burst of 5 frames.
  • Detect, then recognise. A COCO object detector runs only on that burst; "cat" boxes with confidence of at least 0.45 are scored by size and sharpness, and the best crop goes to the embedder.
  • Debounce. A cooldown (2 minutes by default) stops one visit from producing a flood of alerts.

Built to run unattended

  • A foreground camera service with a wake lock that restarts after reboots, and a watchdog that rebinds the camera if frames stop for 30 seconds.
  • Thermal throttling: the motion check slows to half and quarter speed as the phone warms up, and pauses when it's critical.
  • A heartbeat every 60 seconds, so the dashboard can show whether the camera is live.
  • Battery-optimisation guidance for Xiaomi, Huawei, Samsung and Oppo, whose power managers otherwise kill background apps.
12–25
Enrolment photos per cat; no model training needed
0.72
Default similarity threshold (adjustable 0.50–0.92)
33
Unit tests for the embedding maths, motion detection and debouncing
Android 8+
Runs on-device on CPU with TensorFlow Lite

Source: core/Constants.kt, ml/, camera/ and app/src/test in the repository

Alerts and dashboard

Intruder events are saved locally, uploaded to Firestore with a compressed thumbnail, and sent as a Telegram photo message (respecting quiet hours). A web dashboard on Firebase Hosting signs in with the same Google account and shows live status, a gallery, a timeline with the busiest time of day, CSV export and a PDF report. Firestore rules restrict every household's data to its own signed-in user, and the app and dashboard are available in English and Russian.

Looking back

The thresholds are tuned by hand rather than measured on a labelled set, so a proper evaluation of false alarms is the next step, along with push notifications to the owner's phone.

← Back to all projects