4.18. Meerdere sensoren¶
Een handvol OpenMV Cams koppelen twee beeldsensoren op hetzelfde bord – meestal een kleurcamera naast een FLIR® Lepton® thermische sensor, maar dezelfde vorm geldt voor de kleur-plus-event-borden en alle toekomstige dual-sensorhardware. Elke sensor heeft zijn eigen pixelarray, zijn eigen besturingsbus, en draait zijn eigen pijplijn op zijn eigen framesnelheid. De CSI-API breidt zich uit om ze te dekken door de toepassing één CSI-object per fysieke sensor te laten instantiëren.
4.18.1. Selecteren welke sensor¶
De CSI-constructor neemt een cid-argument dat een specifieke sensor op het bord benoemt. cid=-1 (de standaard) selecteert de primaire sensor; de benoemde cid-constanten selecteren een secundaire op chip-ID:
import csi
csi_rgb = csi.CSI() # primary colour sensor
csi_thermal = csi.CSI(cid=csi.LEPTON) # FLIR® Lepton®
Elke instantie bezit zijn eigen configuratie – pixelformaat, framesize, belichtings-/versterkingsknoppen, framebufferpool – en wordt onafhankelijk van de andere gereset, geconfigureerd en uitgelezen. De constanten voor de ondersteunde secundaire sensoren (LEPTON, GENX320 en de andere die in de CSI-referentie staan) benoemen de chip die de toepassing op de secundaire poort verwacht; de driver laat de constructie mislukken als de werkelijke chip niet overeenkomt.
4.18.2. Vastleggen vanaf beide sensoren¶
Elke sensor draait zijn opnamepijplijn onafhankelijk van de andere – de kleursensor levert wellicht dertig frames per seconde terwijl de Lepton® er negen levert. De eenvoudigste manier om die mismatch aan te pakken is de snellere sensor de lus te laten aandrijven en de tragere sensor niet-blokkerend uit te lezen, waarbij genomen wordt wat klaar is en de iteratie wordt overgeslagen wanneer er niets is:
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
De blokkerende snapshot() bepaalt het tempo van de lus; de niet-blokkerende retourneert het meest recente thermische frame wanneer er sinds de vorige aanroep een vers frame is binnengekomen, en anders None. De toepassing blijft draaien op de framesnelheid van de kleursensor en krijgt een thermisch frame wanneer de Lepton® er een produceert.
Het tegenovergestelde patroon – twee blokkerende snapshots achter elkaar – werkt ook, maar de lus draait dan op de tragere van de twee sensorsnelheden, waarbij de pijplijn van de snellere sensor tussen iteraties stilvalt. Kies welke snelheid de downstreamverwerking van de toepassing daadwerkelijk wil aandrijven.
4.18.4. De streambron selecteren¶
Camera’s met twee sensoren hebben twee CSI-instanties, maar nog steeds slechts één stream-framebuffer ertussen. Een constructorargument kiest welke frames van welke sensor de preview voeden:
csi_rgb = csi.CSI() # primary
csi_thermal = csi.CSI(cid=csi.LEPTON,
stream=True) # preview source
stream=True maakt de benoemde instantie de bron. Zonder stream=-argument is de primaire sensor (cid=-1, de standaard) de bron; instanties die met cid= van een secundaire sensor zijn gebouwd blijven stil op de preview tenzij stream=True expliciet wordt doorgegeven. Aanroepen van snapshot() op de niet-geselecteerde sensor leggen nog steeds normaal frames vast in de framebuffers van die sensor – ze werken alleen de preview niet bij.