Мультиспектральна подієва камера

Модуль Multispectral Event Camera поєднує подієвий датчик GENX320 з 1 МП кольоровим датчиком PAG7936 з глобальним затвором на одному модулі — синхронізований конвеєр подій та кольору для високошвидкісного відстеження об’єктів, відстеження LED, візуалізації потоків рідини та інших динамічних сцен.

Multispectral Event Camera

Повна документація, фотографії та замовлення — на сторінці продукту Multispectral Event Camera.

Примітка

Підтримується лише на OpenMV N6.

Основні характеристики

  • Подієвий датчик 320x320, динамічний діапазон >140 дБ, гістограми 375 Гц+

  • PAG7936 кольоровий: 1280x800 @ 120 FPS, 640x400 @ 240 FPS

  • Синхронізовані мітки часу подій із спільним тригером витримки

  • Bачить нижче 5 люкс без автовитримки

  • Споживання від ~3 мВт для потокової передачі подій

  • Орієнтований на високошвидкісне відстеження, відстеження LED та потоки рідини/частинок

Використання

Кольоровий датчик і подієвий датчик GENX320 отримують власний екземпляр csi.CSI. Перший виклик за замовчуванням прив’язується до основного датчика (PAG7936); другий — до GENX320 через передачу cid= csi.GENX320. Виконайте апаратне скидання кольорового датчика через csi.CSI.reset (hard=True), щоб підняти шину, і налаштуйте GENX320 з hard=False, щоб драйвер лише перепрограмував чіп без повторного перемикання скидання.

GENX320 виводить зображення 320x320 у режимі гістограми; PAG7936 на csi.QVGA виводить 320x200. Базове накладення нижче відсікає нижні 120 рядків кадру GENX320. Використовуйте перетворення гомографії (нижче) для точного накладення або більшого розміру кадру PAG7936.

Два робочих буфери залишаються незмінними протягом циклу обробки кадрів — 256x1 альфа-палітра, збережена як image.Image, щоб пікселі гістограми на рівні базової яскравості (128) були прозорими, а підсвічення ON-подій і тіні OFF-подій були непрозорими, і попередньо виділений кадровий буфер GENX320 через image.Image, щоб csi.CSI.snapshot (blocking=False, image=...) міг заповнювати його на місці в кожній ітерації без повторного виділення пам’яті:

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

Кожна ітерація робить блокуючий кольоровий знімок і неблокуючий знімок GENX320. Image.draw_image потім компонує обидва: color_palette= image.PALETTE_EVT_LIGHT (або image.PALETTE_EVT_DARK для темного фону) перетворює гістограму GENX320 у відтінках сірого на кольоровий градієнт, alpha_palette= змішує кожен піксель за допомогою V-подібної альфа-карти, щоб тихі ділянки сцени просвічували крізь кольорове зображення, а hint= image.BILINEAR згладжує збільшення, коли кольоровий датчик працює з більшою роздільною здатністю, ніж GENX320.

Налаштування упередженості GENX320, фільтр AFK, калібрування гарячих пікселів та ioctl-виклики фільтра STC працюють однаково в цій двокамерній конфігурації — викликайте їх на csi1 після csi.CSI.reset. Деталі — у розділах нижче.

Вирівнювання з апаратним прискоренням GPU

Image.draw_image приймає аргумент transform= — матрицю гомографії 3x3 у вигляді 2-вимірного масиву ulab.numpy. На OpenMV N6 GPU виконує проєкцію попіксельно під час того самого малювання, тому кадр GENX320 можна вирівняти відносно перспективи кольорової камери без окремого проходу деформації — корисно, коли два датчики мають дещо різну оптику або поля зору, або коли кольорова камера працює з більшою роздільною здатністю. Відкаліруйте матрицю для кожної камери за допомогою інструменту калібрування накладення GenX320, який відображає мерехтливу шахівницю, щоб подієвий датчик генерував кутові події без будь-якого фізичного руху:

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

