Multispektral händelsekamera

Multispectral Event Camera-modulen kombinerar GENX320-händelsesensorn med en 1 MP PAG7936-färgsensor med global slutare på en enda modul — en synkroniserad händelse- och färgpipeline för höghastighetsspårning av objekt, LED-spårning, vätskeflöde och andra dynamiska scener.

Multispektral händelsekamera

För fullständigt datablad, foton och beställning, se produktsidan för Multispectral Event Camera.

Anteckning

Stöds endast på OpenMV N6.

Höjdpunkter

  • 320x320 händelsesensor, >140 dB dynamiskt omfång, 375 Hz+ histogram

  • PAG7936 färg: 1280x800 @ 120 FPS, 640x400 @ 240 FPS

  • Synkroniserade händelsetidsstämplar med delad exponeringsutlösare

  • Ser under 5 lux utan autoexponering

  • Effektförbrukningen startar vid ~3 mW för händelseströmning

  • Riktad mot höghastighetsspårning, LED-spårning och vätske-/partikelflöde

Användning

Färgsensorn och GENX320-händelsesensorn får var sin egen csi.CSI-instans. Det första anropet använder som standard den primära sensorn (PAG7936); det andra binder till GENX320 genom att skicka cid= csi.GENX320. Gör en hård återställning av färgsensorn med csi.CSI.reset (hard=True) för att slå på spänningsmatningen, och konfigurera GENX320 med hard=False så att dess drivrutin endast omprogrammerar kretsen utan att växla återställningen igen.

GENX320 ger 320x320 i histogramläge; PAG7936 vid csi.QVGA ger 320x200. Det grundläggande överlägget nedan klipper bort de nedersta 120 raderna av GENX320-bildrutan. Använd homografitransformen (nedan) för ett anpassat överlägg eller en större PAG7936-bildstorlek.

Två arbetsbuffertar förblir konstanta under bildslingan — en 256x1 alfa-palett lagrad som en image.Image så att histogrampixlar vid mittengråbaslinjen (128) blir transparenta medan både ON-händelsehöjdpunkter och OFF-händelseskuggor blir ogenomskinliga, och en GENX320-bildbuffert som förallokeras med image.Image så att csi.CSI.snapshot (blocking=False, image=...) kan fylla den på plats vid varje iteration utan omallokering:

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

Varje iteration tar en blockerande färgstillbild och en icke-blockerande GENX320-stillbild. Image.draw_image komponerar sedan de två: color_palette= image.PALETTE_EVT_LIGHT (eller image.PALETTE_EVT_DARK för en mörk bakgrund) mappar GENX320:s gråskalehistogram till en färgramp, alpha_palette= blandar varje pixel med den v-formade alfakartan så att lugna områden i scenen släpper igenom till färgbilden, och hint= image.BILINEAR jämnar ut uppskalningen när färgsensorn körs med högre upplösning än GENX320.

GENX320:s bias-förinställningar, AFK-filter, kalibrering av hotpixlar och STC-filtrets ioctls fungerar alla på samma sätt i denna dubbelkamerakonfiguration — anropa dem på csi1 efter csi.CSI.reset. Se avsnitten nedan för detaljer.

GPU-accelererad inriktning

Image.draw_image accepterar ett transform=-argument — en 3x3 homografimatris som en 2D ulab.numpy-array. På OpenMV N6 kör GPU:n per-pixel-projektionen under samma rityttning, så GENX320-bildrutan kan omjusteras mot färgkamerans perspektiv utan ett separat warp-pass — användbart när de två sensorerna har något olika optik eller synfält, eller när färgkameran körs med högre upplösning. Kalibrera matrisen per kamera med GenX320 Overlay Calibration-verktyget, som visar ett flimrande schackbräde så att händelsesensorn genererar hörnhändelser utan någon fysisk rörelse:

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

Denna variant kör färgkameran vid csi.VGA (640x480) och GENX320 vid dess inbyggda 320x320 — homografin projicerar den mindre GENX320-bildrutan in i den större färgbildrutan som en del av rityttningen, så uppskalningsfaktorn är inbakad i själva matrisen i stället för att tillämpas separat.

