Búsqueda de personas con Lepton

Este es un tutorial para implementar un algoritmo básico de búsqueda de personas con una cámara FLIR Lepton utilizando la librería de visión artificial de código abierto OpenCV.

El objetivo

Las cámaras térmicas son excelentes para encontrar mamíferos en casi cualquier condición de iluminación. Como ejercicio para explorar lo que pueden hacer, intentemos encontrar gente en el campo de visión de Lepton y pongamos un contorno a su alrededor con OpenCV.

Las herramientas

Las herramientas que necesitará:

  1. Un Lepton
  2. Una tarjeta PureThermal
  3. Un ambiente de Python 2.7 con enlaces OpenCV instalados. Esto se puede configurar para Windows, OSX o Linux.
  4. PIL si desea poder guardar imágenes.

La configuración

Siga un tutorial para su plataforma específica y configurar el ambiente de Python y OpenCV instalado. Cuando haya terminado, compruebe que todo funciona viendo transmisión de una cámara web.

import cv2
cv2.namedWindow("preview")
cameraID = 0
vc = cv2.VideoCapture(cameraID)

if vc.isOpened(): # intente obtener el primer marco
rval, frame = vc.read()
De lo contrario:
rval = Falso

mientras rval:
cv2.imshow("preview", frame)
rval, frame = vc.read()
clave = cv2.waitKey(20)
if la clave == 27: # exit on ESC
break

Esto debería mostrar la transmisión Si tiene una cámara web conectada o integrada en su computadora, es posible que tenga que cambiar la identificación de la cámara a un valor distinto a 0. En mi máquina de desarrollo, la identificación de la tarjeta PureThermal es 1.

El alcance

El código de captura de la cámara web OpenCV no es capaz de capturar datos térmicos radiométricos, lo que sería un formato ideal para contar personas pero sí permite capturar la alimentación coloreada de una tarjeta PureThermal, que será lo suficientemente bueno para dibujar contornos con un poco de preprocesamiento.

Específicamente, los humanos tienden a mostrarse muy brillantes en la paleta de colores predeterminada, por lo que convertir las imágenes RGB a HSV y mirar el canal V proporciona una imagen bastante clara de dónde están los objetos de temperatura corporal en la escena.

Pruébelo cambiando cv2.imshow("preview", frame) con el siguiente:

frame_hsv = cv2.cvtColor(frame, cv2.COLOR_RGB2HSV)
frame_v = frame_hsv[:,:,2]
cv2.imshow("preview", frame_v)

Ahora es bastante obvio en dónde están los humanos y tenemos algo con lo que podemos hacer la vista de computadora.

Introduzca OpenCV

OpenCV es una librería de vista de computadora muy popular para C++ con enlaces a Python. Ofrece una amplia variedad de operaciones de vista de computadora comunes, que utilizaremos para dibujar nuestros contornos.

La detección de bordes inteligente es donde comenzaremos. Es una técnica sólida para encontrar bordes en una imagen.

Puede ver los bordes que detecta OpenCV con este código:

thresh = 50
edges = cv2.Canny(frame_v,thresh,thresh*2, L2gradient=True)
cv2.imshow("preview", edges)

Sin embargo, esto no se ve bien. La detección de bordes capta demasiado ruido de alta frecuencia y lo confunde con los bordes. Un pequeño suavizado de imagen debería solucionarlo. Utilizaremos un método para suavizar la imagen y conservar los bordes llamado filtro bilateral. Es como un difuminado gaussiano pero tiene menos impacto en los bordes que buscamos en primer lugar.

blurredBrightness = cv2.bilateralFilter(frame_v,9,150,150)
thresh = 70
edges = cv2.Canny(blurredBrightness,thresh,thresh*2, L2gradient=True)
cv2.imshow("preview", edges)

Esto tiene un aspecto mucho mejor, pero todavía hay margen de mejora. Vamos a intentar reducir cosas como las luces que se delinean como personas. Esto es complicado pero OpenCV proporciona una manera de hacerlo. En primer lugar, crearemos una imagen binaria estableciendo el umbral de la imagen original y poniendo un 1 en donde el píxel esté caliente, y un 0 en donde no lo esté. Después utilizaremos OpenCV para erosionar en las masas amorfas de los número 1 hechos en esa operación. Después de eso, volveremos a extender esas masas amorfas para que tengan aproximadamente el mismo tamaño que antes.

_,mask = cv2.threshold(blurredBrightness,200,1,cv2.THRESH_BINARY)
erodeSize = 5
dilateSize = 7
import numpy as np
eroded = cv2.erode(mask, np.ones((erodeSize, erodeSize)))
mask = cv2.dilate(eroded, np.ones((dilateSize, dilateSize)))

Después de la erosión y la dilatación, la imagen binaria se deja básicamente igual pero con todas las formas pequeñas eliminadas. Eso es exactamente lo que queremos. Ahora podemos usarlo para ocultar todos los bordes que pertenecían a formas pequeñas.

Observemos cómo se ve cuando se aplica a los bordes detectados.

¡No está mal! Además, también parece bastante bien superpuesta en la imagen origen.

El código final tiene un aspecto parecido al siguiente. Es posible que necesite ajustar las constantes a su gusto. OpenCV proporciona una amplia variedad de herramientas que podría utilizar para mejorar los resultados a sus necesidades específicas.

import cv2
import numpy as np
cv2.namedWindow("preview")
cameraID = 0
vc = cv2.VideoCapture(cameraID)

if vc.isOpened(): # try to get the first frame
rval, frame = vc.read()
De lo contrario:
rval = Falso

mientras rval:
frame_v = cv2.cvtColor(frame, cv2.COLOR_RGB2HSV)[:,:,2]

blurredBrightness = cv2.bilateralFilter(frame_v,9,150,150)
thresh = 50
edges = cv2.Canny(blurredBrightness,thresh,thresh*2, L2gradient=True)

_,mask = cv2.threshold(blurredBrightness,200,1,cv2.THRESH_BINARY)
erodeSize = 5
dilateSize = 7
eroded = cv2.erode(mask, np.ones((erodeSize, erodeSize)))
mask = cv2.dilate(eroded, np.ones((dilateSize, dilateSize)))

cv2.imshow("preview", cv2.resize(cv2.cvtColor(mask*edges, cv2.COLOR_GRAY2RGB) | frame, (640, 480), interpolation = cv2.INTER_CUBIC))

val, trama = vc.read()
clave = cv2.waitKey(20)
if la clave == 27: # exit on ESC
break

Artículos relacionados