Цей варіант запускає кольорову камеру на csi.VGA (640x480), а GENX320 — на його рідному 320x320 — гомографія проєктує менший кадр GENX320 у більший кольоровий кадр під час малювання, тому коефіцієнт масштабування вбудований у саму матрицю, а не застосовується окремо.

Деталі подієвої камери

GENX320 — це датчик зору на основі подій — замість зчитування всього масиву 320x320 за фіксованим тактом кадрів, кожен піксель асинхронно повідомляє про «події» в момент виявлення зміни яскравості. Кожна подія містить координати X/Y, полярність ON/OFF (світлий→темний або темний→світлий) та мікросекундну мітку часу. Саме звідси походять мікросекундна часова точність датчика, відсутність розмиття при русі, дуже високий динамічний діапазон і масштабоване за активністю споживання. Статичні сцени не генерують жодних даних.

Мікропрограма OpenMV надає доступ до GENX320 через csi.CSI з cid= csi.GENX320. Доступні два режими роботи:

  • Режим гістограми (за замовчуванням) — події накопичуються на чіпі в побінові лічильники попіксельно та передаються у вигляді кадру у відтінках сірого 320x320 з налаштовуваною частотою (~20-350 FPS). Датчик поводиться як звичайна камера, тому всі стандартні процедури обробки зображень (Image.find_blobs, палітри тощо) працюють безпосередньо.

  • Режим подій — сирі події передаються в numpy ndarray з повними мікросекундними мітками часу для застосувань, яким потрібна часова деталізація, а не попередньо відсортований кадр.

Режим гістограми

У режимі гістограми GENX320 виводить кадри у відтінках сірого, де кожен піксель кодує нещодавню подієву активність у цьому місці. Пікселі вище базової яскравості є ON-подіями (зростання яскравості), нижче — OFF-подіями (спад яскравості). Базова яскравість за замовчуванням — 128, а крок контрасту на подію — 16 — збільшіть контраст, щоб події стали помітнішими:

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 і csi.CSI.framerate — три регулятори, що формують вихід гістограми.

Кольоровий вихід

Встановіть csi.CSI.color_palette на image.PALETTE_EVT_LIGHT для світлого фону або image.PALETTE_EVT_DARK для темного — драйвер безпосередньо виводить кадри RGB565 з використанням палітри:

csi0.color_palette(image.PALETTE_EVT_LIGHT)

Калібрування гарячих пікселів

Подієві датчики накопичують «гарячі пікселі», що спрацьовують помилково. Запустіть csi.IOCTL_GENX320_CALIBRATE на статичній сцені, щоб вимкнути їх. Драйвер будує попіксельний лічильник влучань 320x320, обчислює середнє значення та стандартне відхилення і вимикає будь-який піксель, чий лічильник перевищує mean + sigma * stddev — після цього вимкнені пікселі перестають генерувати події на рівні датчика.

Два параметри контролюють калібрування:

  • event_count — скільки подій підраховувати перед обчисленням статистики. Цикл захоплює кадри, поки загальна кількість подій не перевищить це значення. Вищі значення дають надійнішу оцінку коштом довшого часу калібрування. 10000 — розумна відправна точка.

  • sigma — множник порогу на стандартне відхилення. Менші значення агресивніші (більше вимкнених пікселів); більші — консервативніші. 0.5 — хороше значення за замовчуванням.

Спрямуйте датчик на статичну сцену, щоб події, спричинені рухом, не зараховувалися до пікселів, що насправді справні:

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

Антибліковий (AFK) фільтр

Переривчасті джерела світла (люмінесцентні, дисплеї з LED-підсвіткою) генерують великі обсяги надлишкових подій. Фільтр AFK відхиляє події, чиї пікселі перемикаються з частотою в межах смуги — увімкніть його через csi.IOCTL_GENX320_SET_AFK із межами смуги в герцах:

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

Попередньо встановлені значення упередженості