Detaljer om händelsekameran

GENX320 är en händelsebaserad synsensor — i stället för att läsa ut hela 320x320-arrayen med en fast bildklocka rapporterar varje pixel asynkrona ”händelser” i samma ögonblick som den upptäcker en ljusstyrkeändring. Varje händelse bär en X/Y-koordinat, en ON/OFF-polaritet (ljust→mörkt eller mörkt→ljust) och en mikrosekundstidsstämpel. Det är därifrån sensorns temporala precision på mikrosekundsnivå, frånvaron av rörelseoskärpa, mycket höga dynamiska omfång och aktivitetsskalade effektförbrukning kommer. Statiska scener genererar ingen data.

OpenMV:s fasta programvara exponerar GENX320 via csi.CSI med cid= csi.GENX320. Två driftslägen är tillgängliga:

  • Histogramläge (standard) — händelser ackumuleras på kretsen i per-pixel-fack och rapporteras som en 320x320 gråskalebildruta med en konfigurerbar hastighet (~20-350 FPS). Sensorn beter sig som en vanlig kamera, så alla standardrutiner för bildbehandling (Image.find_blobs, paletter osv.) fungerar direkt.

  • Händelseläge — råa händelser strömmar in i en numpy ndarray med fullständiga mikrosekundstidsstämplar, för tillämpningar som behöver den temporala detaljen snarare än en förbinnad bildruta.

Histogramläge

I histogramläge ger GENX320 gråskalebildrutor där varje pixel kodar den senaste händelseaktiviteten på den platsen. Pixlar ovanför ljusstyrkebaslinjen är ON-händelser (ljusstyrkan stiger), under är OFF-händelser (ljusstyrkan faller). Standardbaslinjens ljusstyrka är 128 och kontraststeget per händelse är 16 — höj kontrasten för att få händelserna att framträda:

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 och csi.CSI.framerate är de tre rattarna som formar histogramutdatan.

Färglagd utdata

Ställ in csi.CSI.color_palette till image.PALETTE_EVT_LIGHT för en ljus bakgrund eller image.PALETTE_EVT_DARK för en mörk — drivrutinen avger RGB565-bildrutor med paletten direkt:

csi0.color_palette(image.PALETTE_EVT_LIGHT)

Kalibrering av hotpixlar

Händelsesensorer samlar på sig ”hotpixlar” som utlöses oäkta. Kör csi.IOCTL_GENX320_CALIBRATE mot en statisk scen för att inaktivera dem. Drivrutinen bygger en 320x320 per-pixel-träffräknare, beräknar medelvärdet och standardavvikelsen, och inaktiverar varje pixel vars antal ligger över mean + sigma * stddev — sedan slutar de inaktiverade pixlarna avge händelser på sensornivå.

Två parametrar styr kalibreringen:

  • event_count — hur många händelser som ska räknas innan statistiken beräknas. Slingan fångar bildrutor tills den löpande händelsesumman passerar denna budget. Högre antal ger en mer tillförlitlig uppskattning på bekostnad av längre kalibreringstid. 10000 är en rimlig utgångspunkt.

  • sigma — tröskelmultiplikator på standardavvikelsen. Lägre värden är mer aggressiva (fler pixlar inaktiveras); högre värden är mer konservativa. 0.5 är ett bra standardvärde.

Rikta sensorn mot en statisk scen först så att inga rörelsedrivna händelser räknas mot pixlar som faktiskt är felfria:

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

Antiflimmerfilter (AFK)

Periodiska ljuskällor (lysrör, LED-drivna skärmar) genererar enorma mängder överflödiga händelser. AFK-filtret avvisar händelser vars pixel växlar med en frekvens inom ett band — aktivera det via csi.IOCTL_GENX320_SET_AFK med bandkanterna i hertz:

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

Bias-förinställningar

