Cómo controlar aglomeraciones con Python, OpenCV e InfluxDB

· 5 min de lectura
Cómo controlar aglomeraciones con Python, OpenCV e InfluxDB


Como ya comenté hace un tiempo, estoy aprendiendo a desarrollar en Python, me parece que es un lenguaje súper fácil de interpretar y hasta ahora, no he encontrado un "no", al intentar hacer cosas con él. Estoy muy contento y sigo aprendiendo.

En este proceso de aprendizaje es que me puse a jugar con OpenCV para la detección de personas o más precisamente de rostros, no me tomó mucho tiempo entender cómo todo funcionaba y comencé a pensar en casos de usos y cómo combinarlos con otras tecnologías.

De esa búsqueda surgió la idea de integrarlo con InfluxDB para que cuente las veces que detecta un rostro, esto, con para que pueda aplicarse a algunos escenarios:

  • Registrar la cantidad de personas que pasan por una determinada entrada a un establecimiento en un determinado momento del día.
  • Lo mismo para autos, cambiando el modelo, en vez de contar rostros, podemos hacerlo con autos que pasan por una determinada avenida/calle.
  • Contar cuántas personas se paran frente a un producto determinado, con el fin de entender si es atractivo para nuestros clientes o no.
  • Medir la conversión en un restaurante: Contar cuánta gente entró, vs, cuántos platos se vendieron.
  • Lo mismo que para al anterior pero en otro tipo de tiendas. Cuántas personas entraron vs, cuántas operaciones de venta se tuvieron.
  • Controlar aglomeraciones en un determinado espacio.

Esté último me parece muy importante en el contexto que estamos viviendo, controlar aglomeraciones ha sido una de las tareas más complicadas y creo que un desarrollo sobre esto puedría ayudar.

Veamos un poco de código

El código de este proyecto lo pueden encontrar en este repositorio de Github:

xe-nvdk/crowd-counter
Crowd Counter is a Python App to count faces and ingest that data to InfluxDB. - xe-nvdk/crowd-counter

Los archivos relevantes aquí son:

  • live.py
  • influxdb_config.ini
  • haarcascade_frontalface_default.xml

El archivo live.py se ve de esta manera y lo que solo debemos hacer aquí es ajustar el nombre del bucket de InfluxDB donde todo se guardará.

Lo que deben modificar o dejar tal cual como esta es la linea:

bucket = "crowd-counter"
# This script will detect faces via your webcam and push the data to a InfluxDB instance.
# By Ignacio Van Droogenbroeck @hectorivand

import cv2

from datetime import datetime

from influxdb_client import Point, InfluxDBClient
from influxdb_client.client.write_api import SYNCHRONOUS

# Specify the InfluxDB bucket

bucket = "crowd-counter"

# In this file, you must set the parameters to connect to InfluxDB.

client = InfluxDBClient.from_config_file('influxdb_config.ini')

write_api = client.write_api(write_options=SYNCHRONOUS)
query_api = client.query_api()

cap = cv2.VideoCapture(0)

# Create the haar cascade
faceCascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

while(True):
	# Capture frame-by-frame
	ret, frame = cap.read()

	# Our operations on the frame come here
	gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

	# Detect faces in the image
	faces = faceCascade.detectMultiScale(
		gray,
		scaleFactor=1.2,
		minNeighbors=5,
		minSize=(30, 100)
	)

	# Write the quantity of faces detected on InfluxDB

	p = Point("public-count").tag("cameras", "entry").field("people", '{0}'.format(len(faces)))
	write_api.write(bucket=bucket, record=p)

	# Draw a rectangle around the faces
	for (x, y, w, h) in faces:
		cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

	# Display the resulting frame
	cv2.imshow('frame', frame)
	if cv2.waitKey(1) & 0xFF == ord('q'):
		break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

El otro archivo para configurar o pasar los valores como variables de entorno, es influxdb_config.ini

[influx2]
url=$INFLUX_URL
org=$INFLUX_ORG
token=$INFLUX_TOKEN
timeout=6000
verify_ssl=True

Si no tienes una instancia de InfluxDB OSS corriendo de manera local o hosteada en algún lado, te recomiendo que te abras una cuenta de InfluxDB Cloud, tiene un tier gratuito y para probar este tipo de soluciones es más que suficiente:

InfluxDB Cloud — the most powerful time series database as a service | InfluxData
InfluxDB Cloud provides the fastest way to access the most powerful time series database as a service. InfluxDB Cloud is much more than just a database.

El último archivo importante es el haarcascade_frontalface_default.xml, el cual nos va a dar los modelos para detectar las caras. Pueden leer sobre haarcascade y porque es una excelente opción para detectar objetos, sin tener que entrenar un modelo con Tensor Flow o algo parecido, en este enlace:

OpenCV: Cascade Classifier

Ahora bien, una vez que tenemos todo corriendo, podemos probarlo ejecutando...

$ python3 live.py

A ver...

Una vez que está corriendo, activará nuestra webcam y comenzará a contar rostros en mi instancia local de InfluxDB. En mi caso, estoy solo al momento de escribir este artículo, entonces para que el gráfico varíe, lo que hice fue dejar de mirar la cámara en un momento.

Como ven, no parece ser muy complicado, lo mismo podríamos hacer para controlar el tránsito en un determinado momento en una autopista o avenida.

Bueno, muy lindo todo, vos te ves divino, los autos, bárbaro, pero mostrame cómo esto me ayuda a controlar aglomeraciones y para responderte a eso, te dejo esta captura.

En este caso, el script detecto 110 caras y llevó ese dato a InfluxDB y de esta manera es cómo podemos hacer control de aglomeraciones.

Particularmente use un video porque no tengo una aglomeración de gente en mi casa, pero con una cámara sería el mismo.

Para ir cerrando

Este software no es perfecto y es parte de mi aprendizaje, así que si encuentran errores o cosas que se pueden mejorar, los invito a contribuir a este repositorio:

xe-nvdk/crowd-counter
Crowd Counter is a Python App to count faces and ingest that data to InfluxDB. - xe-nvdk/crowd-counter

Espero que les haya gustado y si después de leer esto decides comenzar a usarlo, déjame saber cómo lo haces.


baehost