Кожен піксель GenX320 використовує аналоговий фронтенд із кількома налаштовуваними упередженостями. Разом вони визначають чутливість, шум, смугу пропускання пікселя та частоту подій — оптимальна комбінація залежить від сцени. Окремі упередженості:

  • DIFF_ON — поріг контрасту позитивного компаратора. Піксель генерує ON-подію, коли його логарифм освітленості зростає на цю величину. Менше = більша чутливість до яскравих переходів.

  • DIFF_OFF — поріг контрасту негативного компаратора (симетричний аналог для OFF-подій). Менше = більша чутливість до темних переходів.

  • FO — частота зрізу низькочастотного фільтра пікселя. Більше = ширша смуга пропускання пікселя (швидша реакція, менша затримка), але більша фонова шумова активність.

  • HPF — частота зрізу високочастотного фільтра. Більше = сильніше відхилення повільних змін яскравості; лише швидкі переходи досягають компараторів. Корисно для ігнорування фонового дрейфу.

  • REFR — рефрактерний період. Після спрацювання пікселя він залишається у стані скидання протягом цього часу, перш ніж може спрацювати знову. Більше = довший мертвий час, корисно для обмеження частоти подій на піксель.

Після csi.CSI.reset драйвер застосовує csi.GENX320_BIASES_LOW_NOISE, а не csi.GENX320_BIASES_DEFAULT — значення за замовчуванням із технічного паспорта генерують значно вищу фонову частоту подій, тому LOW_NOISE використовується як відправна точка для підтримання тихого потоку. Викличте csi.IOCTL_GENX320_SET_BIASES з іншим набором, коли застосунку потрібна більша чутливість або смуга пропускання.

csi.IOCTL_GENX320_SET_BIASES застосовує один з п’яти наборів:

  • csi.GENX320_BIASES_DEFAULT — значення за замовчуванням із технічного паспорта GenX320. Збалансована чутливість, шум і смуга пропускання для загальних сцен.

  • csi.GENX320_BIASES_LOW_LIGHT — обидва пороги контрасту послаблені для вищої чутливості, FO знижено для зменшення шуму, а HPF встановлено на 0, щоб повільні зміни яскравості все одно реєструвалися — сцена зі слабким освітленням сама по собі генерує мало подій, тому потрібно пропускати якомога більше.

  • csi.GENX320_BIASES_ACTIVE_MARKER — налаштований для відстеження блімаючих LED з високим контрастом. Пороги контрасту підвищені, щоб спрацьовували лише різкі переходи; FO та HPF максимально збільшені для максимальної смуги пропускання пікселя та відхилення будь-якого повільного фонового дрейфу; REFR знижено до 0, щоб фіксувати кожен фронт спалаху послідовно. Результат: потік, що майже повністю складається з фронтів LED, легко відстежувати.

  • csi.GENX320_BIASES_LOW_NOISE — значення за замовчуванням драйвера. Обидва пороги контрасту підвищені порівняно з DEFAULT (менша чутливість), а FO знижено (повільніший піксель = тихіший піксель). Найкраще для статичних або повільних сцен, де хибні події інакше домінували б.

  • csi.GENX320_BIASES_HIGH_SPEED — FO збільшено, щоб кожен піксель міг реагувати швидше, HPF підвищено для відхилення повільного дрейфу яскравості, а REFR збільшено, щоб один швидкорухомий фронт не переповнював зчитування — довший мертвий час тримає обсяг подій у межах при інтенсивному русі.

Перевизначте окремі упередженості за допомогою csi.IOCTL_GENX320_SET_BIAS з одним із csi.GENX320_BIAS_DIFF_ON, csi.GENX320_BIAS_DIFF_OFF, csi.GENX320_BIAS_FO, csi.GENX320_BIAS_HPF або csi.GENX320_BIAS_REFR і значенням ЦАП. Кожна упередженість встановлюється незалежно — виберіть набір як відправну точку, потім відрегулюйте потрібні упередженості для вашої сцени:

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

Відстеження

Оскільки вихід у режимі гістограми є просто зображенням у відтінках сірого, звичайне відстеження плям працює безпосередньо. Для відстеження LED активного маркера завантажте набір упередженостей для активного маркера та знайдіть плями на яскравому кінці гістограми:

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

Режим подій