Varje pixel i GenX320 kör en analog frontend med flera konfigurerbara bias. De styr gemensamt känslighet, brus, pixelbandbredd och händelsefrekvens — rätt kombination beror på scenen. De enskilda bias är:

  • DIFF_ON — den positiva komparatorns kontrasttröskelvärde. En pixel avger en ON-händelse när dess log-belysning har stigit med så mycket. Lägre = känsligare för ljusa övergångar.

  • DIFF_OFF — den negativa komparatorns kontrasttröskelvärde (den symmetriska motsvarigheten för OFF-händelser). Lägre = känsligare för mörka övergångar.

  • FO — pixelns lågpassfiltrets gränsfrekvens. Högre = bredare pixelbandbredd (snabbare respons, lägre latens) men mer bakgrundsbrusaktivitet.

  • HPF — högpassfiltrets gränsfrekvens. Högre = starkare avvisning av långsamma ljusstyrkeändringar; endast snabba övergångar når komparatorerna. Användbart för att ignorera omgivningsdrift.

  • REFR — refraktärperioden. Efter att en pixel utlösts förblir den i återställning så länge innan den kan utlösas igen. Högre = längre död tid, användbart för att begränsa händelsefrekvensen per pixel.

Efter csi.CSI.reset tillämpar drivrutinen csi.GENX320_BIASES_LOW_NOISE, inte csi.GENX320_BIASES_DEFAULT — databladets standardvärden avger en mycket högre bakgrundshändelsefrekvens, så LOW_NOISE används som utgångspunkt för att hålla strömmen tyst. Anropa csi.IOCTL_GENX320_SET_BIASES med en annan förinställning när tillämpningen behöver mer känslighet eller bandbredd.

csi.IOCTL_GENX320_SET_BIASES tillämpar en av fem förinställningar:

  • csi.GENX320_BIASES_DEFAULT — GenX320:s databladsstandardvärden. Balanserad känslighet, brus och bandbredd för allmänna scener.

  • csi.GENX320_BIASES_LOW_LIGHT — båda kontrasttröskelvärdena lättade för högre känslighet, FO sänkt för att hålla nere bruset, och HPF inställd på 0 så att långsamma ljusstyrkeändringar fortfarande registreras — en svagt belyst scen genererar få händelser på egen hand, så vi vill att så många som möjligt ska komma igenom.

  • csi.GENX320_BIASES_ACTIVE_MARKER — avstämd för att spåra blinkande LED-lampor med hög kontrast. Kontrasttröskelvärdena höjda så att endast skarpa övergångar utlöser; FO och HPF vevade högt för att maximera pixelbandbredden och avvisa all långsam omgivningsdrift; REFR dragen till 0 så att varje blinkkant fångas i följd. Resultatet: en ström som nästan helt består av LED-kanter, lätt att spåra.

  • csi.GENX320_BIASES_LOW_NOISE — drivrutinens standard. Båda kontrasttröskelvärdena höjda jämfört med DEFAULT (mindre känsliga) och FO sänkt (långsammare pixel = tystare pixel). Bäst för statiska eller långsamma scener där falska händelser annars skulle dominera.

  • csi.GENX320_BIASES_HIGH_SPEED — FO höjt så att varje pixel kan svara snabbare, HPF höjt för att avvisa långsam ljusstyrkedrift, och REFR höjt så att en enda snabbt rörlig kant inte översvämmar utläsningen — den längre döda tiden håller händelsevolymen begränsad under kraftig rörelse.

Åsidosätt enskilda bias med csi.IOCTL_GENX320_SET_BIAS plus en av csi.GENX320_BIAS_DIFF_ON, csi.GENX320_BIAS_DIFF_OFF, csi.GENX320_BIAS_FO, csi.GENX320_BIAS_HPF eller csi.GENX320_BIAS_REFR och ett DAC-värde. Varje bias ställs in oberoende — välj en förinställning som utgångspunkt och justera sedan de bias som din scen behöver:

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

Spårning

Eftersom histogramlägets utdata bara är en gråskalebild fungerar vanlig blobspårning direkt. För att spåra en LED med aktiv markör, läs in bias-förinställningen för aktiv markör och hitta blobbar i den ljusa änden av histogrammet:

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

Händelseläge

