GENX320 event kamera

Modul GENX320 event kamere je Prophesee senzor vida zasnovan na događajima s razlučivosti 320x320 i mikrosekundskom vremenskom preciznošću.

GENX320 event kamera

Za potpuni datasheet, fotografije i naručivanje pogledajte stranicu proizvoda GENX320 Event Camera.

Napomena

Podržano na OpenMV H7 Plus, RT1062 i N6.

Naglasci

  • 320x320 senzor vida zasnovan na događajima

  • Dinamički raspon od 140 dB, bez zamućenja zbog pokreta

  • Izlazna brzina event-histograma od 375 Hz+

  • Potrošnja energije skalira se s aktivnošću scene — počinje na ~3 mW

  • Radi od <5 luksa do jakog sunčevog svjetla bez automatske ekspozicije

  • Generira sličice u sivim tonovima ili sirove tokove događaja

Upotreba

GENX320 je senzor vida zasnovan na događajima — umjesto očitavanja cijelog polja 320x320 na fiksnom taktu sličica, svaki piksel javlja asinkrone „događaje” u trenutku kada otkrije promjenu svjetline. Svaki događaj nosi X/Y koordinatu, ON/OFF polaritet (svijetlo→tamno ili tamno→svijetlo) i mikrosekundsku vremensku oznaku. Odatle dolaze mikrosekundska vremenska preciznost senzora, izostanak zamućenja zbog pokreta, vrlo visok dinamički raspon i potrošnja energije skalirana s aktivnošću. Statične scene ne generiraju nikakve podatke.

OpenMV firmware izlaže GENX320 kroz csi.CSI s cid= csi.GENX320. Dostupna su dva načina rada:

  • Histogramski način (zadani) — događaji se akumuliraju na čipu u spremnike po pikselu i javljaju kao sličica u sivim tonovima 320x320 s podesivom brzinom (~20-350 FPS). Senzor se ponaša kao obična kamera, pa sve standardne rutine za obradu slike (Image.find_blobs, palete itd.) rade izravno.

  • Event način — sirovi događaji teku u numpy ndarray s punim mikrosekundskim vremenskim oznakama, za primjene kojima je potreban vremenski detalj umjesto unaprijed razvrstane sličice.

Histogramski način

U histogramskom načinu GENX320 generira sličice u sivim tonovima gdje svaki piksel kodira nedavnu aktivnost događaja na toj lokaciji. Pikseli iznad osnovne razine svjetline su ON događaji (svjetlina raste), oni ispod su OFF događaji (svjetlina pada). Zadana osnovna svjetlina je 128, a kontrastni korak po događaju je 16 — povećajte kontrast da događaji više iskaču:

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 i csi.CSI.framerate tri su regulatora koji oblikuju histogramski izlaz.

Obojeni izlaz

Postavite csi.CSI.color_palette na image.PALETTE_EVT_LIGHT za svijetlu pozadinu ili image.PALETTE_EVT_DARK za tamnu — upravljački program emitira RGB565 sličice koristeći paletu izravno:

csi0.color_palette(image.PALETTE_EVT_LIGHT)

Kalibracija vrućih piksela

Event senzori akumuliraju „vruće piksele” koji okidaju lažno. Pokrenite csi.IOCTL_GENX320_CALIBRATE na statičnoj sceni da ih onemogućite. Upravljački program gradi broj pogodaka po pikselu 320x320, izračunava srednju vrijednost i standardnu devijaciju te onemogućuje svaki piksel čiji je broj iznad mean + sigma * stddev — nakon toga onemogućeni pikseli prestaju emitirati događaje na razini senzora.

Kalibraciju kontroliraju dva parametra:

  • event_count — koliko događaja zbrojiti prije izračuna statistike. Petlja hvata sličice sve dok tekući ukupni broj događaja ne prijeđe ovaj proračun. Veći brojevi daju pouzdaniju procjenu uz cijenu duljeg vremena kalibracije. 10000 je razuman početak.

  • sigma — množitelj praga na standardnu devijaciju. Niže vrijednosti su agresivnije (onemogućeno je više piksela); više vrijednosti su konzervativnije. 0.5 je dobra zadana vrijednost.

Prvo usmjerite senzor na statičnu scenu kako se događaji uzrokovani pokretom ne bi pribrojili pikselima koji su zapravo ispravni:

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")

Filtar protiv treperenja (AFK)

Periodični izvori svjetla (fluorescentni, zasloni s LED pozadinom) generiraju ogromne količine suvišnih događaja. AFK filtar odbacuje događaje čiji piksel mijenja stanje na frekvenciji unutar pojasa — omogućite ga putem csi.IOCTL_GENX320_SET_AFK s rubovima pojasa u hercima:

