Termocamera multispettrale (OV5640)¶
La variante OV5640 del modulo Multispectral Thermal Camera abbina un sensore a colori rolling-shutter da 5MP a un nucleo termico FLIR Lepton, così la OpenMV Cam può eseguire affiancate pipeline di visione a colori ad alta risoluzione e pipeline termiche.
Per il datasheet completo, le foto e le informazioni d’ordine, consulta la pagina prodotto Multispectral Thermal.
Nota
Supportato solo sulla OpenMV Cam RT1062.
Punti salienti¶
OV5640: rolling shutter da 5MP per colori a risoluzione più elevata
Accetta nuclei termici FLIR Lepton 1.x / 2.x / 3.x
Elaborazione termica + a colori simultanea su un unico modulo
Vede nel buio totale, supporta la misurazione della temperatura
Autofocus e apertura F2.0 sul sensore a colori
Utilizzo¶
Il sensore a colori e la FLIR Lepton ottengono ciascuno la propria istanza csi.CSI. La prima chiamata usa per impostazione predefinita il sensore primario (la OV5640); la seconda si associa alla Lepton passando cid= csi.LEPTON. Esegui un hard-reset del sensore a colori con csi.CSI.reset (hard=True) per attivarne l’alimentazione, e configura la Lepton con hard=False in modo che il suo driver si limiti a riprogrammare il chip senza riattivare il reset.
csi.CSI.framesize ( csi.QVGA ) adatta l’uscita della Lepton alla camera a colori, così ogni snapshot() restituisce un frame da 320x240. Il driver Lepton effettua internamente l’upscaling del suo frame nativo da 80x60 (1.x/2.x) o 160x120 (3.x) alla dimensione richiesta: a QVGA ogni pixel della Lepton copre una cella 4x4 o 2x2 sul frame a colori.
Due buffer di lavoro restano costanti per tutto il ciclo dei frame: una palette alpha da 256x1 memorizzata come image.Image, in modo che i pixel freddi della Lepton diventino trasparenti e quelli caldi opachi (la rampa quadratica attenua i dettagli di sfondo senza schiacciare i toni intermedi), e un frame buffer della Lepton pre-allocato con image.Image, così che csi.CSI.snapshot (blocking=False, image=...) possa riempirlo sul posto a ogni iterazione senza riallocare:
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())
Ogni iterazione acquisisce uno snapshot a colori bloccante e uno snapshot Lepton non bloccante: la Lepton funziona a 9 Hz, quindi bloccarsi su di essa rallenterebbe la pipeline a colori. Image.draw_image poi compone i due: color_palette= image.PALETTE_IRONBOW mappa la scala di grigi della Lepton su una rampa di colori caldi in stile FLIR, alpha_palette= fonde ogni pixel usando la mappa alpha quadratica, e hint= image.BILINEAR ammorbidisce l’upscaling.
La OV5640 ha un obiettivo con autofocus ad attuatore voice-coil. Attiva una singola passata di autofocus sulla camera a colori tramite csi.CSI.ioctl con csi.IOCTL_TRIGGER_AUTO_FOCUS: il sensore sposta il motore della messa a fuoco una volta e si blocca su qualunque cosa abbia di fronte:
csi0.ioctl(csi.IOCTL_TRIGGER_AUTO_FOCUS)
Riemetti l’ioctl ogni volta che la scena cambia: l’autofocus è a colpo singolo, non continuo.
Misurazione della temperatura¶
Le Lepton radiometriche (Lepton 2.5 / 3.5) riportano dati di temperatura per pixel calibrati. Abilita la modalità di misurazione tramite csi.CSI.ioctl con csi.IOCTL_LEPTON_SET_MODE, poi limita la finestra di temperatura con csi.IOCTL_LEPTON_SET_RANGE (min_celsius, max_celsius). Il driver Lepton mappa linearmente il valore di pixel in scala di grigi 0 su min_celsius e 255 su max_celsius, così ogni pixel diventa una ricerca di temperatura all’interno della finestra configurata. I pixel più freddi di min_celsius saturano a 0, quelli più caldi di max_celsius saturano a 255.
csi.IOCTL_LEPTON_SET_MODE accetta due flag. Il primo attiva la misurazione; il secondo seleziona l’intervallo di temperatura del sensore:
Intervallo basso —
(True, False)— campo del sensore da-10 °Ca+140 °C(scene a scala ambiente). Limita la finestra all’area di interesse, ad es.(20.0, 40.0)per il tracciamento del calore corporeo:csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, False) csi1.ioctl(csi.IOCTL_LEPTON_SET_RANGE, 20.0, 40.0)
Intervallo alto —
(True, True)— campo del sensore da-10 °Ca~+450 °Ctipico (~+400 °Ca temperatura ambiente) per oggetti caldi. Limita ad es. a(0.0, 400.0)per il tracciamento di forni o elementi caldi:csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, True) csi1.ioctl(csi.IOCTL_LEPTON_SET_RANGE, 0.0, 400.0)
Per riconvertire un pixel in scala di grigi in gradi Celsius:
def p_to_temp(p, min_t, max_t):
return (p * (max_t - min_t)) / 255.0 + min_t
Questo funziona su singoli pixel o su statistiche aggregate (ad es. stats.mean() da Image.get_statistics) all’interno di una ROI quando si individuano regioni calde/fredde con Image.find_blobs.