Händelseläget kringgår histogrammet på kretsen och strömmar råa händelser in i en numpy ndarray. Varje händelse är en rad med sex uint16-kolumner:

  • [0] händelsetyp — se nedan

  • [1] sekundstidsstämpel

  • [2] millisekundstidsstämpel

  • [3] mikrosekundstidsstämpel

  • [4] X-koordinat, 0-319

  • [5] Y-koordinat, 0-319

Drivrutinen avger sex händelsetyper i kolumn [0]:

  • csi.PIX_OFF_EVENT — en pixel upptäckte en minskning av ljusstyrkan (komparatortröskelvärdet DIFF_OFF korsades). X/Y pekar på pixeln som utlöstes.

  • csi.PIX_ON_EVENT — en pixel upptäckte en ökning av ljusstyrkan (tröskelvärdet DIFF_ON korsades). X/Y pekar på pixeln.

  • csi.EXT_TRIGGER_FALLING — sensorns externa utlösarstift såg en fallande kant. X/Y används inte.

  • csi.EXT_TRIGGER_RISING — sensorns externa utlösarstift såg en stigande kant. X/Y används inte.

  • csi.RST_TRIGGER_FALLING — pixelåterställningsutlösare, fallande kant. X/Y används inte. Genereras inte av den fasta programvaran för närvarande.

  • csi.RST_TRIGGER_RISING — pixelåterställningsutlösare, stigande kant. X/Y används inte. Genereras inte av den fasta programvaran för närvarande.

GENX320:s externa utlösaringång är kopplad till kamerans bildsynkroniseringslinje, som också dras till P10 på både processorn och stiftlisten — driv P10 för att injicera synkroniseringskanter i händelseströmmen och plocka upp dem som EXT_TRIGGER_RISING / EXT_TRIGGER_FALLING-händelser vid sidan av pixeldatan.

De flesta tillämpningar bryr sig bara om PIX_OFF_EVENT och PIX_ON_EVENT; utlösartyperna låter dig korrelera händelser med externa tidssignaler.

Allokera händelsebufferten med formen (EVT_res, 6) där EVT_res är en tvåpotens mellan 1024 och 65536, gå sedan in i händelseläget via csi.IOCTL_GENX320_SET_MODE med csi.GENX320_MODE_EVENT och buffertstorleken. Läs händelser med csi.IOCTL_GENX320_READ_EVENTS, som fyller bufferten upp till dess kapacitet och returnerar antalet giltiga rader.

Image.draw_event_histogram rastrerar händelser till en gråskalebild — för varje ON-händelse lägger den till contrast i facket; för varje OFF-händelse subtraherar den. clear=True återställer först bilden till brightness; clear=False ackumulerar över många anrop:

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

Histogramlägets bias-förinställningar, AFK-filter och ioctls för kalibrering av hotpixlar fungerar alla på samma sätt i händelseläget — anropa dem efter csi.IOCTL_GENX320_SET_MODE.

Filtrering efter polaritet

Skiva händelsearrayen med ulab för att behålla endast ON-händelser (rörelse till ett ljusare tillstånd) eller endast OFF-händelser:

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)

Långexponeringsackumulering

Ställ in clear=False för att fortsätta stapla händelser i samma bild över många bildrutor — resultatet är en visualisering av rörelsespår. Återställ med jämna mellanrum för att starta en ny exponering:

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

Höghastighetsbehandling

Släpp visualiseringen för att frigöra CPU för händelsebehandling. Skriv ut statistik endast var N:e iteration — att skicka en utskriftsrad vid varje iteration blir flaskhalsen vid höga händelsefrekvenser:

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

Spatiotemporalt kontrastfilter (STC)

En verklig rörlig kontrastkant tenderar att utlösa en brusig skur av händelser på samma pixel inom ett kort tidsfönster — pixelfelmatchning och analogt brus producerar extra händelser kring den äkta övergången som inte är användbara för tillämpningen. STC-filtret är en efterbehandling på kretsen som behåller endast en (eller några få) händelser per skur och släpper resten.

Det implementerar tre strategier, valda via csi.IOCTL_GENX320_SET_STC och en GENX320_STC_*-konstant. Varje läge definieras av vilka händelser det vidarebefordrar från en skur:

