Add TFLite object detection to reduce false positives

Motion detection now optionally runs MobileNet V2 SSD (COCO, quantized)
on frames that trigger motion, identifying objects like people, cats, and
cars. Events without detected objects are suppressed by default. Snapshots
include bounding box annotations. New MCP tool vision_get_detections()
enables label-based queries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alex
2026-02-08 17:04:10 -06:00
parent 68c7e9772f
commit e1171e8ff8
11 changed files with 687 additions and 50 deletions

55
server/download_model.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/bin/bash
# Download MobileNet V2 SSD (COCO, INT8 quantized) for TFLite
#
# Model: ssd_mobilenet_v2_coco_quant_postprocess.tflite (~6MB)
# Source: TensorFlow Model Zoo
# Classes: 80 COCO object classes
#
# This script is idempotent - skips download if model exists.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_DIR="${SCRIPT_DIR}/models"
MODEL_FILE="${MODEL_DIR}/ssd_mobilenet_v2_coco_quant_postprocess.tflite"
ZIP_URL="https://storage.googleapis.com/download.tensorflow.org/models/tflite/coco_ssd_mobilenet_v2_quantized_300x300_uint8_20200430.zip"
ZIP_FILE="${MODEL_DIR}/model.zip"
mkdir -p "${MODEL_DIR}"
if [ -f "${MODEL_FILE}" ]; then
echo "Model already exists: ${MODEL_FILE}"
echo "Size: $(du -h "${MODEL_FILE}" | cut -f1)"
exit 0
fi
echo "Downloading MobileNet V2 SSD (quantized)..."
curl -L -o "${ZIP_FILE}" "${ZIP_URL}"
echo "Extracting model..."
unzip -o "${ZIP_FILE}" -d "${MODEL_DIR}"
# Clean up zip and extra files
rm -f "${ZIP_FILE}"
rm -f "${MODEL_DIR}/labelmap.txt" # We use our own coco_labels.txt
if [ -f "${MODEL_FILE}" ]; then
echo "Model downloaded: ${MODEL_FILE}"
echo "Size: $(du -h "${MODEL_FILE}" | cut -f1)"
else
# The zip might extract with a slightly different path
FOUND=$(find "${MODEL_DIR}" -name "*.tflite" -type f | head -1)
if [ -n "${FOUND}" ] && [ "${FOUND}" != "${MODEL_FILE}" ]; then
mv "${FOUND}" "${MODEL_FILE}"
echo "Model downloaded: ${MODEL_FILE}"
echo "Size: $(du -h "${MODEL_FILE}" | cut -f1)"
else
echo "ERROR: Model file not found after extraction"
exit 1
fi
fi
# Clean up any extracted subdirectories
find "${MODEL_DIR}" -mindepth 1 -type d -exec rm -rf {} + 2>/dev/null || true
echo "Done!"