Режим подій обходить апаратну гістограму та передає сирі події в numpy ndarray. Кожна подія є рядком із шести стовпців uint16:

  • [0] тип події — дивіться нижче

  • [1] мітка часу в секундах

  • [2] мітка часу в мілісекундах

  • [3] мітка часу в мікросекундах

  • [4] координата X, 0-319

  • [5] координата Y, 0-319

Драйвер генерує шість типів подій у стовпці [0]:

  • csi.PIX_OFF_EVENT — піксель виявив зниження яскравості (перетнуто поріг компаратора DIFF_OFF). X/Y вказують на піксель, що спрацював.

  • csi.PIX_ON_EVENT — піксель виявив збільшення яскравості (перетнуто поріг DIFF_ON). X/Y вказують на піксель.

  • csi.EXT_TRIGGER_FALLING — зовнішній тригерний вивід датчика побачив спадний фронт. X/Y не використовуються.

  • csi.EXT_TRIGGER_RISING — зовнішній тригерний вивід датчика побачив наростаючий фронт. X/Y не використовуються.

  • csi.RST_TRIGGER_FALLING — тригер скидання пікселя, спадний фронт. X/Y не використовуються. Наразі не генерується мікропрограмою.

  • csi.RST_TRIGGER_RISING — тригер скидання пікселя, наростаючий фронт. X/Y не використовуються. Наразі не генерується мікропрограмою.

Зовнішній тригерний вхід GENX320 з’єднаний з лінією синхронізації кадрів камери, яка також виведена на P10 як на процесорі, так і на рейці виводів — подайте сигнал на P10 для введення синхроімпульсів у потік подій і отримайте їх як події EXT_TRIGGER_RISING / EXT_TRIGGER_FALLING разом з даними пікселів.

Більшість застосувань цікавляться лише PIX_OFF_EVENT і PIX_ON_EVENT; типи тригерів дозволяють співвідносити події з зовнішніми сигналами синхронізації.

Виділіть буфер подій з формою (EVT_res, 6), де EVT_res — степінь двійки від 1024 до 65536, потім увімкніть режим подій через csi.IOCTL_GENX320_SET_MODE з csi.GENX320_MODE_EVENT і розміром буфера. Читайте події за допомогою csi.IOCTL_GENX320_READ_EVENTS, який заповнює буфер до його місткості та повертає кількість дійсних рядків.

Image.draw_event_histogram растеризує події в зображення у відтінках сірого — для кожної ON-події додає contrast до бін; для кожної OFF-події віднімає. clear=True скидає зображення до brightness спочатку; clear=False накопичує за кількома викликами:

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

Набори упередженостей режиму гістограми, фільтр AFK та ioctl-виклики калібрування гарячих пікселів працюють однаково в режимі подій — викликайте їх після csi.IOCTL_GENX320_SET_MODE.

Фільтрування за полярністю

Нарізайте масив подій за допомогою ulab, щоб залишити лише ON-події (рух до яскравішого стану) або лише OFF-події:

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)

Накопичення з тривалою витримкою

Встановіть clear=False, щоб продовжувати стекувати події в одне зображення протягом багатьох кадрів — результатом є візуалізація слідів руху. Скидайте periodically, щоб почати нову витримку:

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

Високошвидкісна обробка

Прибрати візуалізацію, щоб звільнити CPU для обробки подій. Виводьте статистику лише кожної N-ї ітерації — виведення рядка в кожній ітерації стає вузьким місцем при високих частотах подій:

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

Просторово-часовий контрастний (STC) фільтр

Реальний рухомий контрастний перехід, як правило, викликає гучний сплеск подій на одному пікселі протягом короткого часового вікна — невідповідність пікселів та аналоговий шум генерують додаткові події навколо справжнього переходу, що не є корисними для застосунку. Фільтр STC — це апаратний постпроцес, що зберігає лише одну (або кілька) подій з кожного сплеску і відкидає решту.

Реалізовано три стратегії, вибір яких здійснюється через csi.IOCTL_GENX320_SET_STC і константу GENX320_STC_*. Кожен режим визначається тим, які події він пропускає зі сплеску:

