Multispektrinen tapahtumakamera¶
Multispectral Event Camera -moduuli yhdistää GENX320-tapahtumasensorin ja 1 MP:n PAG7936-globaalisuljinvärisensorin yhdelle moduulille — synkronoitu tapahtuma- ja väriputki nopeaan kohteiden seurantaan, LED-seurantaan, nestevirtaukseen ja muihin dynaamisiin kohtauksiin.
Täydellinen datalehti, kuvat ja tilaustiedot löytyvät Multispectral Event Camera -tuotesivulta.
Muista
Tuettu vain OpenMV N6:lla.
Kohokohdat¶
320x320 tapahtumasensori, >140 dB dynaaminen alue, 375 Hz+ histogrammit
PAG7936-väri: 1280x800 @ 120 FPS, 640x400 @ 240 FPS
Synkronoidut tapahtuma-aikaleimat jaetulla valotuslaukaisimella
Näkee alle 5 luxissa ilman automaattista valotusta
Teho alkaa noin 3 mW:sta tapahtumien suoratoistossa
Suunnattu nopeaan seurantaan, LED-seurantaan ja neste-/hiukkasvirtaukseen
Käyttö¶
Värisensori ja GENX320-tapahtumasensori saavat kumpikin oman csi.CSI-instanssinsa. Ensimmäinen kutsu käyttää oletuksena ensisijaista sensoria (PAG7936); toinen sitoutuu GENX320:een välittämällä cid= csi.GENX320. Nollaa värisensori kovalla nollauksella csi.CSI.reset (hard=True) jännitelinjan käynnistämiseksi, ja määritä GENX320 arvolla hard=False, jotta sen ajuri vain ohjelmoi sirun uudelleen nollausta uudelleen kytkemättä.
GENX320 tuottaa 320x320 histogrammitilassa; PAG7936 tarkkuudella csi.QVGA tuottaa 320x200. Alla oleva peruspäällys leikkaa GENX320-kehyksen alimmat 120 riviä. Käytä homografiamuunnosta (alla) sovitettuun päällykseen tai suurempaan PAG7936-kehyskokoon.
Kaksi työpuskuria pysyy muuttumattomana kehyssilmukan aikana — 256x1 alfapaletti, joka on tallennettu image.Image-objektina niin, että histogrammipikselit keskiharmaalla perustasolla (128) muuttuvat läpinäkyviksi ja sekä ON-tapahtumien korostukset että OFF-tapahtumien varjot muuttuvat läpinäkymättömiksi, sekä GENX320-kehyspuskuri, joka on esivarattu image.Image-objektilla, jotta csi.CSI.snapshot (blocking=False, image=...) voi täyttää sen paikallaan joka iteraatiossa ilman uudelleenvarausta:
import time
import csi
import image
import math
# V-shaped alpha: pixels far from the baseline 128 become opaque.
alpha_pal = image.Image(256, 1, image.GRAYSCALE)
for i in range(256):
alpha_pal[i] = int(math.pow(abs(i - 128) / 128.0, 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.GENX320)
csi1.reset(hard=False) # no hardware reset - just configure GENX320
csi1.pixformat(csi.GRAYSCALE)
csi1.framesize((320, 320))
csi1.brightness(128) # histogram baseline (default)
csi1.contrast(64) # per-event step
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_EVT_LIGHT,
alpha_palette=alpha_pal,
hint=image.BILINEAR)
print(clock.fps())
Jokainen iteraatio ottaa estävän väritilannekuvan ja ei-estävän GENX320-tilannekuvan. Image.draw_image yhdistää sitten nämä kaksi: color_palette= image.PALETTE_EVT_LIGHT (tai image.PALETTE_EVT_DARK tummalle taustalle) kuvaa GENX320:n harmaasävyhistogrammin väriramppiin, alpha_palette= sekoittaa jokaisen pikselin V-muotoisen alfakartan avulla niin, että kohtauksen hiljaiset alueet jäävät värikuvan läpi, ja hint= image.BILINEAR pehmentää skaalausta ylöspäin, kun värisensori toimii suuremmalla resoluutiolla kuin GENX320.
GENX320:n bias-esiasetukset, AFK-suodatin, kuumien pikselien kalibrointi ja STC-suodattimen ioctl:t toimivat kaikki samalla tavalla tässä kaksoiskamerakokoonpanossa — kutsu niitä kohteelle csi1 funktion csi.CSI.reset jälkeen. Katso lisätietoja alla olevista osioista.
GPU-kiihdytetty kohdistus¶
Image.draw_image hyväksyy transform=-argumentin — 3x3 homografiamatriisin 2-ulotteisena ulab.numpy-taulukkona. OpenMV N6:lla GPU suorittaa pikselikohtaisen projektion saman piirron aikana, joten GENX320-kehys voidaan kohdistaa uudelleen värikameran perspektiiviin ilman erillistä vääntövaihetta — hyödyllistä, kun kahdella sensorilla on hieman erilaiset optiikat tai näkökentät, tai kun värikamera toimii suuremmalla resoluutiolla. Kalibroi matriisi kullekin kameralle GenX320 Overlay Calibration -työkalulla, joka näyttää vilkkuvan ruutukuvion niin, että tapahtumasensori tuottaa kulmatapahtumia ilman mitään fyysistä liikettä:
import time
import csi
import image
from ulab import numpy as np
import math
# Calibration matrix from the GenX320 Overlay Calibration tool.
m = np.array([
[2.000000, 0.000000, 0.000000],
[0.000000, 2.000000, 80.000000],
[0.000000, 0.000000, 1.000000],
])
alpha_pal = image.Image(256, 1, image.GRAYSCALE)
for i in range(256):
alpha_pal[i] = int(math.pow(abs(i - 128) / 128.0, 2) * 255)
# Setup the color camera sensor.
csi0 = csi.CSI()
csi0.reset(hard=True)
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
csi1 = csi.CSI(cid=csi.GENX320)
csi1.reset(hard=False)
csi1.pixformat(csi.GRAYSCALE)
csi1.framesize((320, 320))
csi1.brightness(128)
csi1.contrast(64)
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_EVT_LIGHT,
alpha_palette=alpha_pal,
hint=image.BILINEAR,
transform=m)
print(clock.fps())
Tämä variantti ajaa värikameraa tarkkuudella csi.VGA (640x480) ja GENX320:tä sen natiivilla 320x320:lla — homografia projisoi pienemmän GENX320-kehyksen suurempaan värikehykseen osana piirtoa, joten skaalauskerroin on leivottu itse matriisiin sen sijaan, että se sovellettaisiin erikseen.
Tapahtumakameran yksityiskohdat¶
GENX320 on tapahtumapohjainen konenäkösensori — sen sijaan, että se lukisi koko 320x320-taulukon kiinteällä kehyskellolla, jokainen pikseli raportoi asynkronisia ”tapahtumia” sillä hetkellä, kun se havaitsee kirkkauden muutoksen. Jokainen tapahtuma sisältää X/Y-koordinaatin, ON/OFF-polariteetin (kirkkaasta tummaan tai tummasta kirkkaaseen) ja mikrosekunnin aikaleiman. Tästä juontuvat sensorin mikrosekunnin aikatarkkuus, liike-epäterävyyden puute, erittäin korkea dynaaminen alue ja aktiivisuuteen skaalautuva tehonkulutus. Staattiset kohtaukset eivät tuota dataa.
OpenMV-laiteohjelmisto tarjoaa GENX320:n csi.CSI-rajapinnan kautta arvolla cid= csi.GENX320. Käytettävissä on kaksi toimintatilaa:
Histogrammitila (oletus) — tapahtumat kerätään sirulla pikselikohtaisiin lokeroihin ja raportoidaan 320x320 harmaasävykehyksenä määriteltävällä nopeudella (~20-350 FPS). Sensori käyttäytyy kuin tavallinen kamera, joten kaikki vakiona olevat kuvankäsittelyrutiinit (
Image.find_blobs, paletit jne.) toimivat suoraan.Tapahtumatila — raakatapahtumat suoratoistetaan numpy-objektiin
ndarraytäysillä mikrosekunnin aikaleimoilla sovelluksia varten, jotka tarvitsevat ajallisen tarkkuuden esikerätyn kehyksen sijaan.
Histogrammitila¶
Histogrammitilassa GENX320 tuottaa harmaasävykehyksiä, joissa jokainen pikseli koodaa kyseisen sijainnin viimeaikaisen tapahtuma-aktiivisuuden. Kirkkauden perustason yläpuolella olevat pikselit ovat ON-tapahtumia (kirkkaus nousee), alapuolella olevat OFF-tapahtumia (kirkkaus laskee). Oletusperustason kirkkaus on 128 ja tapahtumakohtainen kontrastiaskel on 16 — nosta kontrastia, jotta tapahtumat erottuvat:
import csi
import time
csi0 = csi.CSI(cid=csi.GENX320)
csi0.reset()
csi0.pixformat(csi.GRAYSCALE)
csi0.framesize((320, 320))
csi0.brightness(128) # baseline (default 128)
csi0.contrast(16) # per-event step
csi0.framerate(50) # 20-350 FPS
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
print(clock.fps())
csi.CSI.brightness, csi.CSI.contrast ja csi.CSI.framerate ovat ne kolme säädintä, jotka muokkaavat histogrammin tulostetta.
Väritetty tuloste¶
Aseta csi.CSI.color_palette arvoon image.PALETTE_EVT_LIGHT vaaleaa taustaa varten tai image.PALETTE_EVT_DARK tummaa varten — ajuri tuottaa RGB565-kehyksiä käyttäen palettia suoraan:
csi0.color_palette(image.PALETTE_EVT_LIGHT)
Kuumien pikselien kalibrointi¶
Tapahtumasensoreihin kertyy ”kuumia pikseleitä”, jotka laukeavat virheellisesti. Suorita csi.IOCTL_GENX320_CALIBRATE staattista kohtausta vasten niiden poistamiseksi käytöstä. Ajuri rakentaa 320x320 pikselikohtaisen osumalukumäärän, laskee keskiarvon ja keskihajonnan ja poistaa käytöstä jokaisen pikselin, jonka lukumäärä on yli mean + sigma * stddev — sen jälkeen käytöstä poistetut pikselit lakkaavat tuottamasta tapahtumia sensoritasolla.
Kaksi parametria ohjaa kalibrointia:
event_count— kuinka monta tapahtumaa lasketaan ennen tilastojen laskemista. Silmukka kaappaa kehyksiä, kunnes käynnissä oleva tapahtumien kokonaismäärä ylittää tämän budjetin. Suuremmat määrät antavat luotettavamman arvion pidemmän kalibrointiajan kustannuksella.10000on järkevä lähtökohta.sigma— kynnyskerroin keskihajonnalle. Pienemmät arvot ovat aggressiivisempia (enemmän pikseleitä poistetaan käytöstä); suuremmat arvot ovat varovaisempia.0.5on hyvä oletusarvo.
Suuntaa sensori ensin staattiseen kohtaukseen, jotta liikkeen aiheuttamia tapahtumia ei lasketa sellaisia pikseleitä vastaan, jotka itse asiassa ovat kunnossa:
csi0.snapshot(time=5000) # let the user steady the camera
disabled = csi0.ioctl(csi.IOCTL_GENX320_CALIBRATE, 10000, 0.5)
print(f"disabled {disabled} hot pixels")
Vilkkumisenesto (AFK) -suodatin¶
Jaksolliset valonlähteet (loisteputket, LED-ohjatut näytöt) tuottavat valtavia määriä tarpeettomia tapahtumia. AFK-suodatin hylkää tapahtumat, joiden pikseli vaihtaa tilaa kaistan sisällä olevalla taajuudella — ota se käyttöön funktiolla csi.IOCTL_GENX320_SET_AFK antamalla kaistan reunat hertseinä:
csi0.ioctl(csi.IOCTL_GENX320_SET_AFK, 1, 130, 160) # 130-160 Hz
csi0.ioctl(csi.IOCTL_GENX320_SET_AFK, 0) # disable
Bias-esiasetukset¶
Jokainen GenX320:n pikseli ajaa analogista etupäätä useilla määriteltävillä biaseilla. Ne ohjaavat yhdessä herkkyyttä, kohinaa, pikselin kaistanleveyttä ja tapahtumanopeutta — oikea yhdistelmä riippuu kohtauksesta. Yksittäiset biasit ovat:
DIFF_ON — positiivisen komparaattorin kontrastikynnysarvo. Pikseli tuottaa ON-tapahtuman, kun sen logaritminen valaistus on noussut tämän verran. Pienempi = herkempi kirkkaille siirtymille.
DIFF_OFF — negatiivisen komparaattorin kontrastikynnysarvo (symmetrinen vastine OFF-tapahtumille). Pienempi = herkempi tummille siirtymille.
FO — pikselin alipäästön rajataajuus. Korkeampi = leveämpi pikselin kaistanleveys (nopeampi vaste, pienempi viive) mutta enemmän taustakohina-aktiivisuutta.
HPF — ylipäästön rajataajuus. Korkeampi = voimakkaampi hitaiden kirkkausmuutosten hylkääminen; vain nopeat siirtymät yltävät komparaattoreihin. Hyödyllinen ympäröivän ajautumisen sivuuttamiseen.
REFR — refraktäärinen jakso. Kun pikseli on lauennut, se pysyy nollaustilassa tämän ajan ennen kuin se voi laueta uudelleen. Korkeampi = pidempi kuollut aika, hyödyllinen pikselikohtaisen tapahtumanopeuden rajaamiseen.
Funktion csi.CSI.reset jälkeen ajuri soveltaa esiasetusta csi.GENX320_BIASES_LOW_NOISE, ei csi.GENX320_BIASES_DEFAULT — datalehden oletukset tuottavat paljon korkeamman taustatapahtumanopeuden, joten LOW_NOISE käytetään lähtökohtana virran pitämiseksi hiljaisena. Kutsu csi.IOCTL_GENX320_SET_BIASES eri esiasetuksella, kun sovellus tarvitsee enemmän herkkyyttä tai kaistanleveyttä.
csi.IOCTL_GENX320_SET_BIASES soveltaa yhtä viidestä esiasetuksesta:
csi.GENX320_BIASES_DEFAULT— GenX320-datalehden oletukset. Tasapainotettu herkkyys, kohina ja kaistanleveys yleisiä kohtauksia varten.csi.GENX320_BIASES_LOW_LIGHT— molempia kontrastikynnysarvoja löysennetty suuremman herkkyyden saavuttamiseksi, FO laskettu kohinan pitämiseksi alhaalla, ja HPF asetettu arvoon 0, jotta hitaat kirkkausmuutokset edelleen rekisteröityvät — hämärä kohtaus tuottaa itsestään vähän tapahtumia, joten haluamme mahdollisimman monen läpi.csi.GENX320_BIASES_ACTIVE_MARKER— viritetty korkeakontrastisten vilkkuvien LEDien seurantaan. Kontrastikynnysarvot nostettu niin, että vain terävät siirtymät laukaisevat; FO ja HPF nostettu korkealle pikselin kaistanleveyden maksimoimiseksi ja minkä tahansa hitaan ympäröivän ajautumisen hylkäämiseksi; REFR vedetty arvoon 0, jotta jokainen vilkkureuna tallennetaan peräkkäin. Tulos: virta, joka on lähes pelkkiä LED-reunoja, helppo seurata.csi.GENX320_BIASES_LOW_NOISE— ajurin oletus. Molempia kontrastikynnysarvoja nostettu verrattuna arvoonDEFAULT(vähemmän herkkä) ja FO laskettu (hitaampi pikseli = hiljaisempi pikseli). Paras staattisille tai hitaille kohtauksille, joissa virheelliset tapahtumat muuten dominoisivat.csi.GENX320_BIASES_HIGH_SPEED— FO nostettu, jotta jokainen pikseli voi vastata nopeammin, HPF nostettu hitaan kirkkausajautumisen hylkäämiseksi, ja REFR nostettu, jotta yksittäinen nopeasti liikkuva reuna ei tulvi luenta — pidempi kuollut aika pitää tapahtumamäärän rajoitettuna voimakkaassa liikkeessä.
Ohita yksittäiset biasit funktiolla csi.IOCTL_GENX320_SET_BIAS sekä yhdellä konstanteista csi.GENX320_BIAS_DIFF_ON, csi.GENX320_BIAS_DIFF_OFF, csi.GENX320_BIAS_FO, csi.GENX320_BIAS_HPF tai csi.GENX320_BIAS_REFR ja DAC-arvolla. Jokainen bias asetetaan itsenäisesti — valitse esiasetus lähtökohdaksi ja säädä sitten niitä biaseja, joita kohtauksesi tarvitsee:
csi0.ioctl(csi.IOCTL_GENX320_SET_BIASES, csi.GENX320_BIASES_LOW_LIGHT)
csi0.ioctl(csi.IOCTL_GENX320_SET_BIAS, csi.GENX320_BIAS_HPF, 20)
Seuranta¶
Koska histogrammitilan tuloste on vain harmaasävykuva, tavallinen blob-seuranta toimii suoraan. Seurataksesi aktiivisen merkin LEDiä lataa aktiivisen merkin bias-esiasetus ja etsi blobeja histogrammin kirkkaasta päästä:
import csi
import time
csi0 = csi.CSI(cid=csi.GENX320)
csi0.reset()
csi0.pixformat(csi.GRAYSCALE)
csi0.framesize((320, 320))
csi0.brightness(128)
csi0.contrast(16)
csi0.framerate(200)
csi0.ioctl(csi.IOCTL_GENX320_SET_BIASES, csi.GENX320_BIASES_ACTIVE_MARKER)
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
for blob in img.find_blobs([(120, 140)], invert=True,
pixels_threshold=2, area_threshold=4,
merge=True):
img.draw_detection(blob)
print(clock.fps())
Tapahtumatila¶
Tapahtumatila ohittaa sirulla olevan histogrammin ja suoratoistaa raakatapahtumat numpy-objektiin ndarray. Jokainen tapahtuma on rivi, jossa on kuusi uint16-saraketta:
[0]tapahtuman tyyppi — katso alla[1]sekuntien aikaleima[2]millisekuntien aikaleima[3]mikrosekuntien aikaleima[4]X-koordinaatti, 0-319[5]Y-koordinaatti, 0-319
Ajuri tuottaa kuusi tapahtumatyyppiä sarakkeessa [0]:
csi.PIX_OFF_EVENT— pikseli havaitsi kirkkauden vähenemisen (DIFF_OFF-komparaattorin kynnysarvo ylitettiin). X/Y osoittavat lauenneeseen pikseliin.csi.PIX_ON_EVENT— pikseli havaitsi kirkkauden lisääntymisen (DIFF_ON-kynnysarvo ylitettiin). X/Y osoittavat pikseliin.csi.EXT_TRIGGER_FALLING— sensorin ulkoinen laukaisinnasta näki laskevan reunan. X/Y ovat käyttämättömiä.csi.EXT_TRIGGER_RISING— sensorin ulkoinen laukaisinnasta näki nousevan reunan. X/Y ovat käyttämättömiä.csi.RST_TRIGGER_FALLING— pikselin nollauslaukaisin, laskeva reuna. X/Y ovat käyttämättömiä. Laiteohjelmisto ei tuota tätä tällä hetkellä.csi.RST_TRIGGER_RISING— pikselin nollauslaukaisin, nouseva reuna. X/Y ovat käyttämättömiä. Laiteohjelmisto ei tuota tätä tällä hetkellä.
GENX320:n ulkoinen laukaisintulo on kytketty kameran kehyssynkronointilinjaan, joka on myös reititetty nastaan P10 sekä prosessorissa että nastaliittimessä — ohjaa P10:tä syöttääksesi synkronointireunoja tapahtumavirtaan ja poimi ne EXT_TRIGGER_RISING / EXT_TRIGGER_FALLING -tapahtumina pikselidatan ohella.
Useimmat sovellukset välittävät vain tyypeistä PIX_OFF_EVENT ja PIX_ON_EVENT; laukaisintyyppien avulla voit korreloida tapahtumat ulkoisten ajoitussignaalien kanssa.
Varaa tapahtumapuskuri muodolla (EVT_res, 6), jossa EVT_res on kahden potenssi väliltä 1024 ja 65536, ja siirry sitten tapahtumatilaan funktiolla csi.IOCTL_GENX320_SET_MODE arvolla csi.GENX320_MODE_EVENT ja puskurin koolla. Lue tapahtumat funktiolla csi.IOCTL_GENX320_READ_EVENTS, joka täyttää puskurin sen kapasiteettiin asti ja palauttaa kelvollisten rivien lukumäärän.
Image.draw_event_histogram rasteroi tapahtumat harmaasävykuvaksi — jokaista ON-tapahtumaa kohti se lisää contrast lokeroon; jokaista OFF-tapahtumaa kohti se vähentää. clear=True nollaa kuvan arvoon brightness ensin; clear=False kerää monen kutsun yli:
import csi
import image
import time
from ulab import numpy as np
img = image.Image(320, 320, image.GRAYSCALE)
events = np.zeros((2048, 6), dtype=np.uint16)
csi0 = csi.CSI(cid=csi.GENX320)
csi0.reset()
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events.shape[0])
clock = time.clock()
while True:
clock.tick()
n = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS, events)
img.draw_event_histogram(events[:n], clear=True, brightness=128, contrast=64)
img.flush()
print(n, clock.fps())
Histogrammitilan bias-esiasetukset, AFK-suodatin ja kuumien pikselien kalibroinnin ioctl:t toimivat kaikki samalla tavalla tapahtumatilassa — kutsu niitä funktion csi.IOCTL_GENX320_SET_MODE jälkeen.
Suodatus polariteetin mukaan¶
Leikkaa tapahtumataulukko ulabilla pitääksesi vain ON-tapahtumat (liike kirkkaampaan tilaan) tai vain OFF-tapahtumat:
TARGET = csi.PIX_ON_EVENT # or csi.PIX_OFF_EVENT
events_slice = events[:n]
indices = np.nonzero(events_slice[:, 0] == TARGET)[0]
if len(indices):
target_events = np.take(events_slice, indices, axis=0)
img.draw_event_histogram(target_events, clear=True,
brightness=128, contrast=64)
Pitkän valotuksen kerääminen¶
Aseta clear=False jatkaaksesi tapahtumien pinoamista samaan kuvaan monen kehyksen ajan — tulos on liikejäljen visualisointi. Nollaa ajoittain aloittaaksesi uuden valotuksen:
EXPOSURE_FRAMES = 30
i = 0
while True:
n = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS, events)
clear = (i % EXPOSURE_FRAMES) == 0
img.draw_event_histogram(events[:n], clear=clear, brightness=128, contrast=64)
img.flush()
i += 1
Suurnopeuskäsittely¶
Pudota visualisointi vapauttaaksesi suoritintehoa tapahtumien käsittelyyn. Tulosta tilastot vain joka N:nnellä iteraatiolla — tulostusrivin työntäminen joka iteraatiossa muodostuu pullonkaulaksi korkeilla tapahtumanopeuksilla:
csi0 = csi.CSI(cid=csi.GENX320)
csi0.reset()
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events.shape[0])
clock = time.clock()
i = 0
while True:
clock.tick()
n = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS, events)
i += 1
if not i % 10:
print(f"{n} events {clock.fps()} fps")
Spatiotemporaalinen kontrasti (STC) -suodatin¶
Todellinen liikkuva kontrastireuna laukaisee yleensä kohinaisen purskeen tapahtumia samalla pikselillä lyhyen aikaikkunan sisällä — pikselien epäsovitus ja analoginen kohina tuottavat ylimääräisiä tapahtumia aidon siirtymän ympärille, jotka eivät ole hyödyllisiä sovellukselle. STC-suodatin on sirulla oleva jälkikäsittely, joka pitää vain yhden (tai muutaman) tapahtuman purskeesta ja pudottaa loput.
Se toteuttaa kolme strategiaa, jotka valitaan funktiolla csi.IOCTL_GENX320_SET_STC ja GENX320_STC_*-konstantilla. Jokainen tila määritellään sen mukaan, mitkä tapahtumat se välittää purskeesta:
Tila |
Pitää |
Pudottaa |
|---|---|---|
jokainen tapahtuma |
ei mitään |
|
purskeen toinen tapahtuma |
ensimmäinen + myöhemmät tapahtumat |
|
purskeen ensimmäinen tapahtuma |
myöhemmät tapahtumat |
|
ensimmäinen + myöhemmät reunat |
vain tarpeeton kohina |
Yksityiskohtaisesti:
csi.GENX320_STC_DISABLE— suodatin pois päältä, jokainen tapahtuma menee läpi (oletus).csi.GENX320_STC_ONLY— pitää purskeen toisen tapahtuman. Parametri:stc_threshold(ms). Jos uusi tapahtuma pikselillä saapuu ajanstc_thresholdsisällä edellisestä tapahtumasta, sitä pidetään purskeen ”toisena” ja se välitetään — ensimmäinen tapahtuma ja kaikki saman purskeen myöhemmät tapahtumat suodatetaan pois. Paras, kun haluat kohinalla vahvistetun siirtymän aivan ensimmäisen osuman sijaan.csi.GENX320_STC_TRAIL_ONLY— pitää purskeen ensimmäisen tapahtuman. Parametri:trail_threshold(ms). Kun pikseli on lauennut, saman pikselin myöhemmät tapahtumat pudotetaan, kunnestrail_thresholdon kulunut. Säilyttää johtavan reunan tarkan ajoituksen — hyödyllinen, kun polariteetin vaihtohetki on tärkeämpi kuin purskeen vahvistus.csi.GENX320_STC_TRAIL— yhdistää molemmat. Parametrit:stc_thresholdjatrail_threshold(molemmat ms). Pitää johtavan reunan Trail-tilan mukaan sekä myöhemmät reunat STC-tilan mukaan, joten useita tapahtumia purskeesta pääsee silti läpi — korkeampi tapahtumien läpäisykyky kuin yksitilaisilla suodattimilla mutta rikkain signaali.
Kahden kynnysarvon on pysyttävä suunnilleen 13:1-suhteen sisällä — sensori hylkää konfiguraatiot, joissa toinen on yli ~13x toista:
csi0.ioctl(csi.IOCTL_GENX320_SET_STC, csi.GENX320_STC_TRAIL, 1, 2)
csi0.ioctl(csi.IOCTL_GENX320_SET_STC, csi.GENX320_STC_DISABLE)
Puskurin syvyys¶
Kun tapahtumanopeudet piikittävät, oletuksena oleva kolmoispuskuriputki suosii uusinta kehystä ja hylkää vanhat. Nosta FIFO-syvyyttä funktiolla csi.CSI.framebuffers jonottaaksesi tapahtumia sen sijaan — sillä kustannuksella, että käsitellään hieman vanhempaa dataa, kun isäntä jää jälkeen:
csi0.framebuffers(10) # FIFO depth, > 3 enables queueing
Työpöytäsuoratoisto ja visualisointi¶
Reaaliaikaista GUI-visualisointia varten isäntä-PC:llä GenX320 Event Streaming -työkalu openmv-projects-repositoriossa yhdistää kameran DearPyGui-käyttöliittymään. PC:n GUI ajaa kahta visualisointia vierekkäin: tapahtumien kerääntymiskankaan (sama idea kuin Image.draw_event_histogram, mutta valittavilla paleteilla sekä liukuvan ikkunan ja automaattisen tyhjennyksen tiloilla) ja pikselikohtaisen taajuuskartan, jota ohjaa IIR-kaistanpäästösuodatin — hyödyllinen jaksollisten signaalien (pyörivät tuulettimet, vilkkuvat LEDit jne.) havaitsemiseen suoraan tapahtumavirrasta.
Se sisältää kaksi kamerassa ajettavaa suoratoistoskriptiä:
Käsitelty tila (
genx320_event_mode_streaming_on_cam.py) — kamera dekoodaa tapahtumat funktiollacsi.IOCTL_GENX320_READ_EVENTSja suoratoistaa jokaisen rivin 12 tavuna USB:n yli ([0]tyyppi,[1]s,[2]ms,[3]us,[4]x,[5]y). Helppo käsitellä PC:llä, koska siirtomuoto vastaa kameran ndarray-muotoa.Raakatila (
genx320_raw_event_mode_streaming_on_cam.py) — kamera suoratoistaa sirun natiivit 32-bittiset pakatut tapahtumasanat funktiollacsi.IOCTL_GENX320_READ_EVENTS_RAW. Se on 4 tavua tapahtumaa kohti verrattuna 12:een käsitellyssä tilassa (noin 3x vähemmän dataa USB:n yli), joten ~3x korkeampi saavutettavissa oleva tapahtumanopeus, kun yhteys on pullonkaula. PC dekoodaa pakatut sanat takaisin samaan 6-sarakkeiseen tapahtumamuotoon vektoroidulla numpyllä, joten alavirran visualisoijan koodi on identtinen.
Raakatila on oletus GUI:ssa, koska USB-läpäisykyky on sitova rajoite niillä nopeuksilla, joita GenX320 voi tuottaa; vaihda käsiteltyyn tilaan, jos sinun täytyy liittää käsittelylogiikkaa kamerassa ajettavaan skriptiin.