csi0.ioctl(csi.IOCTL_GENX320_SET_AFK, 1, 130, 160)  # 130-160 Hz
csi0.ioctl(csi.IOCTL_GENX320_SET_AFK, 0)            # disable

Predefinirane postavke biasa

Svaki piksel u GenX320 pokreće analogni front-end s nekoliko podesivih biasa. Oni zajednički upravljaju osjetljivošću, šumom, propusnošću piksela i brzinom događaja — prava kombinacija ovisi o sceni. Pojedinačni biasi su:

  • DIFF_ON — pozitivni kontrastni prag komparatora. Piksel emitira ON događaj kada mu se log-osvjetljenje povisi za toliko. Niže = osjetljiviji na svijetle prijelaze.

  • DIFF_OFF — negativni kontrastni prag komparatora (simetrični parnjak za OFF događaje). Niže = osjetljiviji na tamne prijelaze.

  • FO — niskopropusna granična frekvencija piksela. Više = šira propusnost piksela (brži odziv, niže kašnjenje) ali više aktivnosti pozadinskog šuma.

  • HPF — visokopropusna granična frekvencija. Više = jače odbacivanje sporih promjena svjetline; samo brzi prijelazi dosežu komparatore. Korisno za zanemarivanje pomicanja ambijenta.

  • REFR — refrakterni period. Nakon što piksel okine, ostaje u resetu toliko dugo prije nego što ponovno može okinuti. Više = dulje mrtvo vrijeme, korisno za ograničavanje brzine događaja po pikselu.

Nakon csi.CSI.reset upravljački program primjenjuje csi.GENX320_BIASES_LOW_NOISE, a ne csi.GENX320_BIASES_DEFAULT — zadane postavke iz datasheeta emitiraju mnogo veću brzinu pozadinskih događaja, pa se LOW_NOISE koristi kao polazna točka da bi tok ostao tih. Pozovite csi.IOCTL_GENX320_SET_BIASES s drugačijom predefiniranom postavkom kada primjeni treba više osjetljivosti ili propusnosti.

csi.IOCTL_GENX320_SET_BIASES primjenjuje jednu od pet predefiniranih postavki:

  • csi.GENX320_BIASES_DEFAULT — zadane postavke iz GenX320 datasheeta. Uravnotežena osjetljivost, šum i propusnost za opće scene.

  • csi.GENX320_BIASES_LOW_LIGHT — oba kontrastna praga su olabavljena za veću osjetljivost, FO je snižen kako bi šum ostao nizak, a HPF je postavljen na 0 tako da se spore promjene svjetline i dalje bilježe — scena pri slabom svjetlu sama po sebi generira malo događaja, pa želimo da ih što više prođe.

  • csi.GENX320_BIASES_ACTIVE_MARKER — podešen za praćenje visokokontrastnih trepćućih LED dioda. Kontrastni pragovi su podignuti tako da okidaju samo oštri prijelazi; FO i HPF su podignuti visoko kako bi se maksimizirala propusnost piksela i odbacilo svako sporo pomicanje ambijenta; REFR je spušten na 0 tako da se svaki rub treptaja hvata bez prekida. Rezultat: tok koji je gotovo u potpunosti sastavljen od LED rubova, lak za praćenje.

  • csi.GENX320_BIASES_LOW_NOISE — zadana postavka upravljačkog programa. Oba kontrastna praga podignuta u odnosu na DEFAULT (manje osjetljivo) i FO snižen (sporiji piksel = tiši piksel). Najbolje za statične ili spore scene gdje bi lažni događaji inače prevladali.

  • csi.GENX320_BIASES_HIGH_SPEED — FO podignut tako da svaki piksel može brže reagirati, HPF podignut da odbaci sporo pomicanje svjetline, a REFR podignut tako da jedan brzo pokretni rub ne preplavi očitavanje — dulje mrtvo vrijeme drži količinu događaja ograničenom pod jakim pokretom.

Nadjačajte pojedinačne biase s csi.IOCTL_GENX320_SET_BIAS plus jednim od csi.GENX320_BIAS_DIFF_ON, csi.GENX320_BIAS_DIFF_OFF, csi.GENX320_BIAS_FO, csi.GENX320_BIAS_HPF ili csi.GENX320_BIAS_REFR i DAC vrijednošću. Svaki bias se postavlja neovisno — odaberite predefiniranu postavku kao polaznu točku, zatim podesite koje god biase vaša scena treba:

csi0.ioctl(csi.IOCTL_GENX320_SET_BIASES, csi.GENX320_BIASES_LOW_LIGHT)
csi0.ioctl(csi.IOCTL_GENX320_SET_BIAS, csi.GENX320_BIAS_HPF, 20)

