Multispectral térmica (OV5640)¶
La variante OV5640 del módulo de cámara Multispectral Thermal combina un sensor de color de 5MP de obturador rodante (rolling shutter) con un núcleo térmico FLIR Lepton, de modo que la OpenMV Cam puede ejecutar simultáneamente cadenas de visión de color de alta resolución y cadenas térmicas.
Para ver la hoja de datos completa, fotos e información de compra, consulta la página del producto Multispectral Thermal.
Nota
Compatible únicamente con la OpenMV Cam RT1062.
Aspectos destacados¶
OV5640: obturador rodante de 5MP para color de mayor resolución
Admite núcleos térmicos FLIR Lepton 1.x / 2.x / 3.x
Procesamiento térmico + color simultáneo en un solo módulo
Ve en completa oscuridad y admite la medición de temperatura
Enfoque automático y apertura F2.0 en el sensor de color
Uso¶
El sensor de color y el FLIR Lepton obtienen cada uno su propia instancia de csi.CSI. La primera llamada toma por defecto el sensor principal (el OV5640); la segunda se enlaza al Lepton pasando cid= csi.LEPTON. Reinicia físicamente el sensor de color con csi.CSI.reset (hard=True) para activar el riel de alimentación, y configura el Lepton con hard=False para que su controlador solo reprograme el chip sin volver a conmutar el reinicio.
csi.CSI.framesize ( csi.QVGA ) ajusta la salida del Lepton a la cámara de color, de modo que cada snapshot() devuelve un fotograma de 320x240. El controlador del Lepton aumenta internamente la escala de su fotograma nativo de 80x60 (1.x/2.x) o 160x120 (3.x) al tamaño solicitado: en QVGA cada píxel del Lepton cubre una celda de 4x4 o 2x2 en el fotograma de color.
Dos búferes auxiliares permanecen constantes durante el bucle de fotogramas: una paleta alfa de 256x1 almacenada como una image.Image para que los píxeles fríos del Lepton se vuelvan transparentes y los píxeles calientes se vuelvan opacos (la rampa cuadrática suprime el detalle de fondo sin aplastar el rango medio), y un búfer de fotogramas del Lepton preasignado con image.Image para que csi.CSI.snapshot (blocking=False, image=...) pueda rellenarlo en el sitio en cada iteración sin reasignar memoria:
import time
import csi
import image
import math
alpha_pal = image.Image(256, 1, image.GRAYSCALE)
for i in range(256):
alpha_pal[i] = int(math.pow((i / 255), 2) * 255)
# Setup the color camera sensor.
csi0 = csi.CSI()
csi0.reset(hard=True) # force hardware reset.
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
csi1 = csi.CSI(cid=csi.LEPTON)
csi1.reset(hard=False) # no hardware reset - just configure lepton
csi1.pixformat(csi.GRAYSCALE)
csi1.framesize(csi.QVGA)
# Optional temperature range controls for the LEPTON.
# csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, False)
# csi1.ioctl(csi.IOCTL_LEPTON_SET_RANGE, 20.0, 40.0)
clock = time.clock()
img1 = image.Image(csi1.width(), csi1.height(), csi1.pixformat())
while True:
clock.tick()
img0 = csi0.snapshot()
csi1.snapshot(blocking=False, image=img1)
img0.draw_image(img1, 0, 0, color_palette=image.PALETTE_IRONBOW,
alpha_palette=alpha_pal,
hint=image.BILINEAR)
print(clock.fps())
Cada iteración toma una captura de color bloqueante y una captura del Lepton no bloqueante: el Lepton funciona a 9 Hz, por lo que bloquearse en él limitaría la cadena de color. A continuación, Image.draw_image compone las dos: color_palette= image.PALETTE_IRONBOW asigna la escala de grises del Lepton a una rampa de color cálido de estilo FLIR, alpha_palette= mezcla cada píxel usando el mapa alfa cuadrático, y hint= image.BILINEAR suaviza el aumento de escala.
El OV5640 tiene una lente de enfoque automático con actuador de bobina de voz. Activa una única pasada de enfoque automático en la cámara de color mediante csi.CSI.ioctl con csi.IOCTL_TRIGGER_AUTO_FOCUS: el sensor barre el motor de enfoque una vez y se fija en lo que tenga delante:
csi0.ioctl(csi.IOCTL_TRIGGER_AUTO_FOCUS)
Vuelve a emitir el ioctl cada vez que cambie la escena: el enfoque automático es de un solo disparo, no continuo.
Medición de temperatura¶
Los Lepton radiométricos (Lepton 2.5 / 3.5) informan datos de temperatura calibrados por píxel. Habilita el modo de medición mediante csi.CSI.ioctl con csi.IOCTL_LEPTON_SET_MODE, y luego acota la ventana de temperatura con csi.IOCTL_LEPTON_SET_RANGE (min_celsius, max_celsius). El controlador del Lepton asigna linealmente el valor de píxel en escala de grises 0 a min_celsius y 255 a max_celsius, de modo que cada píxel se convierte en una consulta de temperatura dentro de la ventana configurada. Los píxeles más fríos que min_celsius se saturan en 0 y los píxeles más calientes que max_celsius se saturan en 255.
csi.IOCTL_LEPTON_SET_MODE toma dos indicadores. El primero activa la medición; el segundo selecciona el rango de temperatura del sensor:
Rango bajo —
(True, False)— alcance del sensor de-10 °Ca+140 °C(escenas a escala de habitación). Acota la ventana al área de interés, p. ej.(20.0, 40.0)para el seguimiento del calor corporal:csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, False) csi1.ioctl(csi.IOCTL_LEPTON_SET_RANGE, 20.0, 40.0)
Rango alto —
(True, True)— alcance del sensor de-10 °Ca~+450 °Ctípico (~+400 °Ca temperatura ambiente) para objetos calientes. Acota a, p. ej.,(0.0, 400.0)para el seguimiento de hornos o elementos calientes:csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, True) csi1.ioctl(csi.IOCTL_LEPTON_SET_RANGE, 0.0, 400.0)
Para convertir un píxel en escala de grises de nuevo a grados Celsius:
def p_to_temp(p, min_t, max_t):
return (p * (max_t - min_t)) / 255.0 + min_t
Esto funciona en píxeles individuales o en estadísticas agregadas (p. ej. stats.mean() de Image.get_statistics) dentro de una ROI al localizar regiones calientes/frías con Image.find_blobs.