4.18. Více senzorů

Hrstka OpenMV Cam kombinuje dva obrazové senzory na stejné desce – nejčastěji barevnou kameru spolu s tepelným senzorem FLIR® Lepton®, ale stejné uspořádání platí pro desky kombinující barvu a události a pro jakýkoli budoucí hardware se dvěma senzory. Každý senzor má své vlastní pixelové pole, svou vlastní řídicí sběrnici a běží svou vlastní pipeline svou vlastní snímkovou frekvencí. API CSI je pokrývá tím, že umožňuje aplikaci vytvořit jeden objekt CSI na fyzický senzor.

4.18.1. Výběr senzoru

Konstruktor CSI přijímá argument cid, který pojmenovává konkrétní senzor na desce. cid=-1 (výchozí) vybírá primární senzor; pojmenované konstanty cid vybírají sekundární senzor podle ID čipu:

import csi

csi_rgb     = csi.CSI()                    # primary colour sensor
csi_thermal = csi.CSI(cid=csi.LEPTON)      # FLIR® Lepton®

Každá instance vlastní svou vlastní konfiguraci – pixelový formát, framesize, ovládací prvky expozice / zisku, pool snímkového bufferu (frame buffer) – a je resetována, konfigurována a čtena nezávisle na ostatních. Konstanty pro podporované sekundární senzory (LEPTON, GENX320 a další uvedené v referenci CSI) pojmenovávají čip, který aplikace očekává na sekundárním portu; ovladač konstrukci nepovede, pokud se skutečný čip neshoduje.

4.18.2. Snímání z obou senzorů

Každý senzor běží svou snímací pipeline nezávisle na druhém – barevný senzor může dodávat třicet snímků za sekundu, zatímco Lepton® jich dodává devět. Přímočarý způsob, jak tento nesoulad zvládnout, je nechat řídit smyčku rychlejší senzor a číst pomalejší senzor neblokujícím způsobem, vzít cokoli je připraveno a iteraci přeskočit, když není nic:

import csi

csi_rgb     = csi.CSI()
csi_thermal = csi.CSI(cid=csi.LEPTON)

csi_rgb.reset()                        # powers the rail, pulses RESET
csi_rgb.pixformat(csi.RGB565)
csi_rgb.framesize(csi.QVGA)

csi_thermal.reset(hard=False)          # I2C reconfigure only
csi_thermal.pixformat(csi.GRAYSCALE)
csi_thermal.framesize(csi.QQVGA)

while True:
    rgb_img     = csi_rgb.snapshot()                  # blocks for next colour frame
    thermal_img = csi_thermal.snapshot(blocking=False)  # returns None if not ready
    if thermal_img is not None:
        # process aligned colour + thermal pair
        pass
    else:
        # process colour only on this iteration
        pass

Blokující snapshot() udává tempo smyčky; neblokující vrací nejnovější tepelný snímek, pokud od předchozího volání dorazil čerstvý, a jinak None. Aplikace běží dál snímkovou frekvencí barevného senzoru a získá tepelný snímek pokaždé, když jej Lepton® vyprodukuje.

Opačný vzor – dva blokující snímky za sebou – také funguje, ale smyčka pak běží pomalejší z frekvencí obou senzorů, přičemž pipeline rychlejšího senzoru se mezi iteracemi zastavuje. Vyberte si tu frekvenci, kterou navazující zpracování aplikace skutečně chce řídit.

4.18.3. Reset na sdílených napájecích větvích

Některé desky se dvěma senzory napájejí oba čipy z jediné napájecí větve nebo sdílejí resetovací linku. Na nich první reset() zvedne napájecí větev a vyšle puls na sdílený signál; následné resety na ostatních instancích CSI by měly předat hard=False, aby přeprogramovaly pouze svůj vlastní čip, aniž by protáhly souseda resetem:

csi_rgb.reset()                        # primary -- powers the rail, pulses RESET
csi_thermal.reset(hard=False)          # secondary -- I2C reconfigure only

hard=True na sekundárním senzoru v tomto uspořádání by jako vedlejší efekt znovu resetoval primární, čímž by se zrušilo veškeré nastavení, které aplikace již provedla. Referenční stránka pro každou desku se dvěma senzory uvádí, zda jsou napájecí větve sdílené.

4.18.4. Výběr zdroje streamu

Kamery se dvěma senzory mají dvě instance CSI, ale přesto jen jeden streamovací snímkový buffer (frame buffer) mezi nimi. Argument konstruktoru vybírá, snímky kterého senzoru napájejí náhled:

csi_rgb     = csi.CSI()                    # primary
csi_thermal = csi.CSI(cid=csi.LEPTON,
                      stream=True)         # preview source

stream=True činí pojmenovanou instanci zdrojem. Bez argumentu stream= je zdrojem primární senzor (cid=-1, výchozí); instance vytvořené s cid= sekundárního senzoru zůstávají na náhledu tiché, pokud není explicitně předáno stream=True. Volání snapshot() na nevybraném senzoru stále normálně snímají snímky do snímkových bufferů (frame buffer) onoho senzoru – jen neaktualizují náhled.