Praćenje

Budući da je izlaz histogramskog načina samo slika u sivim tonovima, uobičajeno praćenje mrlja radi izravno. Za praćenje active-marker LED diode učitajte active-marker predefiniranu postavku biasa i pronađite mrlje na svijetlom kraju histograma:

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())

Event način

Event način zaobilazi histogram na čipu i tokovno šalje sirove događaje u numpy ndarray. Svaki događaj je redak od šest uint16 stupaca:

  • [0] tip događaja — vidi ispod

  • [1] vremenska oznaka u sekundama

  • [2] vremenska oznaka u milisekundama

  • [3] vremenska oznaka u mikrosekundama

  • [4] X koordinata, 0-319

  • [5] Y koordinata, 0-319

Upravljački program emitira šest tipova događaja u stupcu [0]:

  • csi.PIX_OFF_EVENT — piksel je otkrio smanjenje svjetline (prijeđen je kontrastni prag komparatora DIFF_OFF). X/Y upućuju na piksel koji je okinuo.

  • csi.PIX_ON_EVENT — piksel je otkrio povećanje svjetline (prijeđen je prag DIFF_ON). X/Y upućuju na piksel.

  • csi.EXT_TRIGGER_FALLING — vanjski okidni pin senzora vidio je padajući rub. X/Y se ne koriste.

  • csi.EXT_TRIGGER_RISING — vanjski okidni pin senzora vidio je rastući rub. X/Y se ne koriste.

  • csi.RST_TRIGGER_FALLING — okidač reseta piksela, padajući rub. X/Y se ne koriste. Trenutno ga firmware ne generira.

  • csi.RST_TRIGGER_RISING — okidač reseta piksela, rastući rub. X/Y se ne koriste. Trenutno ga firmware ne generira.

Vanjski okidni ulaz GENX320 ožičen je na liniju sinkronizacije sličica kamere, koja je također usmjerena na P10 i na procesoru i na pin headeru — pokrenite P10 da ubacite sinkronizacijske rubove u tok događaja i pokupite ih kao EXT_TRIGGER_RISING / EXT_TRIGGER_FALLING događaje uz podatke piksela.

Većini primjena stalo je samo do PIX_OFF_EVENT i PIX_ON_EVENT; okidni tipovi omogućuju korelaciju događaja s vanjskim vremenskim signalima.

Alocirajte event međuspremnik s oblikom (EVT_res, 6) gdje je EVT_res potencija dvojke između 1024 i 65536, zatim uđite u event način kroz csi.IOCTL_GENX320_SET_MODE s csi.GENX320_MODE_EVENT i veličinom međuspremnika. Čitajte događaje s csi.IOCTL_GENX320_READ_EVENTS, koji puni međuspremnik do njegovog kapaciteta i vraća broj valjanih redaka.

Image.draw_event_histogram rasterizira događaje u sliku u sivim tonovima — za svaki ON događaj dodaje contrast u spremnik; za svaki OFF događaj oduzima. clear=True najprije resetira sliku na brightness; clear=False akumulira kroz mnogo poziva:

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())

Predefinirane postavke biasa histogramskog načina, AFK filtar i ioctli za kalibraciju vrućih piksela svi rade na isti način u event načinu — pozovite ih nakon csi.IOCTL_GENX320_SET_MODE.

Filtriranje po polaritetu

Izrežite polje događaja pomoću ulab kako biste zadržali samo ON događaje (pokret prema svjetlijem stanju) ili samo OFF događaje:

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)

Akumulacija duge ekspozicije

Postavite clear=False da nastavite slagati događaje u istu sliku kroz mnogo sličica — rezultat je vizualizacija traga pokreta. Povremeno resetirajte da započnete novu ekspoziciju:

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

Obrada visoke brzine

Izostavite vizualizaciju kako biste oslobodili CPU za obradu događaja. Ispisujte statistiku samo svake N-te iteracije — slanje ispisne linije pri svakoj iteraciji postaje usko grlo pri visokim brzinama događaja:

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")

Filtar prostorno-vremenskog kontrasta (STC)

Stvarni pokretni kontrastni rub obično okida bučni rafal događaja na istom pikselu unutar kratkog vremenskog prozora — neusklađenost piksela i analogni šum proizvode dodatne događaje oko stvarnog prijelaza koji nisu korisni primjeni. STC filtar je naknadna obrada na čipu koja zadržava samo jedan (ili nekoliko) događaja po rafalu i odbacuje ostale.

