GENX320 Olay Kamerası¶
GENX320 Olay Kamerası Modülü, 320x320 çözünürlük ve mikrosaniye zamansal hassasiyete sahip Prophesee olay tabanlı bir görüş sensörüdür.
Tam veri sayfası, fotoğraflar ve sipariş bilgileri için GENX320 Olay Kamerası ürün sayfasına bakın.
Not
OpenMV H7 Plus, RT1062 ve N6 üzerinde desteklenir.
Öne Çıkanlar¶
320x320 olay tabanlı görüş sensörü
140 dB dinamik aralık, hareket bulanıklığı yok
375 Hz+ olay-histogramı çıkış hızı
Güç, sahne etkinliğiyle ölçeklenir — yaklaşık 3 mW’tan başlar
Otomatik pozlama olmadan <5 lükstan parlak güneş ışığına kadar çalışır
Gri tonlamalı çerçeveler veya ham olay akışları üretir
Kullanım¶
GENX320 olay tabanlı bir görüş sensörüdür — sabit bir çerçeve saatinde tüm 320x320 diziyi okumak yerine, her piksel parlaklık değişimini algıladığı anda eşzamansız “olaylar” bildirir. Her olay bir X/Y koordinatı, bir AÇIK/KAPALI polarite (parlak→karanlık veya karanlık→parlak) ve bir mikrosaniye zaman damgası taşır. Sensörün mikrosaniye zamansal hassasiyeti, hareket bulanıklığı olmaması, çok yüksek dinamik aralığı ve etkinliğe göre ölçeklenen güç tüketimi buradan gelir. Durağan sahneler hiç veri üretmez.
OpenMV aygıt yazılımı (firmware) GENX320’yi csi.CSI üzerinden cid= csi.GENX320 ile sunar. İki çalışma modu mevcuttur:
Histogram modu (varsayılan) — olaylar çip üzerinde piksel başına kutucuklarda biriktirilir ve yapılandırılabilir bir hızda (~20-350 FPS) 320x320 gri tonlamalı bir çerçeve olarak bildirilir. Sensör normal bir kamera gibi davranır, böylece tüm standart görüntü işleme rutinleri (
Image.find_blobs, paletler vb.) doğrudan çalışır.Olay modu — ham olaylar, önceden kutucuklara ayrılmış bir çerçeve yerine zamansal ayrıntıya ihtiyaç duyan uygulamalar için tam mikrosaniye zaman damgalarıyla bir numpy
ndarrayiçine akar.
Histogram modu¶
Histogram modunda GENX320, her pikselin o konumdaki son olay etkinliğini kodladığı gri tonlamalı çerçeveler üretir. Parlaklık taban çizgisinin üzerindeki pikseller AÇIK olaylardır (parlaklık yükseliyor), altındakiler KAPALI olaylardır (parlaklık düşüyor). Varsayılan taban çizgisi parlaklığı 128 ve olay başına kontrast adımı 16’dır — olayları öne çıkarmak için kontrastı artırın:
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 ve csi.CSI.framerate, histogram çıktısını şekillendiren üç düğmedir.
Renklendirilmiş çıktı¶
Açık bir arka plan için csi.CSI.color_palette değerini image.PALETTE_EVT_LIGHT olarak, koyu bir arka plan için image.PALETTE_EVT_DARK olarak ayarlayın — sürücü, paleti doğrudan kullanarak RGB565 çerçeveler üretir:
csi0.color_palette(image.PALETTE_EVT_LIGHT)
Sıcak piksel kalibrasyonu¶
Olay sensörleri, sahte şekilde tetiklenen “sıcak pikseller” biriktirir. Bunları devre dışı bırakmak için durağan bir sahneye karşı csi.IOCTL_GENX320_CALIBRATE çalıştırın. Sürücü, piksel başına 320x320 vuruş sayısı oluşturur, ortalama ve standart sapmayı hesaplar ve sayısı mean + sigma * stddev değerinin üzerinde olan herhangi bir pikseli devre dışı bırakır — ardından devre dışı bırakılan pikseller sensör düzeyinde olay üretmeyi durdurur.
Kalibrasyonu iki parametre denetler:
event_count— istatistikleri hesaplamadan önce kaç olayın sayılacağı. Döngü, çalışan toplam olay bu bütçeyi aşana kadar çerçeve yakalar. Daha yüksek sayılar, daha uzun kalibrasyon süresi pahasına daha güvenilir bir tahmin verir.10000makul bir başlangıç noktasıdır.sigma— standart sapma üzerindeki eşik çarpanı. Daha düşük değerler daha agresiftir (daha fazla piksel devre dışı bırakılır); daha yüksek değerler daha tutucudur.0.5iyi bir varsayılandır.
Hareket kaynaklı olayların gerçekte sorunsuz olan piksellere karşı sayılmaması için sensörü önce durağan bir sahneye doğrultun:
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")
Titreşim önleme (AFK) filtresi¶
Periyodik ışık kaynakları (floresan, LED ile çalışan ekranlar) büyük miktarda gereksiz olay üretir. AFK filtresi, pikseli bir bant içindeki bir frekansta değişen olayları reddeder — bunu csi.IOCTL_GENX320_SET_AFK aracılığıyla bant kenarlarını hertz cinsinden vererek etkinleştirin:
csi0.ioctl(csi.IOCTL_GENX320_SET_AFK, 1, 130, 160) # 130-160 Hz
csi0.ioctl(csi.IOCTL_GENX320_SET_AFK, 0) # disable
Bias hazır ayarları¶
GenX320’deki her piksel, yapılandırılabilir birkaç bias’a sahip bir analog ön uç çalıştırır. Bunlar birlikte duyarlılığı, gürültüyü, piksel bant genişliğini ve olay hızını yönetir — doğru kombinasyon sahneye bağlıdır. Tek tek bias’lar şunlardır:
DIFF_ON — pozitif karşılaştırıcı kontrast eşiği. Bir piksel, log-aydınlatması bu kadar yükseldiğinde bir AÇIK olay üretir. Daha düşük = parlak geçişlere daha duyarlı.
DIFF_OFF — negatif karşılaştırıcı kontrast eşiği (KAPALI olaylar için simetrik karşılığı). Daha düşük = karanlık geçişlere daha duyarlı.
FO — pikselin alçak geçiren kesme frekansı. Daha yüksek = daha geniş piksel bant genişliği (daha hızlı yanıt, daha düşük gecikme) ancak daha fazla arka plan gürültüsü etkinliği.
HPF — yüksek geçiren kesme frekansı. Daha yüksek = yavaş parlaklık değişimlerinin daha güçlü reddedilmesi; yalnızca hızlı geçişler karşılaştırıcılara ulaşır. Ortam kaymasını yok saymak için kullanışlıdır.
REFR — refrakter süre. Bir piksel tetiklendikten sonra, tekrar tetiklenebilmesinden önce bu süre boyunca sıfırlanmış durumda kalır. Daha yüksek = daha uzun ölü süre, piksel başına olay hızını sınırlamak için kullanışlıdır.
csi.CSI.reset işleminden sonra sürücü, csi.GENX320_BIASES_DEFAULT değil csi.GENX320_BIASES_LOW_NOISE uygular — veri sayfası varsayılanları çok daha yüksek bir arka plan olay hızı üretir, bu nedenle akışı sessiz tutmak için başlangıç noktası olarak LOW_NOISE kullanılır. Uygulama daha fazla duyarlılık veya bant genişliğine ihtiyaç duyduğunda farklı bir hazır ayarla csi.IOCTL_GENX320_SET_BIASES çağırın.
csi.IOCTL_GENX320_SET_BIASES, beş hazır ayardan birini uygular:
csi.GENX320_BIASES_DEFAULT— GenX320 veri sayfası varsayılanları. Genel sahneler için dengeli duyarlılık, gürültü ve bant genişliği.csi.GENX320_BIASES_LOW_LIGHT— daha yüksek duyarlılık için her iki kontrast eşiği de gevşetilmiş, gürültüyü düşük tutmak için FO azaltılmış ve yavaş parlaklık değişimleri yine de kaydedilsin diye HPF 0 olarak ayarlanmıştır — az ışıklı bir sahne kendiliğinden az olay üretir, bu nedenle olabildiğince çoğunun geçmesini isteriz.csi.GENX320_BIASES_ACTIVE_MARKER— yüksek kontrastlı yanıp sönen LED’leri izlemek için ayarlanmıştır. Yalnızca keskin geçişlerin tetiklemesi için kontrast eşikleri yükseltilmiş; piksel bant genişliğini en üst düzeye çıkarmak ve herhangi bir yavaş ortam kaymasını reddetmek için FO ve HPF yükseğe çekilmiş; her yanıp sönme kenarının arka arkaya yakalanması için REFR 0’a çekilmiştir. Sonuç: neredeyse tamamen LED kenarlarından oluşan, izlemesi kolay bir akış.csi.GENX320_BIASES_LOW_NOISE— sürücü varsayılanı. Her iki kontrast eşiği deDEFAULTdeğerine göre yükseltilmiş (daha az duyarlı) ve FO azaltılmıştır (daha yavaş piksel = daha sessiz piksel). Sahte olayların aksi takdirde baskın olacağı durağan veya yavaş sahneler için en iyisidir.csi.GENX320_BIASES_HIGH_SPEED— her pikselin daha hızlı yanıt verebilmesi için FO yükseltilmiş, yavaş parlaklık kaymasını reddetmek için HPF yükseltilmiş ve hızlı hareket eden tek bir kenarın okumayı sel altında bırakmaması için REFR yükseltilmiştir — daha uzun ölü süre, yoğun hareket altında olay hacmini sınırlı tutar.
csi.IOCTL_GENX320_SET_BIAS ile csi.GENX320_BIAS_DIFF_ON, csi.GENX320_BIAS_DIFF_OFF, csi.GENX320_BIAS_FO, csi.GENX320_BIAS_HPF veya csi.GENX320_BIAS_REFR öğelerinden birini ve bir DAC değerini kullanarak tek tek bias’ları geçersiz kılın. Her bias bağımsız olarak ayarlanır — başlangıç noktası olarak bir hazır ayar seçin, ardından sahnenizin ihtiyaç duyduğu bias’ları ince ayarlayın:
csi0.ioctl(csi.IOCTL_GENX320_SET_BIASES, csi.GENX320_BIASES_LOW_LIGHT)
csi0.ioctl(csi.IOCTL_GENX320_SET_BIAS, csi.GENX320_BIAS_HPF, 20)
İzleme¶
Histogram modu çıktısı yalnızca bir gri tonlamalı görüntü olduğundan, normal nokta (blob) izleme doğrudan çalışır. Bir etkin işaretleyici LED’ini izlemek için etkin işaretleyici bias hazır ayarını yükleyin ve histogramın parlak ucunda noktalar (blob) bulun:
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())
Olay modu¶
Olay modu, çip üzerindeki histogramı atlar ve ham olayları bir numpy ndarray içine akıtır. Her olay, altı uint16 sütundan oluşan bir satırdır:
[0]olay türü — aşağıya bakın[1]saniye zaman damgası[2]milisaniye zaman damgası[3]mikrosaniye zaman damgası[4]X koordinatı, 0-319[5]Y koordinatı, 0-319
Sürücü, [0] sütununda altı olay türü üretir:
csi.PIX_OFF_EVENT— bir piksel parlaklık azalması algıladı (DIFF_OFFkarşılaştırıcı eşiği aşıldı). X/Y, tetiklenen pikseli gösterir.csi.PIX_ON_EVENT— bir piksel parlaklık artışı algıladı (DIFF_ONeşiği aşıldı). X/Y, pikseli gösterir.csi.EXT_TRIGGER_FALLING— sensörün harici tetikleyici pini bir düşen kenar gördü. X/Y kullanılmaz.csi.EXT_TRIGGER_RISING— sensörün harici tetikleyici pini bir yükselen kenar gördü. X/Y kullanılmaz.csi.RST_TRIGGER_FALLING— piksel sıfırlama tetikleyicisi, düşen kenar. X/Y kullanılmaz. Şu anda aygıt yazılımı (firmware) tarafından üretilmemektedir.csi.RST_TRIGGER_RISING— piksel sıfırlama tetikleyicisi, yükselen kenar. X/Y kullanılmaz. Şu anda aygıt yazılımı (firmware) tarafından üretilmemektedir.
GENX320’nin harici tetikleyici girişi, kameranın çerçeve eşitleme hattına bağlıdır; bu hat hem işlemcide hem de pin başlığında P10‘a da yönlendirilmiştir — eşitleme kenarlarını olay akışına enjekte etmek için P10’u sürün ve bunları piksel verisiyle birlikte EXT_TRIGGER_RISING / EXT_TRIGGER_FALLING olayları olarak alın.
Çoğu uygulama yalnızca PIX_OFF_EVENT ve PIX_ON_EVENT ile ilgilenir; tetikleyici türleri, olayları harici zamanlama sinyalleriyle ilişkilendirmenize olanak tanır.
Olay arabelleğini (EVT_res, 6) şekliyle ayırın; burada EVT_res, 1024 ile 65536 arasında ikinin bir kuvvetidir, ardından csi.IOCTL_GENX320_SET_MODE aracılığıyla csi.GENX320_MODE_EVENT ve arabellek boyutuyla olay moduna girin. Olayları, arabelleği kapasitesine kadar dolduran ve geçerli satır sayısını döndüren csi.IOCTL_GENX320_READ_EVENTS ile okuyun.
Image.draw_event_histogram, olayları bir gri tonlamalı görüntüye rasterleştirir — her AÇIK olay için kutucuğa contrast ekler; her KAPALI olay için çıkarır. clear=True görüntüyü önce brightness değerine sıfırlar; clear=False birçok çağrı boyunca biriktirir:
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())
Histogram modu bias hazır ayarları, AFK filtresi ve sıcak piksel kalibrasyonu ioctl’leri, olay modunda da aynı şekilde çalışır — bunları csi.IOCTL_GENX320_SET_MODE işleminden sonra çağırın.
Polariteye göre filtreleme¶
Yalnızca AÇIK olayları (daha parlak bir duruma doğru hareket) veya yalnızca KAPALI olayları tutmak için olay dizisini ulab ile dilimleyin:
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)
Uzun pozlama birikimi¶
Olayları birçok çerçeve boyunca aynı görüntüye yığmaya devam etmek için clear=False ayarlayın — sonuç bir hareket izi görselleştirmesidir. Yeni bir pozlama başlatmak için periyodik olarak sıfırlayın:
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
Yüksek hızlı işleme¶
Olay işleme için CPU’yu serbest bırakmak amacıyla görselleştirmeyi bırakın. İstatistikleri yalnızca her N’inci yinelemede yazdırın — her yinelemede bir yazdırma satırı göndermek, yüksek olay hızlarında darboğaz haline gelir:
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")
Uzamsal-zamansal kontrast (STC) filtresi¶
Gerçek bir hareket eden kontrast kenarı, kısa bir zaman penceresi içinde aynı piksel üzerinde gürültülü bir olay patlaması tetikleme eğilimindedir — piksel uyumsuzluğu ve analog gürültü, gerçek geçişin etrafında uygulamaya yararı olmayan ek olaylar üretir. STC filtresi, bir patlama başına yalnızca bir (veya birkaç) olayı tutan ve geri kalanını atan çip üzerindeki bir son işlemdir.
csi.IOCTL_GENX320_SET_STC ve bir GENX320_STC_* sabiti aracılığıyla seçilen üç strateji uygular. Her mod, bir patlamadan hangi olayları ilettiğiyle tanımlanır:
Mod |
Tutar |
Atar |
|---|---|---|
her olay |
hiçbir şey |
|
bir patlamanın ikinci olayı |
ilk + sonraki olaylar |
|
bir patlamanın ilk olayı |
sonraki olaylar |
|
ilk + sonraki kenarlar |
yalnızca gereksiz gürültü |
Ayrıntılı olarak:
csi.GENX320_STC_DISABLE— filtre kapalı, her olay geçer (varsayılan).csi.GENX320_STC_ONLY— bir patlamanın ikinci olayını tutar. Parametre:stc_threshold(ms). Bir piksel üzerinde yeni bir olay, önceki bir olaydan sonrastc_thresholdiçinde gelirse, bir patlamanın “ikincisi” olarak kabul edilir ve iletilir — ilk olay ve aynı patlamadaki sonraki tüm olaylar filtrelenir. İlk vuruş yerine gürültüyle onaylanmış bir geçiş istediğinizde en iyisidir.csi.GENX320_STC_TRAIL_ONLY— bir patlamanın ilk olayını tutar. Parametre:trail_threshold(ms). Bir piksel tetiklendikten sonra,trail_thresholdgeçene kadar aynı piksel üzerindeki sonraki olaylar atılır. Öncü kenarın hassas zamanlamasını korur — polarite değişim anının patlama onayından daha önemli olduğu durumlarda kullanışlıdır.csi.GENX320_STC_TRAIL— her ikisini birleştirir. Parametreler:stc_thresholdvetrail_threshold(ikisi de ms). Trail moduna göre öncü kenarı ve STC moduna göre sonraki kenarları tutar, böylece bir patlamadan birden fazla olay yine de geçer — tek modlu filtrelerden daha yüksek olay iş hacmi ancak en zengin sinyal.
İki eşik, kabaca 13:1 oranı içinde kalmalıdır — sensör, birinin diğerinin yaklaşık 13 katından fazla olduğu yapılandırmaları reddeder:
csi0.ioctl(csi.IOCTL_GENX320_SET_STC, csi.GENX320_STC_TRAIL, 1, 2)
csi0.ioctl(csi.IOCTL_GENX320_SET_STC, csi.GENX320_STC_DISABLE)
Arabellek derinliği¶
Olay hızları yükseldiğinde, varsayılan üçlü arabellek hattı en son çerçeveyi tercih eder ve eskileri atar. Bunun yerine olayları kuyruğa almak için csi.CSI.framebuffers aracılığıyla FIFO derinliğini artırın — ana bilgisayar geri kaldığında biraz daha eski verileri işleme pahasına:
csi0.framebuffers(10) # FIFO depth, > 3 enables queueing
Masaüstü akışı ve görselleştirme¶
Bir ana bilgisayar PC’de gerçek zamanlı GUI görselleştirmesi için, openmv-projects deposundaki GenX320 Olay Akışı aracı kamerayı bir DearPyGui ön ucuyla eşleştirir. PC GUI’si yan yana iki görselleştirme çalıştırır: bir olay birikim tuvali (Image.draw_event_histogram ile aynı fikir ancak seçilebilir paletler ve kayan pencere ile otomatik temizleme modlarıyla) ve bir IIR bant geçiren filtre ile yönlendirilen piksel başına bir frekans haritası — olay akışında periyodik sinyalleri (dönen fanlar, yanıp sönen LED’ler vb.) doğrudan tespit etmek için kullanışlıdır.
İki kamera üzerinde akış betiğiyle gelir:
İşlenmiş mod (
genx320_event_mode_streaming_on_cam.py) — kamera olaylarıcsi.IOCTL_GENX320_READ_EVENTSile çözer ve her satırı USB üzerinden 12 bayt olarak akıtır ([0]tür,[1]sn,[2]ms,[3]us,[4]x,[5]y). Tel formatı kamera üzerindeki ndarray formatıyla eşleştiği için PC’de tüketilmesi kolaydır.Ham mod (
genx320_raw_event_mode_streaming_on_cam.py) — kamera, çipin yerel 32 bit paketlenmiş olay sözcüklerinicsi.IOCTL_GENX320_READ_EVENTS_RAWaracılığıyla akıtır. Bu, işlenmiş moddaki 12 bayta karşılık olay başına 4 bayttır (USB üzerinden yaklaşık 3 kat daha az veri), bu nedenle bağlantı darboğaz olduğunda yaklaşık 3 kat daha yüksek ulaşılabilir olay hızı sağlar. PC, paketlenmiş sözcükleri vektörize numpy kullanarak aynı 6 sütunlu olay düzenine geri çözer, böylece sonraki görselleştirici kodu aynıdır.
Ham mod, GenX320’nin üretebildiği hızlarda bağlayıcı kısıtlama USB iş hacmi olduğundan GUI’de varsayılandır; işleme mantığını kamera üzerindeki betiğe bağlamanız gerekiyorsa işlenmiş moda geçin.