Режим

Зберігає

Відкидає

csi.GENX320_STC_DISABLE

кожну подію

нічого

csi.GENX320_STC_ONLY

другу подію сплеску

першу + наступні події

csi.GENX320_STC_TRAIL_ONLY

першу подію сплеску

наступні події

csi.GENX320_STC_TRAIL

першу + наступні фронти

лише надлишковий шум

Детально:

  • csi.GENX320_STC_DISABLE — фільтр вимкнено, всі події проходять (за замовчуванням).

  • csi.GENX320_STC_ONLY — зберігає другу подію сплеску. Параметр: stc_threshold (мс). Якщо нова подія на пікселі надходить у межах stc_threshold після попередньої події, вона вважається «другою» сплеску і передається далі — перша подія та будь-які наступні події того самого сплеску фільтруються. Найкраще, коли потрібен шумопідтверджений перехід, а не перше спрацювання.

  • csi.GENX320_STC_TRAIL_ONLY — зберігає першу подію сплеску. Параметр: trail_threshold (мс). Після спрацювання пікселя наступні події на тому самому пікселі відкидаються, поки не мине trail_threshold. Зберігає точний час провідного фронту — корисно, коли момент перемикання полярності важливіший за підтвердження сплеску.

  • csi.GENX320_STC_TRAIL — поєднує обидва. Параметри: stc_threshold і trail_threshold (обидва в мс). Зберігає провідний фронт за режимом Trail плюс наступні фронти за режимом STC, тому кілька подій зі сплеску все одно проходять — вища пропускна здатність подій порівняно з однорежимними фільтрами, але найбагатший сигнал.

Два пороги мають зберігатися приблизно у співвідношенні 13:1 — датчик відхиляє конфігурації, де один більш ніж приблизно в 13 разів перевищує інший:

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

Глибина буфера

Коли частота подій різко зростає, стандартний конвеєр з потрійним буфером надає перевагу найновішому кадру і відкидає старі. Збільште глибину FIFO через csi.CSI.framebuffers, щоб ставити події в чергу — коштом обробки дещо застарілих даних, коли хост відстає:

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

Стримінг і візуалізація на робочому столі

Для візуалізації в реальному часі у GUI на ПК, інструмент GenX320 Event Streaming у репозиторії openmv-projects поєднує камеру з DearPyGui-фронтендом. GUI на ПК показує дві візуалізації поряд: полотно накопичення подій (та сама ідея, що й Image.draw_event_histogram, але з вибірними палітрами та режимами ковзного вікна і автоочищення) і карту частот по пікселях на основі IIR смугового фільтра — корисно для виявлення periodичних сигналів (обертові вентилятори, LED, що миготять тощо) безпосередньо в потоці подій.

У комплект входять два скрипти потокової передачі з камери:

  • Оброблений режим (genx320_event_mode_streaming_on_cam.py) — камера декодує події за допомогою csi.IOCTL_GENX320_READ_EVENTS і передає кожен рядок як 12 байт через USB ([0] тип, [1] сек, [2] мс, [3] мкс, [4] x, [5] y). Легко споживати на ПК, оскільки формат дроту збігається з форматом ndarray на камері.

  • Сирий режим (genx320_raw_event_mode_streaming_on_cam.py) — камера передає рідні 32-бітні упаковані слова подій чіпа через csi.IOCTL_GENX320_READ_EVENTS_RAW. Це 4 байти на подію проти 12 в обробленому режимі (приблизно в 3 рази менше даних через USB), тому досяжна частота подій приблизно в 3 рази вища, коли посилання є вузьким місцем. ПК декодує упаковані слова назад у той самий 6-стовпчиковий формат подій за допомогою векторизованого numpy, тому код візуалізатора є ідентичним.

Сирий режим є стандартним у GUI, оскільки пропускна здатність USB є обмежувальним чинником при частотах, які може генерувати GenX320; перейдіть на оброблений режим, якщо потрібно вбудувати логіку обробки в скрипт на камері.