Implementira tri strategije, odabrane putem csi.IOCTL_GENX320_SET_STC i GENX320_STC_* konstante. Svaki način definiran je time koje događaje prosljeđuje iz rafala:

Način

Zadržava

Odbacuje

csi.GENX320_STC_DISABLE

svaki događaj

ništa

csi.GENX320_STC_ONLY

drugi događaj rafala

prvi + kasnije događaje

csi.GENX320_STC_TRAIL_ONLY

prvi događaj rafala

naredne događaje

csi.GENX320_STC_TRAIL

prvi + naredne rubove

samo suvišni šum

Detaljno:

  • csi.GENX320_STC_DISABLE — filtar isključen, svaki događaj prolazi (zadano).

  • csi.GENX320_STC_ONLY — zadržava drugi događaj rafala. Parametar: stc_threshold (ms). Ako novi događaj na pikselu stigne unutar stc_threshold od prethodnog događaja, smatra se „drugim” događajem rafala i prosljeđuje se — prvi događaj i bilo koji naredni događaji u istom rafalu se filtriraju. Najbolje kada želite prijelaz potvrđen šumom umjesto samog prvog pogotka.

  • csi.GENX320_STC_TRAIL_ONLY — zadržava prvi događaj rafala. Parametar: trail_threshold (ms). Nakon što piksel okine, naredni događaji na istom pikselu se odbacuju dok ne istekne trail_threshold. Čuva precizno vrijeme vodećeg ruba — korisno kada je trenutak promjene polariteta važniji od potvrde rafala.

  • csi.GENX320_STC_TRAIL — kombinira oboje. Parametri: stc_threshold i trail_threshold (oba ms). Zadržava vodeći rub prema Trail načinu plus naredne rubove prema STC načinu, tako da i dalje prolazi više događaja iz rafala — veća propusnost događaja od jednonačinskih filtara, ali najbogatiji signal.

Dva praga moraju ostati otprilike unutar omjera 13:1 — senzor odbija konfiguracije gdje je jedan više od ~13x veći od drugog:

csi0.ioctl(csi.IOCTL_GENX320_SET_STC, csi.GENX320_STC_TRAIL, 1, 2)
csi0.ioctl(csi.IOCTL_GENX320_SET_STC, csi.GENX320_STC_DISABLE)

Dubina međuspremnika

Kada brzine događaja skoče, zadani trostruko-spremnikovani protok daje prednost najnovijoj sličici i odbacuje stare. Povećajte dubinu FIFO-a putem csi.CSI.framebuffers da umjesto toga stavite događaje u red čekanja — uz cijenu obrade nešto starijih podataka kada host zaostane:

csi0.framebuffers(10)  # FIFO depth, > 3 enables queueing

Streaming i vizualizacija na računalu

Za vizualizaciju GUI-ja u stvarnom vremenu na host računalu, alat GenX320 Event Streaming u repozitoriju openmv-projects uparuje kameru s DearPyGui sučeljem. PC GUI pokreće dvije vizualizacije jednu uz drugu: platno za akumulaciju događaja (ista ideja kao Image.draw_event_histogram ali s odabirljivim paletama i načinima kliznog prozora vs. automatskog brisanja) i kartu frekvencije po pikselu vođenu IIR pojasnopropusnim filtrom — korisno za uočavanje periodičnih signala (rotirajući ventilatori, trepćuće LED diode itd.) izravno u toku događaja.

Dolazi s dvije skripte za streaming na kameri:

  • Obrađeni način (genx320_event_mode_streaming_on_cam.py) — kamera dekodira događaje s csi.IOCTL_GENX320_READ_EVENTS i tokovno šalje svaki redak kao 12 bajtova preko USB-a ([0] tip, [1] sek, [2] ms, [3] us, [4] x, [5] y). Lako za obradu na PC-u jer se format na vezi podudara s formatom ndarray na kameri.

  • Sirovi način (genx320_raw_event_mode_streaming_on_cam.py) — kamera tokovno šalje čipove izvorne 32-bitne pakirane event riječi kroz csi.IOCTL_GENX320_READ_EVENTS_RAW. To je 4 bajta po događaju naspram 12 u obrađenom načinu (oko 3x manje podataka preko USB-a), pa ~3x veća ostvariva brzina događaja kada je veza usko grlo. PC dekodira pakirane riječi natrag u isti raspored događaja od 6 stupaca koristeći vektorizirani numpy, pa je kod nizvodnog vizualizatora identičan.

Sirovi način je zadani u GUI-ju jer je propusnost USB-a vezujuće ograničenje pri brzinama koje GenX320 može proizvesti; prebacite se na obrađeni način ako trebate uključiti logiku obrade u skriptu na kameri.