Cámaras y SeguridadTécnico

Cámara que envía fotos a tu teléfono cuando detecta movimiento

Detecta movimiento con Picamera2 y OpenCV, guarda fotos y envía notificaciones al instante.

NivelTécnico
Tiempo1.5 h
Costo est.~$129
Pasos5

Partiendo de la lección de visión artificial de la Academia: cuando haya movimiento, guarda una foto y envía una notificación push con ntfy, un servicio gratuito y de código abierto que también puedes alojar tú.

⚠ SEGURIDAD
Las leyes de grabación varían. Apunta las cámaras a tu propiedad, coloca avisos donde se exija y evita grabar audio si no conoces las reglas locales.

Video tutorial

▶ Sebastian TrujilloVer en YouTube ↗

Video de Sebastian Trujillo, insertado desde YouTube. Los pasos escritos abajo son nuestros y coinciden con la lista de piezas.

Pasos de la misión

  1. Prepara la cámara

    Conecta la Camera Module 3 y confirma que rpicam-still funciona.

  2. Instala la app

    Instala ntfy en tu teléfono y suscríbete a un tema con nombre largo y aleatorio: cualquiera que conozca un tema público puede leerlo.

  3. Corre el detector

    Usa el script de abajo; guarda un JPG y lo envía como adjunto cuando detecta movimiento, con una pausa para no saturarte.

  4. Ejecútalo al arrancar

    Crea un servicio systemd como en la guía de la cámara del dron.

  5. Guarda con seguridad

    Guarda las imágenes en un NAS o borra las viejas con una tarea cron para que la tarjeta nunca se llene.

Código

import cv2, time, requests
from picamera2 import Picamera2

TOPIC = "https://ntfy.sh/mc-cam-7f3k9x2q"   # use your own random topic
cam = Picamera2(); cam.configure(cam.create_video_configuration(main={"format": "RGB888", "size": (1280, 720)}))
cam.start(); time.sleep(1)
prev, last = None, 0

while True:
    frame = cam.capture_array()
    gray = cv2.GaussianBlur(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), (21, 21), 0)
    if prev is not None and time.time() - last > 60:
        diff = cv2.threshold(cv2.absdiff(prev, gray), 25, 255, cv2.THRESH_BINARY)[1]
        if cv2.countNonZero(diff) > 8000:
            name = time.strftime("/home/maker/cam_%Y%m%d_%H%M%S.jpg")
            cv2.imwrite(name, frame)
            with open(name, "rb") as f:
                requests.put(TOPIC, data=f, headers={"Filename": "motion.jpg", "Title": "Motion detected"})
            last = time.time()
    prev = gray

Code comments are in English, like most libraries and docs — a good habit for makers.

Preguntas

¿Algo más grande que una cámara?

Frigate NVR corre en un Pi 5 con acelerador de IA y graba varias cámaras IP con detección real de personas y carros.