Multispektrální termální (PAG7936)

Varianta PAG7936 modulu Multispectral Thermal Camera Module kombinuje 1MP barevný senzor s global shutter a termální jádro FLIR Lepton, takže OpenMV Cam dokáže souběžně provozovat barevné vidění i termální pipeline.

Multispektrální termální (PAG7936)

Kompletní datasheet, fotografie a informace o objednání najdete na produktové stránce Multispectral Thermal.

Poznámka

Podporováno pouze na OpenMV N6.

Hlavní vlastnosti

  • PAG7936: 1MP global shutter

  • Přijímá termální jádra FLIR Lepton 1.x / 2.x / 3.x

  • Současné zpracování termálního i barevného obrazu na jednom modulu

  • Vidí v úplné tmě, podporuje měření teploty

  • Global shutter zvládá rychlý pohyb bez artefaktů rolling shutter

Použití

Barevný senzor a FLIR Lepton mají každý vlastní instanci csi.CSI. První volání se ve výchozím nastavení váže na primární senzor (PAG7936); druhé se připojí k Leptonu předáním cid= csi.LEPTON. Proveďte hardwarový reset barevného senzoru pomocí csi.CSI.reset (hard=True) pro zapnutí napájecí větve a Lepton nakonfigurujte s hard=False, aby jeho ovladač pouze přeprogramoval čip bez opětovného přepnutí resetu.

csi.CSI.framesize ( csi.QVGA ) sladí výstup Leptonu s barevnou kamerou, takže každý snapshot() vrací snímek 320x240. Ovladač Leptonu interně převzorkuje jeho nativní snímek 80x60 (1.x/2.x) nebo 160x120 (3.x) na požadovanou velikost — při QVGA pokrývá každý pixel Leptonu buňku 4x4 nebo 2x2 na barevném snímku.

Dva pomocné buffery zůstávají v průběhu smyčky snímků konstantní — alfa paleta 256x1 uložená jako image.Image, díky níž se chladné pixely Leptonu stanou průhlednými a horké pixely neprůhlednými (kvadratická rampa potlačuje detaily pozadí, aniž by potlačila střední pásmo), a frame buffer Leptonu předalokovaný pomocí image.Image, takže csi.CSI.snapshot (blocking=False, image=...) jej může v každé iteraci naplnit na místě bez opětovné alokace:

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())

Každá iterace pořídí blokující barevný snímek a neblokující snímek Leptonu — Lepton běží na 9 Hz, takže blokování na něm by zpomalilo barevnou pipeline. Image.draw_image poté oba snímky složí: color_palette= image.PALETTE_IRONBOW mapuje stupně šedi Leptonu na teplou barevnou rampu ve stylu FLIR, alpha_palette= mísí každý pixel pomocí kvadratické alfa mapy a hint= image.BILINEAR vyhladí převzorkování.

Měření teploty

Radiometrické Leptony (Lepton 2.5 / 3.5) poskytují kalibrovaná teplotní data pro každý pixel. Zapněte režim měření pomocí csi.CSI.ioctl s csi.IOCTL_LEPTON_SET_MODE a poté omezte teplotní okno pomocí csi.IOCTL_LEPTON_SET_RANGE (min_celsius, max_celsius). Ovladač Leptonu lineárně mapuje hodnotu pixelu ve stupních šedi 0 na min_celsius a 255 na max_celsius, takže každý pixel se stává vyhledáním teploty v rámci nakonfigurovaného okna. Pixely chladnější než min_celsius saturují na 0, pixely teplejší než max_celsius saturují na 255.

csi.IOCTL_LEPTON_SET_MODE přijímá dva příznaky. První zapíná měření; druhý vybírá teplotní rozsah senzoru:

  • Nízký rozsah(True, False) — rozsah senzoru -10 °C+140 °C (scény velikosti místnosti). Omezte okno na oblast zájmu, např. (20.0, 40.0) pro sledování tělesného tepla:

    csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, False)
    csi1.ioctl(csi.IOCTL_LEPTON_SET_RANGE, 20.0, 40.0)
    
  • Vysoký rozsah(True, True) — rozsah senzoru typicky -10 °C~+450 °C (~+400 °C při pokojové teplotě) pro horké objekty. Omezte např. na (0.0, 400.0) pro sledování pece nebo horkých prvků:

    csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, True)
    csi1.ioctl(csi.IOCTL_LEPTON_SET_RANGE, 0.0, 400.0)
    

Pro převod pixelu ve stupních šedi zpět na stupně Celsia:

def p_to_temp(p, min_t, max_t):
    return (p * (max_t - min_t)) / 255.0 + min_t

Toto funguje na jednotlivých pixelech nebo na agregovaných statistikách (např. stats.mean() z Image.get_statistics) uvnitř ROI při lokalizaci horkých/chladných oblastí pomocí Image.find_blobs.

Zarovnání akcelerované GPU

Image.draw_image přijímá argument transform= — homografickou matici 3x3 jako 2-D ulab.numpy pole. Na OpenMV N6 GPU provádí projekci po jednotlivých pixelech během téhož vykreslení, takže snímek Leptonu lze znovu zarovnat s perspektivou barevné kamery bez samostatného warp průchodu. Matici kalibrujte pro každou kameru pomocí nástroje 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())

Mějte na paměti, že tato varianta provozuje barevnou kameru v csi.VGA (640x480) a Lepton v csi.QQVGA (160x120) — homografie promítá menší snímek Leptonu do většího barevného snímku jako součást vykreslení, takže faktor převzorkování je zapečen přímo do matice, místo aby se aplikoval zvlášť.