Multispektral termisk (PAG7936)¶
PAG7936-varianten av Multispectral Thermal Camera Module kombinerar en 1 MP global-shutter-färgsensor med en FLIR Lepton termisk kärna, så att OpenMV Cam kan köra färgseende- och termiska pipelines sida vid sida.
För fullständigt datablad, foton och beställning, se produktsidan för Multispectral Thermal.
Anteckning
Stöds endast på OpenMV N6.
Höjdpunkter¶
PAG7936: 1 MP global shutter
Accepterar FLIR Lepton 1.x / 2.x / 3.x termiska kärnor
Samtidig termisk- och färgbehandling på en enda modul
Ser i fullständigt mörker, stöder temperaturmätning
Global shutter hanterar snabb rörelse utan rolling-shutter-artefakter
Användning¶
Färgsensorn och FLIR Lepton får var sin egen csi.CSI-instans. Det första anropet använder som standard den primära sensorn (PAG7936); det andra binder till Lepton genom att skicka cid= csi.LEPTON. Gör en hård återställning av färgsensorn med csi.CSI.reset (hard=True) för att få upp spänningen, och konfigurera Lepton med hard=False så att dess drivrutin endast omprogrammerar chipet utan att växla återställningen på nytt.
csi.CSI.framesize ( csi.QVGA ) anpassar Lepton-utmatningen till färgkameran, så att varje snapshot() returnerar en 320x240-bildruta. Lepton-drivrutinen skalar internt upp sin ursprungliga bildruta på 80x60 (1.x/2.x) eller 160x120 (3.x) till den begärda storleken — vid QVGA täcker varje Lepton-pixel en cell på 4x4 eller 2x2 i färgbildrutan.
Två arbetsbuffertar förblir konstanta genom bildrutans loop — en 256x1 alfa-palett lagrad som en image.Image så att svala Lepton-pixlar blir transparenta och heta pixlar blir ogenomskinliga (den kvadratiska rampen dämpar bakgrundsdetaljer utan att klämma ihop mellanområdet), och en Lepton-bildbuffert som förallokeras med image.Image så att csi.CSI.snapshot (blocking=False, image=...) kan fylla den på plats vid varje iteration utan omallokering:
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())
Varje iteration tar en blockerande färgstillbild och en icke-blockerande Lepton-stillbild — Lepton körs vid 9 Hz, så att blockera på den skulle strypa färgpipelinen. Image.draw_image sammanfogar sedan de två: color_palette= image.PALETTE_IRONBOW mappar Leptons gråskala till en varm färgramp i FLIR-stil, alpha_palette= blandar varje pixel med hjälp av den kvadratiska alfakartan, och hint= image.BILINEAR jämnar ut uppskalningen.
Temperaturmätning¶
Radiometriska Lepton-enheter (Lepton 2.5 / 3.5) rapporterar kalibrerade temperaturdata per pixel. Aktivera mätläge via csi.CSI.ioctl med csi.IOCTL_LEPTON_SET_MODE, och begränsa sedan temperaturfönstret med csi.IOCTL_LEPTON_SET_RANGE (min_celsius, max_celsius). Lepton-drivrutinen mappar linjärt gråskalepixelvärdet 0 till min_celsius och 255 till max_celsius, så att varje pixel blir en temperaturuppslagning inom det konfigurerade fönstret. Pixlar som är kallare än min_celsius mättas vid 0, pixlar som är varmare än max_celsius mättas vid 255.
csi.IOCTL_LEPTON_SET_MODE tar två flaggor. Den första aktiverar mätning; den andra väljer sensorns temperaturområde:
Lågt område —
(True, False)— sensorspann-10 °Ctill+140 °C(rumsskaliga scener). Begränsa fönstret till intresseområdet, t.ex.(20.0, 40.0)för kroppsvärmespårning:csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, False) csi1.ioctl(csi.IOCTL_LEPTON_SET_RANGE, 20.0, 40.0)
Högt område —
(True, True)— sensorspann-10 °Ctill typiskt~+450 °C(~+400 °Cvid rumstemperatur) för heta objekt. Begränsa till t.ex.(0.0, 400.0)för spårning av ugn eller heta element:csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, True) csi1.ioctl(csi.IOCTL_LEPTON_SET_RANGE, 0.0, 400.0)
För att konvertera en gråskalepixel tillbaka till Celsius:
def p_to_temp(p, min_t, max_t):
return (p * (max_t - min_t)) / 255.0 + min_t
Detta fungerar på enskilda pixlar eller på aggregerad statistik (t.ex. stats.mean() från Image.get_statistics) inom ett ROI när heta/svala regioner lokaliseras med Image.find_blobs.
GPU-accelererad inriktning¶
Image.draw_image accepterar ett transform=-argument — en 3x3 homografimatris som en 2D ulab.numpy-array. På OpenMV N6 kör GPU:n projektionen per pixel under samma rityta, så att Lepton-bildrutan kan omriktas mot färgkamerans perspektiv utan en separat förvrängningspassning. Kalibrera matrisen per kamera med verktyget thermal-overlay-calibration
import time
import csi
import image
from ulab import numpy as np
import math
# Calibration matrix from the thermal-overlay-calibration tool.
m = np.array([
[3.704807, 0.257018, 37.260564],
[0.052147, 3.609977, -7.831831],
[0.000294, 0.000552, 1.000000],
])
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.VGA)
csi1 = csi.CSI(cid=csi.LEPTON)
csi1.reset(hard=False) # no hardware reset - just configure lepton
csi1.pixformat(csi.GRAYSCALE)
csi1.framesize(csi.QQVGA)
# 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,
transform=m)
print(clock.fps())
Observera att denna variant kör färgkameran vid csi.VGA (640x480) och Lepton vid csi.QQVGA (160x120) — homografin projicerar den mindre Lepton-bildrutan in i den större färgbildrutan som en del av ritningen, så uppskalningsfaktorn är inbakad i själva matrisen i stället för att tillämpas separat.