4.18. Capteurs multiples¶
Quelques OpenMV Cams associent deux capteurs d’image sur la même carte – le plus souvent une caméra couleur aux côtés d’un capteur thermique FLIR® Lepton®, mais le même schéma s’applique aux cartes couleur-plus-événement et à tout futur matériel à double capteur. Chaque capteur possède sa propre matrice de pixels, son propre bus de contrôle, et exécute son propre pipeline à sa propre cadence de trames. L’API CSI les prend en charge en laissant l’application instancier un objet CSI par capteur physique.
4.18.1. Choix du capteur¶
Le constructeur CSI prend un argument cid qui désigne un capteur spécifique sur la carte. cid=-1 (la valeur par défaut) sélectionne le capteur principal ; les constantes cid nommées sélectionnent un capteur secondaire par identifiant de puce
import csi
csi_rgb = csi.CSI() # primary colour sensor
csi_thermal = csi.CSI(cid=csi.LEPTON) # FLIR® Lepton®
Chaque instance possède sa propre configuration – format de pixel, taille de trame, réglages d’exposition / gain, pool de tampons d’image – et est réinitialisée, configurée et lue indépendamment de l’autre. Les constantes pour les capteurs secondaires pris en charge (LEPTON, GENX320, et les autres listées dans la référence CSI) nomment la puce que l’application s’attend à trouver sur le port secondaire ; le pilote fait échouer la construction si la puce réelle ne correspond pas.
4.18.2. Capture depuis les deux capteurs¶
Chaque capteur exécute son pipeline de capture indépendamment de l’autre – le capteur couleur peut fournir trente trames par seconde tandis que le Lepton® en fournit neuf. La manière la plus simple de gérer cet écart est de laisser le capteur le plus rapide piloter la boucle et de lire le capteur le plus lent de façon non bloquante, en prenant ce qui est prêt et en sautant l’itération lorsque rien ne l’est
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
Le snapshot() bloquant cadence la boucle ; le non bloquant retourne la trame thermique la plus récente lorsqu’une nouvelle est arrivée depuis l’appel précédent, et None dans le cas contraire. L’application continue de tourner à la cadence de trames du capteur couleur et obtient une trame thermique chaque fois que le Lepton® en produit une.
Le schéma inverse – deux captures bloquantes l’une après l’autre – fonctionne aussi, mais la boucle tourne alors à la cadence du plus lent des deux capteurs, le pipeline du capteur le plus rapide se mettant en pause entre les itérations. Choisissez la cadence que le traitement en aval de l’application souhaite réellement piloter.
4.18.4. Choix de la source du flux¶
Les caméras à deux capteurs ont deux instances CSI mais ne disposent malgré tout que d’un seul tampon d’image de flux pour les deux. Un argument du constructeur choisit quel capteur alimente la prévisualisation avec ses trames
csi_rgb = csi.CSI() # primary
csi_thermal = csi.CSI(cid=csi.LEPTON,
stream=True) # preview source
stream=True fait de l’instance nommée la source. Sans argument stream=, le capteur principal (cid=-1, la valeur par défaut) est la source ; les instances construites avec un cid= d’un capteur secondaire restent muettes sur la prévisualisation à moins que stream=True ne soit passé explicitement. Les appels à snapshot() sur le capteur non sélectionné capturent toujours normalement des trames dans les tampons d’image de ce capteur – ils ne mettent simplement pas à jour la prévisualisation.