4.18. Flera sensorer¶
Ett fåtal OpenMV Cam-modeller parar två bildsensorer på samma kort – vanligast en färgkamera bredvid en FLIR® Lepton® värmesensor, men samma form gäller för kort med färg plus händelse och eventuell framtida hårdvara med dubbla sensorer. Varje sensor har sin egen pixelmatris, sin egen styrbuss och kör sin egen pipeline i sin egen bildfrekvens. CSI-API:t utökas för att täcka dem genom att låta applikationen instansiera ett CSI-objekt per fysisk sensor.
4.18.1. Välja vilken sensor¶
CSI-konstruktorn tar ett cid-argument som namnger en specifik sensor på kortet. cid=-1 (standard) väljer den primära sensorn; de namngivna cid-konstanterna väljer en sekundär via chip-ID:
import csi
csi_rgb = csi.CSI() # primary colour sensor
csi_thermal = csi.CSI(cid=csi.LEPTON) # FLIR® Lepton®
Varje instans äger sin egen konfiguration – pixelformat, framesize, exponerings- / förstärkningsrattar, bildbuffertpool – och återställs, konfigureras och läses oberoende av den andra. Konstanterna för de stödda sekundära sensorerna (LEPTON, GENX320 och de andra som listas i CSI-referensen) namnger det chip applikationen förväntar sig på den sekundära porten; drivrutinen låter konstruktionen misslyckas om det faktiska chippet inte matchar.
4.18.2. Tagning från båda sensorerna¶
Varje sensor kör sin tagningspipeline oberoende av den andra – färgsensorn kan leverera trettio bildrutor per sekund medan Lepton® levererar nio. Det enklaste sättet att hantera den obalansen är att låta den snabbare sensorn driva loopen och läsa den långsammare sensorn icke-blockerande, ta vad som är klart och hoppa över iterationen när inget finns:
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
Den blockerande snapshot() ger loopen dess takt; den icke-blockerande returnerar den senaste värmebildrutan när en färsk har landat sedan föregående anrop, och None annars. Applikationen fortsätter köra i färgsensorns bildfrekvens och får en värmebildruta närhelst Lepton® producerar en.
Det motsatta mönstret – två blockerande stillbilder i följd – fungerar också, men loopen körs då i den långsammare av de två sensorernas takter, där den snabbare sensorns pipeline stannar upp mellan iterationerna. Välj vilken takt än applikationens efterföljande bearbetning faktiskt vill driva.
4.18.4. Välja strömkälla¶
Kameror med två sensorer har två CSI-instanser men fortfarande bara en strömbildbuffert mellan dem. Ett konstruktorargument väljer vilken sensors bildrutor som matar förhandsgranskningen:
csi_rgb = csi.CSI() # primary
csi_thermal = csi.CSI(cid=csi.LEPTON,
stream=True) # preview source
stream=True gör den namngivna instansen till källan. Utan något stream=-argument är den primära sensorn (cid=-1, standard) källan; instanser byggda med cid= för en sekundär sensor förblir tysta på förhandsgranskningen om inte stream=True skickas explicit. Anrop till snapshot() på den ovalda sensorn tar fortfarande bildrutor in i den sensorns bildbuffertar som vanligt – de uppdaterar bara inte förhandsgranskningen.