GENX320-tapahtumakamera¶
GENX320 Event Camera Module on Prophesee-yhtiön tapahtumapohjainen näkösensori, jonka resoluutio on 320x320 ja jonka ajallinen tarkkuus on mikrosekuntiluokkaa.
Täydellisen datalehden, kuvat ja tilaustiedot löydät GENX320 Event Camera -tuotesivulta.
Muista
Tuettu malleissa OpenMV H7 Plus, RT1062 ja N6.
Kohokohdat¶
320x320 tapahtumapohjainen näkösensori
140 dB:n dynaaminen alue, ei liike-epäterävyyttä
375 Hz+ tapahtumahistogrammien ulostulonopeus
Tehonkulutus skaalautuu näkymän aktiivisuuden mukaan — alkaa noin 3 mW:sta
Toimii alle 5 luksista kirkkaaseen auringonpaisteeseen ilman automaattista valotusta
Tuottaa harmaasävykehyksiä tai raakoja tapahtumavirtoja
Käyttö¶
GENX320 on tapahtumapohjainen näkösensori — sen sijaan, että koko 320x320-matriisi luettaisiin ulos kiinteällä kehyskellotaajuudella, jokainen pikseli raportoi asynkronisia ”tapahtumia” sillä hetkellä, kun se havaitsee kirkkauden muutoksen. Jokainen tapahtuma sisältää X/Y-koordinaatin, ON/OFF-polariteetin (kirkkaasta→tummaksi tai tummasta→kirkkaaksi) sekä mikrosekuntiaikaleiman. Tästä juontuvat sensorin mikrosekuntiluokan ajallinen tarkkuus, liike-epäterävyyden puuttuminen, erittäin laaja dynaaminen alue sekä aktiivisuuteen skaalautuva tehonkulutus. Staattiset näkymät eivät tuota lainkaan dataa.
OpenMV-laiteohjelmisto tuo GENX320:n käyttöön csi.CSI-luokan 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ä säädettävällä nopeudella (~20–350 FPS). Sensori käyttäytyy kuin tavallinen kamera, joten kaikki tavanomaiset kuvankäsittelyrutiinit (
Image.find_blobs, paletit jne.) toimivat suoraan.Tapahtumatila — raakatapahtumat virtaavat numpy-tyyppiseen
ndarray-taulukkoon täysillä mikrosekuntiaikaleimoilla niitä sovelluksia varten, jotka tarvitsevat ajallisen yksityiskohdan esivalmistellun kehyksen sijaan.
Histogrammitila¶
Histogrammitilassa GENX320 tuottaa harmaasävykehyksiä, joissa kukin 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 16 — nosta kontrastia, jotta tapahtumat erottuvat selvemmin:
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 ulostuloa.
Värillinen ulostulo¶
Aseta csi.CSI.color_palette arvoon image.PALETTE_EVT_LIGHT vaaleaa taustaa varten tai image.PALETTE_EVT_DARK tummaa taustaa 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. Aja csi.IOCTL_GENX320_CALIBRATE staattista näkymää vasten poistaaksesi ne käytöstä. Ajuri rakentaa 320x320-pikselikohtaisen osumalaskurin, laskee keskiarvon ja keskihajonnan sekä poistaa käytöstä jokaisen pikselin, jonka laskuri ylittää arvon mean + sigma * stddev — tämän jälkeen käytöstä poistetut pikselit lakkaavat lähettämästä tapahtumia sensoritasolla.
Kaksi parametria ohjaa kalibrointia:
event_count— kuinka monta tapahtumaa lasketaan ennen tilastojen laskemista. Silmukka kaappaa kehyksiä, kunnes juokseva tapahtumien kokonaismäärä ylittää tämän budjetin. Suuremmat arvot antavat luotettavamman arvion pidemmän kalibrointiajan kustannuksella.10000on järkevä lähtökohta.sigma— keskihajonnan kynnyskerroin. Pienemmät arvot ovat aggressiivisempia (enemmän pikseleitä poistetaan käytöstä); suuremmat arvot ovat varovaisempia.0.5on hyvä oletusarvo.
Suuntaa sensori ensin staattiseen näkymään, jotta liikkeen aiheuttamia tapahtumia ei lasketa niitä pikseleitä vastaan, jotka ovat itse asiassa 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")
Vilkunnanesto-suodatin (AFK)¶
Jaksolliset valonlähteet (loisteputket, LED-ohjatut näytöt) tuottavat valtavia määriä turhia tapahtumia. AFK-suodatin hylkää tapahtumat, joiden pikseli vaihtelee tiettyyn taajuuskaistaan kuuluvalla taajuudella — ota se käyttöön komennolla csi.IOCTL_GENX320_SET_AFK antaen 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 sisältää analogisen etuasteen useilla säädettävillä bias-arvoilla. Ne ohjaavat yhdessä herkkyyttä, kohinaa, pikselin kaistanleveyttä ja tapahtumanopeutta — oikea yhdistelmä riippuu näkymästä. Yksittäiset bias-arvot ovat:
DIFF_ON — positiivisen vertailijan kontrastikynnysarvo. Pikseli lähettää ON-tapahtuman, kun sen logaritminen valaistus on noussut tämän verran. Pienempi = herkempi kirkkaille muutoksille.
DIFF_OFF — negatiivisen vertailijan kontrastikynnysarvo (symmetrinen vastine OFF-tapahtumille). Pienempi = herkempi tummille muutoksille.
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äys; vain nopeat muutokset saavuttavat vertailijat. Hyödyllinen ympäristön ajautuman ohittamiseen.
REFR — palautumisaika. Pikselin lauettua se pysyy nollaustilassa tämän ajan, ennen kuin se voi laueta uudelleen. Korkeampi = pidempi kuolleen aika, hyödyllinen pikselikohtaisen tapahtumanopeuden rajaamiseen.
Komennon csi.CSI.reset jälkeen ajuri ottaa käyttöön asetukset csi.GENX320_BIASES_LOW_NOISE, ei asetuksia 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 ottaa käyttöön yhden viidestä esiasetuksesta:
csi.GENX320_BIASES_DEFAULT— GenX320:n datalehden oletukset. Tasapainotettu herkkyys, kohina ja kaistanleveys yleisiin näkymiin.csi.GENX320_BIASES_LOW_LIGHT— molempia kontrastikynnysarvoja löysennetty herkkyyden lisäämiseksi, FO laskettu kohinan pitämiseksi kurissa ja HPF asetettu nollaan, jotta hitaatkin kirkkausmuutokset rekisteröityvät — hämärä näkymä tuottaa itsessään vähän tapahtumia, joten haluamme niistä mahdollisimman monen läpi.csi.GENX320_BIASES_ACTIVE_MARKER— viritetty korkeakontrastisten vilkkuvien LEDien seurantaan. Kontrastikynnysarvoja nostettu niin, että vain terävät muutokset laukaisevat; FO ja HPF kohotettu korkealle pikselin kaistanleveyden maksimoimiseksi ja hitaan ympäristön ajautuman hylkäämiseksi; REFR vedetty nollaan, jotta jokainen vilkkumisen reuna tallentuu peräkkäin. Tuloksena on virta, joka koostuu lähes pelkistä LEDien reunoista ja jota on helppo seurata.csi.GENX320_BIASES_LOW_NOISE— ajurin oletus. Molemmat kontrastikynnysarvot nostettu verrattuna asetukseenDEFAULT(vähemmän herkkä) ja FO laskettu (hitaampi pikseli = hiljaisempi pikseli). Paras staattisille tai hitaille näkymille, joissa virheelliset tapahtumat muutoin hallitsisivat.csi.GENX320_BIASES_HIGH_SPEED— FO nostettu, jotta kukin pikseli voi reagoida nopeammin, HPF nostettu hitaan kirkkausajautuman hylkäämiseksi ja REFR nostettu, jottei yksittäinen nopeasti liikkuva reuna tukkisi ulkolukua — pidempi kuollut aika pitää tapahtumamäärän rajattuna voimakkaan liikkeen aikana.
Ohita yksittäiset bias-arvot komennolla csi.IOCTL_GENX320_SET_BIAS yhdessä jonkin seuraavista kanssa: csi.GENX320_BIAS_DIFF_ON, csi.GENX320_BIAS_DIFF_OFF, csi.GENX320_BIAS_FO, csi.GENX320_BIAS_HPF tai csi.GENX320_BIAS_REFR, sekä DAC-arvo. Kukin bias asetetaan erikseen — valitse esiasetus lähtökohdaksi ja säädä sitten niitä bias-arvoja, joita näkymäsi 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 ulostulo on vain harmaasävykuva, tavanomainen blob-seuranta toimii suoraan. Aktiivisen markkeri-LEDin seuraamiseksi lataa aktiivisen markkerin 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 sirun histogrammin ja virtaa raakatapahtumat numpy-tyyppiseen ndarray-taulukkoon. Jokainen tapahtuma on rivi, jossa on kuusi uint16-saraketta:
[0]tapahtuman tyyppi — katso alta[1]sekuntien aikaleima[2]millisekuntien aikaleima[3]mikrosekuntien aikaleima[4]X-koordinaatti, 0–319[5]Y-koordinaatti, 0–319
Ajuri lähettää kuutta tapahtumatyyppiä sarakkeessa [0]:
csi.PIX_OFF_EVENT— pikseli havaitsi kirkkauden vähenemisen (DIFF_OFF-vertailijan kynnysarvo ylittyi). X/Y osoittavat lauenneeseen pikseliin.csi.PIX_ON_EVENT— pikseli havaitsi kirkkauden lisääntymisen (DIFF_ON-kynnysarvo ylittyi). X/Y osoittavat pikseliin.csi.EXT_TRIGGER_FALLING— sensorin ulkoinen liipaisunasta havaitsi laskevan reunan. X/Y eivät ole käytössä.csi.EXT_TRIGGER_RISING— sensorin ulkoinen liipaisunasta havaitsi nousevan reunan. X/Y eivät ole käytössä.csi.RST_TRIGGER_FALLING— pikselin nollausliipaisin, laskeva reuna. X/Y eivät ole käytössä. Laiteohjelmisto ei tuota tätä tällä hetkellä.csi.RST_TRIGGER_RISING— pikselin nollausliipaisin, nouseva reuna. X/Y eivät ole käytössä. Laiteohjelmisto ei tuota tätä tällä hetkellä.
GENX320:n ulkoinen liipaisutulo on kytketty kameran kehyssynkronointilinjaan, joka on myös reititetty nastaan P10 sekä prosessorissa että nastarimassa — ohjaa P10:tä syöttääksesi synkronointireunoja tapahtumavirtaan ja poimi ne EXT_TRIGGER_RISING / EXT_TRIGGER_FALLING -tapahtumina pikselidatan rinnalla.
Useimmat sovellukset välittävät vain tapahtumista PIX_OFF_EVENT ja PIX_ON_EVENT; liipaisutyyppien avulla voit yhdistää tapahtumat ulkoisiin ajoitussignaaleihin.
Varaa tapahtumapuskuri muodolla (EVT_res, 6), jossa EVT_res on kahden potenssi välillä 1024 ja 65536, ja siirry sitten tapahtumatilaan komennolla csi.IOCTL_GENX320_SET_MODE arvolla csi.GENX320_MODE_EVENT ja puskurin koolla. Lue tapahtumat komennolla csi.IOCTL_GENX320_READ_EVENTS, joka täyttää puskurin sen kapasiteettiin asti ja palauttaa kelvollisten rivien määrän.
Image.draw_event_histogram rasteroi tapahtumat harmaasävykuvaksi — jokaista ON-tapahtumaa kohti se lisää lokeroon arvon contrast ja jokaista OFF-tapahtumaa kohti vähentää sen. clear=True nollaa kuvan ensin arvoon brightness; clear=False kerää useiden kutsujen 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-komennot toimivat kaikki samalla tavalla tapahtumatilassa — kutsu niitä komennon csi.IOCTL_GENX320_SET_MODE jälkeen.
Suodatus polariteetin mukaan¶
Viipaloi tapahtumataulukko ulabilla säilyttää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 kertyminen¶
Aseta clear=False pinotaksesi tapahtumia samaan kuvaan useiden kehysten ajan — tuloksena on liikejälkien 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
Suuren nopeuden käsittely¶
Pudota visualisointi vapauttaaksesi prosessoria tapahtumankäsittelyyn. Tulosta tilastot vain joka N:nnellä iteraatiolla — tulostusrivin työntäminen jokaisella iteraatiolla muodostuu pullonkaulaksi suurilla 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")
Tila-aikakontrastisuodatin (STC)¶
Todellinen liikkuva kontrastireuna laukaisee tyypillisesti kohinaisen tapahtumien purskeen samalla pikselillä lyhyen aikaikkunan sisällä — pikselien epätäsmäys ja analoginen kohina tuottavat ylimääräisiä tapahtumia aidon muutoksen ympärille, jotka eivät ole sovelluksen kannalta hyödyllisiä. STC-suodatin on sirulla suoritettava jälkikäsittely, joka säilyttää vain yhden (tai muutaman) tapahtuman purskeesta ja hylkää loput.
Se toteuttaa kolme strategiaa, jotka valitaan komennolla csi.IOCTL_GENX320_SET_STC ja vakiolla GENX320_STC_*. Kukin tila määritellään sen mukaan, mitkä tapahtumat se välittää purskeesta:
Tila |
Säilyttää |
Hylkää |
|---|---|---|
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 turha kohina |
Yksityiskohtaisesti:
csi.GENX320_STC_DISABLE— suodatin pois, jokainen tapahtuma kulkee läpi (oletus).csi.GENX320_STC_ONLY— säilyttää purskeen toisen tapahtuman. Parametri:stc_threshold(ms). Jos pikselin uusi tapahtuma saapuustc_threshold-ajan sisällä edellisestä tapahtumasta, sitä pidetään purskeen ”toisena” tapahtumana ja se välitetään — ensimmäinen tapahtuma ja samaan purskeeseen kuuluvat myöhemmät tapahtumat suodatetaan pois. Paras silloin, kun haluat kohinalla varmennetun muutoksen aivan ensimmäisen osuman sijaan.csi.GENX320_STC_TRAIL_ONLY— säilyttää purskeen ensimmäisen tapahtuman. Parametri:trail_threshold(ms). Pikselin lauettua samaa pikseliä koskevat myöhemmät tapahtumat hylätään, kunnestrail_thresholdon kulunut. Säilyttää etureunan tarkan ajoituksen — hyödyllinen, kun polariteetin vaihtumishetki on tärkeämpi kuin purskeen varmistus.csi.GENX320_STC_TRAIL— yhdistää molemmat. Parametrit:stc_thresholdjatrail_threshold(molemmat ms). Säilyttää etureunan Trail-tilan mukaisesti sekä myöhemmät reunat STC-tilan mukaisesti, joten useita purskeen tapahtumia pääsee silti läpi — korkeampi tapahtumien läpäisykyky kuin yksitilaisilla suodattimilla, mutta rikkain signaali.
Kahden kynnysarvon on pysyttävä karkeasti suhteessa 13:1 — sensori hylkää konfiguraatiot, joissa toinen on yli noin 13-kertainen toiseen nähden:
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, oletusarvoinen kolmoispuskuriputki suosii uusinta kehystä ja hylkää vanhat. Nosta FIFO-syvyyttä ominaisuudella csi.CSI.framebuffers jonottaaksesi tapahtumia sen sijaan — sen hinnalla, että käsiteltävä data on hieman vanhempaa silloin, kun isäntä jää jälkeen:
csi0.framebuffers(10) # FIFO depth, > 3 enables queueing
Työpöytäsuoratoisto ja visualisointi¶
Reaaliaikaiseen graafiseen visualisointiin isäntä-PC:llä GenX320 Event Streaming -työkalu openmv-projects-repossa yhdistää kameran DearPyGui-käyttöliittymään. PC:n graafinen käyttöliittymä näyttää kaksi visualisointia rinnakkain: tapahtumien kertymäkankaan (sama idea kuin Image.draw_event_histogram, mutta valittavilla paleteilla sekä liukuva-ikkuna- vai automaattinollaustiloilla) ja IIR-kaistanpäästösuodattimen ohjaaman pikselikohtaisen taajuuskartan — hyödyllinen jaksollisten signaalien (pyörivät tuulettimet, vilkkuvat LEDit jne.) havaitsemiseen suoraan tapahtumavirrasta.
Sen mukana toimitetaan kaksi kameralla ajettavaa suoratoistoskriptiä:
Käsitelty tila (
genx320_event_mode_streaming_on_cam.py) — kamera purkaa tapahtumat komennollacsi.IOCTL_GENX320_READ_EVENTSja suoratoistaa kunkin rivin 12 tavuna USB:n yli ([0]tyyppi,[1]s,[2]ms,[3]µs,[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 komennollacsi.IOCTL_GENX320_READ_EVENTS_RAW. Se on 4 tavua tapahtumaa kohti verrattuna käsitellyn tilan 12 tavuun (noin 3 kertaa vähemmän dataa USB:n yli), joten noin 3 kertaa korkeampi saavutettavissa oleva tapahtumanopeus silloin, kun linkki on pullonkaula. PC purkaa pakatut sanat takaisin samaan 6-sarakkeiseen tapahtumamuotoon vektoroidulla numpylla, joten myöhemmän visualisoijan koodi on identtinen.
Raakatila on graafisen käyttöliittymän oletus, koska USB:n läpäisykyky on sitova rajoite niillä nopeuksilla, joita GenX320 pystyy tuottamaan; vaihda käsiteltyyn tilaan, jos sinun täytyy liittää käsittelylogiikkaa kameralla ajettavaan skriptiin.