Frigate, videovigilancia DIY con inteligencia artificial
- yayitazale
- January 9, 2022
Para empezar el año os traigo un post que tenía muchas ganas de publicar y que los suscriptores también pidieron en la encuesta que realizamos en el canal de telegram hace tiempo.
En los últimos años ha habido un crecimiento de ventas de cámaras IP con cada vez una mayor cantidad de opciones de marcas que nos atan a su vez a sistemas propietarios en la nube. Con este sistema, podremos integrar en nuestra plataforma Home Assistant todas las cámaras y tener notificaciones utilizando inteligencia artificial para detectar objetos (personas, gatos, pájaros, coches, etc).
TOC
- Funcionamiento
- Requisitos
- Instalando Frigate sobre unraid con Docker
- Configurar Frigate para detección de personas y gatos
- Notificaciones de Telegram
- Integración de Frigate en Home Assistant
- Control de Privacidad con la API de TAPO
Funcionamiento
Lo primero que demos hacer es entender el funcionamiento del sistema que vamos a implementar. El flujo de nuestras imágenes será el del siguiente esquema, donde podéis ver el papel que juega Frigate por si solo en todo el camino desde la cámara hasta la notificación inteligente con Telegram:
Y esto es lo que hace cada uno de los elementos del esquema en cada paso:
- Cámaras: emitirán la imagen de vídeo comprimida y a unos 25 FPS.
- FFmpeg: descomprimirá el vídeo en tiempo real y reducirá los FPS a lo que nosotros configuremos (por ejemplo, 10 FPS).
- OpenCV: recibirá los fotogramas y nos dirá si hay zonas en la imagen donde hay movimiento. La salida serán las zonas recortadas donde ha encontrado movimiento.
- TensorFlow: recibirá los recortes de los fotogramas donde haya movimiento y usando un modelo de inteligencia artificial nos dirá si ha detectado alguno de los objetos que busquemos y con que confianza (de 0 a 100%). A partir de cierta confianza se iniciará un evento de detección y se guardará todo el vídeo desde el primer fotograma con una detección hasta el último cuando el objeto salga de la escena.
- MQTT: el evento generará avisos (inicio y fin de un evento) que se enviarán a nuestro broker MQTT para que otros puedan utilizarlo como input
- Node-Red: conectaremos el MQTT para saber cuando tenemos un final de evento y crearemos un flujo lógico para coger el clip o snapshot del evento y enviarlo a telegram.
- Telegram: crearemos un grupo para recibir los avisos con el video/foto del evento.
Requisitos
Antes de empezar con las instalación vamos a hacer caso a la documentación publicada por los autores del proyecto y vamos a revisar los requisitos para poner en marcha el sistema.
El primer requisito y el más importante es que debemos tener alguna cámara IP que permita el streaming en RTSP y emita dicho streaming de vídeo en formato H.264.
Existen muchas marcas con diferentes precios y especificaciones pero mi recomendación es que si necesitas cámaras nuevas, compres las de la marca Tapo, la línea de IoT de TP-Link.
Estas cámaras tienen una API (local) que nos permite activar y desactivar el modo privacidad, que consiste en un apagado del sensor. Además, si adquirimos las cámaras tipo PTZ, a través de la API podremos mover físicamente la cámara para apuntar al techo o pared cuando estemos en casa y queramos privacidad físicamente asegurada.
En cualquier caso existen muchas otras marcas reconocidas como Hikvision o Amcrest que nos permitirán activar el streaming RTSP sin dificultad.
En mi caso tengo:
- Tapo C100: para zonas en interior en las que la privacidad no es tan importante y quiero una cámara pequeña y compacta.
- Tapo C200: para interior, cuando la privacidad es importante prefiero poder hacer que la cámara mire al techo cuando estoy en casa
- Tapo C310: para exteriores
Una vez que tengamos las cámaras tendremos que configurarlas y habilitar el streaming RTSP. Como depende mucho de cada marca, os dejo este enlace para hacerlo con las Tapo. Es importante que cuando configures dicho stream anotes el enlace y la resolución ya que necesitaremos esa información para crear el archivo de configuración de Frigate.
En cuanto al servidor, como en todos los post hasta la fecha, voy a dar por supuesto que tienes un servidor funcionando con unraid. De todas formas, si es tu primera vez aquí y no tienes un servidor en casa, quiero que sepas que existe la posibilidad de instalarlo sobre una RPI. Los pasos a seguir serán parecidos y si necesitas ayuda puedes pasarte pedirla en los comentarios o en nuestro canal de Discord.
En cualquier caso, en el servidor podremos hacer que todo funcione sobre la CPU sin gastar un solo euro, por ejemplo para probar, pero es recomendable equipar con un par de elementos de hardware específicos que eviten el uso continuado de CPU.
Si te ha picado la curiosidad y has leído lo que pone en el enlace a streaming de vídeo en formato H.264, te habrás dado cuenta de que se trata de una emisión de vídeo comprimida (para que el tráfico en la red sea la menor posible). Esto hace que nuestra aplicación tenga que descomprimir/decodificar el vídeo que le llegue de cada cámara, algo que no le gusta mucho a nuestra CPU. Para que el proceso sea más eficiente podemos utilizar la aceleración por hardware que han implementando los desarroladores. Dependiendo del tipo de hardware que tengamos en el servidor podremos usar la gráfica integrada de nuestra CPU Intel o AMD, o bien una gráfica dedicada de Nvidia. Para quede más sencillo vamos a instalar la versión que utiliza la gráfica integrada de la CPU ya que es bastante eficiente y no nos va a costar dinero ya que es un elemento que ya tenemos.
En cuanto a la inteligencia artificial para detectar objetos, este sistema utiliza modelos pre-entrenados con la librería TensorFlow, para el cual es conveniente de nuevo no utilizar la CPU ya que es poco eficiente. El modelo a ejecutar concretamente es de tipo TF-lite, para lo cual lo ideal es utilizar placas aceleradoras de IA de tipo TPU. Esto nos ofrecerá un rendimiento mucho mayor a coste energético mucho más bajo y además con mucha más velocidad. Esto quiere decir que cuando le pasemos un fotograma del vídeo al modelo de inteligencia artificial tardará mucho menos tiempo en responder si ha detectado el tipo de objeto que buscamos.
Las más conocidas son las Coral Edge, de las cuales con este sistema funcionan los modelos de PCIe (tanto el mini-PCI como los M.2) o USB.
Con esto ya tendríamos cubiertos los requisitos de hardware. En cuanto al software, como hemos visto en Funcionamiento, necesitas tener previamente instalado el broker de MQTT, Node-Red y Home Assistant.
Instalando Frigate sobre unraid con Docker
Antes de instalar el contenedor de frigate debemos crear un archivo de configuración mínimo en la ruta del servidor /appdata/frigate (tendrás que crear la ruta también). Simplemente puedes descargar este archivo y editarlo con la configuración que corresponda con tu instalación o seguir los pasos de la documentación oficial para crear uno. Más adelante, cuando tengamos todo funcionando podremos alterar este archivo para dejarlo a nuestro gusto.
Además, en caso de que nuestro TPU sea de tipo PCIe, demos instalar el driver correspondiente (en caso de que sea USB no es necesario). Para ello, vamos a la app store de unraid y buscamos por Coral:
Lo instalamos y cuando termine aceptamos:
Para proceder a la instalación de Frigate, como siempre, vamos a la app store de unraid y buscamos por Frigate. Como puedes ver, tenemos dos versiones, la primera para instalaciones con la aceleración de hardware usando la gráfica integrada de la CPU, y la segunda para instalaciones con una gráfica Nvidia para dicha tarea:
Si te fijas bien y haces click en el logo del programa, puedes ver que la persona que mantiene estas plantillas de unraid es, oh wait, soy yo!
Elegimos el primero (sin nvidia) y le damos a install y nos llevará a la pantalla de configuración del contenedor:
Aquí solo deberemos editar la entrada TPU Mapping de nuevo de acuerdo a si tenemos un TPU PCI o uno USB. Si es PCI debemos sustituir /dev/bus/usb por /dev/apex_0. También como siempre conviene que revises que no tienes los puertos 1935 y 5000 ocupados por otra APP. En caso de que así sea deberás cambiarlos por otros.
Aceptamos y esperamos a que arranque, si hemos hecho todo bien deberíamos pode acceder a http://IP-DE-UNRAID:5000 y deberemos ver la interfaz web:
Configurar Frigate para detección de personas y gatos
Ahora que ya tenemos el sistema funcionando vamos a seguir los pasos de la documentación para crear un archivo de configuración completo.
Como es bastante extenso, voy a comentar por encima los elementos básicos que debes configurar en un archivo de ejemplo .
Los elementos que podemos rastrear dependen del banco de imagenes o datatset con el que se haya entrenado el modelo. El modelo que usa frigate está entrenado con el dataset COCO y la lista de objetos que podemos rastrear la tienes aquí. Por ejemplo:
- person
- bicycle
- car
- motorcycle
- airplane
- bus
- train
- car
- boat
- traffic light
- fire hydrant
- stop sign
- parking meter
- bench
- bird
- cat
- dog
- horse
- sheep
- cow
- elephant
- bear
- zebra
- giraffe
- …
Además es importante que entiendas cómo se lanzan los eventos en base a la configuración de min_score y threshold. Por cada fotograma que le pasemos al modelo de TensorFlow nos devolverá una puntuación (confianza) si encuentra algún objeto de los que hemos configurado para rastrear. Cualquier puntuación por debajo de min_score será ignorada como un falso positivo. Si obtenemos puntuaciones por encima de ese valor empieza el rastreo del objeto. El threshold o umbral se basa en la media del historial de puntuaciones (3 valores) para un objeto rastreado. Tienes todo mejor explicado aquí.
Si la media de 3 puntuaciones está por encima del umbral configurado se considera que hemos detectado el objeto y se inicia un evento en Frigate. Cuando de nuevo, la media caiga por debajo del umbral consideraremos que el evento ha finalizado.
Estos eventos generarán un pequeño clip de vídeo y un snapshot con el fotograma con mayor puntuación de todo el evento.
Notificaciones de Telegram
Ahora que hemos configurado nuestra cámara para rastrear personas y gatos, vamos a crear un flujo en Node-Red para enviar notifiaciones de Telegram. Lo primero es crear un bot de telegram y un grupo al que vamos a invitar al bot.
En Telegram buscamos a BotFather y usando el comando /newbot sigues los pasos para crearlo,. Guardamos el TOKEN. Después creas un grupo de telegram y añades al bot a dicho grupo. Escribes un mensaje en grupo para iniciarlo. En el navegador abres este enlace rellenando el token que te haya dado para el BotFather: https://api.telegram.org/bot+Token/getUpdates y copias el chatID.
En node red instalamos el pallete node-red-contrib-telegrambot y después importamos este flow.
Tendrás que configurar el nodo de MQTT con la configuración de tu broker, el nodo de Home Assistant con tu instancia de HASS y el nodo de Telegram con los datos de tu bot. Además, en el nodo Create Message debes añadir el chatID del grupo que hayas creado en telegram.
Con esto tendremos notificaciones para cuando el gato se detecte estemos o no en casa y de personas si no estamos en casa. Nos llegará en el final del evento un vídeo y una foto con el bounding box y el porcentaje de la puntuación obtenida tipo:
Integración de Frigate en Home Assistant
Frigate tiene un componente que puedes instalar vía Hacs. Si buscas por Frigate podrás instalarlo. Luego si vas a integraciones y configuras el elemento Frigate tendremos no creará sensores y cámaras para poder añadirlas en un dashboard:
Control de Privacidad con la API de TAPO
En este caso también en Hacs tendremos la posibilidad de instalar el elemento Tapo:
Tendremos que configurar cada una de las cámaras ya que lo que hace este componente es enviar las peticiones al endpoint de cada una de las cámaras en vez de al cloud.
El elemento nos creará servicios en Home assitant para llamar al modo privacidad o a los movimientos PTZ de las cámaras que lo soporten. Con esto podremos crear automatizaciones por ejemplo en Node-Red para que el moto privacidad salte solo:
Nos vemos en el siguiente post.
Nota: algunos de los enlaces a productos o servicios pueden ser enlaces referidos con los que podemos obtener una comisión de venta.