Läge

Behåller

Släpper

csi.GENX320_STC_DISABLE

varje händelse

ingenting

csi.GENX320_STC_ONLY

andra händelsen i en skur

första + senare händelser

csi.GENX320_STC_TRAIL_ONLY

första händelsen i en skur

efterföljande händelser

csi.GENX320_STC_TRAIL

första + efterföljande kanter

endast överflödigt brus

I detalj:

  • csi.GENX320_STC_DISABLE — filter av, varje händelse passerar igenom (standard).

  • csi.GENX320_STC_ONLY — behåller den andra händelsen i en skur. Parameter: stc_threshold (ms). Om en ny händelse på en pixel anländer inom stc_threshold från en tidigare händelse betraktas den som den ”andra” i en skur och vidarebefordras — den första händelsen och alla efterföljande händelser i samma skur filtreras bort. Bäst när du vill ha en brusbekräftad övergång snarare än den allra första träffen.

  • csi.GENX320_STC_TRAIL_ONLY — behåller den första händelsen i en skur. Parameter: trail_threshold (ms). Efter att en pixel utlösts släpps efterföljande händelser på samma pixel tills trail_threshold har förflutit. Bevarar den exakta tidpunkten för den ledande kanten — användbart när ögonblicket för polaritetsväxlingen spelar större roll än skurbekräftelse.

  • csi.GENX320_STC_TRAIL — kombinerar båda. Parametrar: stc_threshold och trail_threshold (båda ms). Behåller den ledande kanten enligt Trail-läget plus efterföljande kanter enligt STC-läget, så att flera händelser från en skur fortfarande kommer igenom — högre händelsegenomströmning än enkellägesfiltren men den rikaste signalen.

De två tröskelvärdena måste hålla sig inom ungefär ett 13:1-förhållande — sensorn avvisar konfigurationer där det ena är mer än ~13x det andra:

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

Buffertdjup

När händelsefrekvenserna spikar gynnar standardpipelinen med trippelbuffert den senaste bildrutan och kasserar gamla. Höj FIFO-djupet via csi.CSI.framebuffers för att i stället köa händelser — på bekostnad av att något äldre data behandlas när värden hamnar på efterkälken:

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

Skrivbordsströmning och visualisering

För realtidsvisualisering i GUI på en värd-PC parar GenX320 Event Streaming-verktyget i openmv-projects-förvaret ihop kameran med en DearPyGui-frontend. PC-GUI:t kör två visualiseringar sida vid sida: en händelseackumuleringsduk (samma idé som Image.draw_event_histogram men med valbara paletter och lägen för glidande fönster kontra autorensning) och en per-pixel-frekvenskarta driven av ett IIR-bandpassfilter — användbar för att upptäcka periodiska signaler (roterande fläktar, blinkande LED-lampor osv.) direkt i händelseströmmen.

Det levereras med två strömningsskript på kameran:

  • Bearbetat läge (genx320_event_mode_streaming_on_cam.py) — kameran avkodar händelser med csi.IOCTL_GENX320_READ_EVENTS och strömmar varje rad som 12 byte över USB ([0] typ, [1] sek, [2] ms, [3] us, [4] x, [5] y). Lätt att konsumera på PC:n eftersom trådformatet matchar ndarray-formatet på kameran.

  • Råläge (genx320_raw_event_mode_streaming_on_cam.py) — kameran strömmar kretsens inbyggda 32-bitars packade händelseord genom csi.IOCTL_GENX320_READ_EVENTS_RAW. Det är 4 byte per händelse jämfört med 12 i bearbetat läge (ungefär 3x mindre data över USB), alltså ~3x högre uppnåelig händelsefrekvens när länken är flaskhalsen. PC:n avkodar de packade orden tillbaka till samma 6-kolumners händelselayout med vektoriserad numpy, så koden för den efterföljande visualiseraren är identisk.

Råläge är standard i GUI:t eftersom USB-genomströmningen är den begränsande faktorn vid de frekvenser som GenX320 kan producera; växla till bearbetat läge om du behöver koppla in bearbetningslogik i skriptet på kameran.