mirror of
https://github.com/openmv/openmv.git
synced 2025-09-26 23:09:13 +08:00
drivers/sensors: Add different event buffer sizes for genx320.
This commit is contained in:
parent
3908807509
commit
c231f66555
@ -88,7 +88,7 @@ typedef struct genx_state {
|
||||
|
||||
static genx_state_t genx = {};
|
||||
|
||||
static int set_active_mode(omv_csi_t *csi, genx_mode_t mode);
|
||||
static int set_active_mode(omv_csi_t *csi, genx_mode_t mode, int framesize);
|
||||
|
||||
static int reset(omv_csi_t *csi) {
|
||||
genx_state_t *genx = csi->priv;
|
||||
@ -99,7 +99,7 @@ static int reset(omv_csi_t *csi) {
|
||||
genx->event_time_us = 0;
|
||||
|
||||
// Set histogram mode by default.
|
||||
if (set_active_mode(csi, OMV_CSI_GENX320_MODE_HISTO)) {
|
||||
if (set_active_mode(csi, OMV_CSI_GENX320_MODE_HISTO, OMV_CSI_FRAMESIZE_320X320)) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ static int set_framesize(omv_csi_t *csi, omv_csi_framesize_t framesize) {
|
||||
if (genx->mode == OMV_CSI_GENX320_MODE_HISTO) {
|
||||
return (framesize == OMV_CSI_FRAMESIZE_320X320) ? 0 : -1;
|
||||
} else {
|
||||
return (framesize == OMV_CSI_FRAMESIZE_128X64) ? 0 : -1;
|
||||
return (framesize == OMV_CSI_FRAMESIZE_CUSTOM) ? 0 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,7 +420,7 @@ static int ioctl(omv_csi_t *csi, int request, va_list ap) {
|
||||
int mode = va_arg(ap, int);
|
||||
|
||||
if (mode == OMV_CSI_GENX320_MODE_HISTO) {
|
||||
if ((ret = set_active_mode(csi, OMV_CSI_GENX320_MODE_HISTO))) {
|
||||
if ((ret = set_active_mode(csi, OMV_CSI_GENX320_MODE_HISTO, OMV_CSI_FRAMESIZE_320X320))) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -432,17 +432,25 @@ static int ioctl(omv_csi_t *csi, int request, va_list ap) {
|
||||
break;
|
||||
}
|
||||
} else if (mode == OMV_CSI_GENX320_MODE_EVENT) {
|
||||
if ((ret = set_active_mode(csi, OMV_CSI_GENX320_MODE_EVENT))) {
|
||||
size_t ndarray_size = va_arg(ap, size_t);
|
||||
|
||||
if (ndarray_size < 1024 || ndarray_size > 65536 || (ndarray_size & (ndarray_size - 1))) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
resolution[OMV_CSI_FRAMESIZE_CUSTOM][0] = 1024;
|
||||
resolution[OMV_CSI_FRAMESIZE_CUSTOM][1] = ndarray_size >> 8;
|
||||
|
||||
if ((ret = set_active_mode(csi, OMV_CSI_GENX320_MODE_EVENT, OMV_CSI_FRAMESIZE_CUSTOM))) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 1 byte per pixel.
|
||||
if ((ret = omv_csi_set_pixformat(csi, PIXFORMAT_GRAYSCALE))) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 128*64 bytes / 4 bytes per event = 2048 events.
|
||||
if ((ret = omv_csi_set_framesize(csi, OMV_CSI_FRAMESIZE_128X64))) {
|
||||
if ((ret = omv_csi_set_framesize(csi, OMV_CSI_FRAMESIZE_CUSTOM))) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -607,7 +615,7 @@ static int post_process_event(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
return valid_count;
|
||||
}
|
||||
|
||||
static int set_active_mode(omv_csi_t *csi, genx_mode_t mode) {
|
||||
static int set_active_mode(omv_csi_t *csi, genx_mode_t mode, int framesize) {
|
||||
genx_state_t *genx = csi->priv;
|
||||
|
||||
if (genx->issd) {
|
||||
@ -638,8 +646,8 @@ static int set_active_mode(omv_csi_t *csi, genx_mode_t mode) {
|
||||
}
|
||||
|
||||
// Configure Packet and Frame sizes
|
||||
uint32_t packet_width = (mode == OMV_CSI_GENX320_MODE_EVENT) ? 128 : ACTIVE_SENSOR_WIDTH;
|
||||
uint32_t packet_height = (mode == OMV_CSI_GENX320_MODE_EVENT) ? 64 : ACTIVE_SENSOR_HEIGHT;
|
||||
uint32_t packet_width = resolution[framesize][0];
|
||||
uint32_t packet_height = resolution[framesize][1];
|
||||
uint32_t packet_hsync = (mode == OMV_CSI_GENX320_MODE_EVENT) ?
|
||||
EVENT_HSYNC_CLOCK_CYCLES : HISTO_HSYNC_CLOCK_CYCLES;
|
||||
|
||||
|
@ -1196,6 +1196,8 @@ static mp_obj_t py_csi_ioctl(size_t n_args, const mp_obj_t *args) {
|
||||
case OMV_CSI_IOCTL_GENX320_SET_MODE: {
|
||||
if (n_args == 1) {
|
||||
error = omv_csi_ioctl(self->csi, request, mp_obj_get_int(args[0]));
|
||||
} else if (n_args == 2) {
|
||||
error = omv_csi_ioctl(self->csi, request, mp_obj_get_int(args[0]), mp_obj_get_int(args[1]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1207,11 +1209,15 @@ static mp_obj_t py_csi_ioctl(size_t n_args, const mp_obj_t *args) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Expected a ndarray with dtype uint16"));
|
||||
}
|
||||
|
||||
uint32_t expected_len = resolution[self->csi->framesize][0] *
|
||||
(resolution[self->csi->framesize][1] / sizeof(uint32_t));
|
||||
|
||||
if (!(ndarray_is_dense(array) && (array->ndim == 2) &&
|
||||
(array->shape[ULAB_MAX_DIMS - 2] == 2048) &&
|
||||
(array->shape[ULAB_MAX_DIMS - 2] == expected_len) &&
|
||||
(array->shape[ULAB_MAX_DIMS - 1] == EC_EVENT_SIZE))) {
|
||||
mp_raise_msg_varg(&mp_type_ValueError,
|
||||
MP_ERROR_TEXT("Expected a dense ndarray with shape (2048, %d)"), EC_EVENT_SIZE);
|
||||
MP_ERROR_TEXT("Expected a dense ndarray with shape (%d, %d)"),
|
||||
expected_len, EC_EVENT_SIZE);
|
||||
}
|
||||
|
||||
error = omv_csi_ioctl(self->csi, request, array->array);
|
||||
|
@ -16,6 +16,7 @@ img = image.Image(320, 320, image.GRAYSCALE)
|
||||
|
||||
# Stores camera events
|
||||
# Shape: (EVT_res, 6) where EVT_res is the event resolution
|
||||
# EVT_res: must be a power of two between 1024 and 65536.
|
||||
# Columns:
|
||||
# [0] Event type
|
||||
# [1] Seconds timestamp
|
||||
@ -28,7 +29,7 @@ events = np.zeros((2048, 6), dtype=np.uint16)
|
||||
# Initialize the sensor.
|
||||
csi0 = csi.CSI(cid=csi.GENX320)
|
||||
csi0.reset()
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT)
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events.shape[0])
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
|
@ -20,6 +20,7 @@ img = image.Image(320, 320, image.GRAYSCALE)
|
||||
|
||||
# Stores camera events
|
||||
# Shape: (EVT_res, 6) where EVT_res is the event resolution
|
||||
# EVT_res: must be a power of two between 1024 and 65536.
|
||||
# Columns:
|
||||
# [0] Event type
|
||||
# [1] Seconds timestamp
|
||||
@ -32,7 +33,7 @@ events = np.zeros((2048, 6), dtype=np.uint16)
|
||||
# Initialize the sensor.
|
||||
csi0 = csi.CSI(cid=csi.GENX320)
|
||||
csi0.reset()
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT)
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events.shape[0])
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
|
@ -0,0 +1,56 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2025 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# This example shows off using the genx320 event camera from Prophesee
|
||||
# using event streaming mode with a very deep event buffer for capturing events.
|
||||
|
||||
import csi
|
||||
import image
|
||||
import time
|
||||
# https://micropython-ulab.readthedocs.io/en/latest/index.html
|
||||
from ulab import numpy as np
|
||||
|
||||
# Surface to draw the histogram image on.
|
||||
img = image.Image(320, 320, image.GRAYSCALE)
|
||||
|
||||
# Stores camera events
|
||||
# Shape: (EVT_res, 6) where EVT_res is the event resolution
|
||||
# EVT_res: must be a power of two between 1024 and 65536.
|
||||
# Columns:
|
||||
# [0] Event type
|
||||
# [1] Seconds timestamp
|
||||
# [2] Milliseconds timestamp
|
||||
# [3] Microseconds timestamp
|
||||
# [4] X coordinate 0 to 319 for GENX320
|
||||
# [5] Y coordinate 0 to 319 for GENX320
|
||||
events = np.zeros((32768, 6), dtype=np.uint16)
|
||||
|
||||
# Initialize the sensor.
|
||||
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()
|
||||
|
||||
# Reads up to 32768 events from the camera.
|
||||
# Returns the number of valid events (0-32768) or a negative error code.
|
||||
# Note that old events in the buffer are not cleared to save CPU time.
|
||||
event_count = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS, events)
|
||||
|
||||
# Render events into a histogram image.
|
||||
# If clear=True, the image is reset to "brightness" before drawing.
|
||||
# For each PIX_ON_EVENT, add "contrast" to the bin value;
|
||||
# for each PIX_OFF_EVENT, subtract it and clamp to [0, 255].
|
||||
# If clear=False, histogram accumulates over multiple calls.
|
||||
img.draw_event_histogram(events[:event_count], clear=True, brightness=128, contrast=16)
|
||||
|
||||
# Push the image to the jpeg buffer for the IDE to pull and display.
|
||||
# The IDE pulls frames off the camera at a much lower rate than the
|
||||
# onboard camera frame rate printed below.
|
||||
img.flush()
|
||||
|
||||
print(event_count, clock.fps())
|
@ -0,0 +1,64 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2025 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# This example shows off using the genx320 event camera from Prophesee
|
||||
# using event streaming mode with a very deep event buffer for capturing events.
|
||||
#
|
||||
# Adds filtering of events based on the event type (PIX_ON_EVENT or PIX_OFF_EVENT).
|
||||
|
||||
import csi
|
||||
import image
|
||||
import time
|
||||
# https://micropython-ulab.readthedocs.io/en/latest/index.html
|
||||
from ulab import numpy as np
|
||||
|
||||
TARGET_EVENT_TYPE = csi.PIX_ON_EVENT # Change to PIX_OFF_EVENT to filter low events.
|
||||
|
||||
# Surface to draw the histogram image on.
|
||||
img = image.Image(320, 320, image.GRAYSCALE)
|
||||
|
||||
# Stores camera events
|
||||
# Shape: (EVT_res, 6) where EVT_res is the event resolution
|
||||
# EVT_res: must be a power of two between 1024 and 65536.
|
||||
# Columns:
|
||||
# [0] Event type
|
||||
# [1] Seconds timestamp
|
||||
# [2] Milliseconds timestamp
|
||||
# [3] Microseconds timestamp
|
||||
# [4] X coordinate 0 to 319 for GENX320
|
||||
# [5] Y coordinate 0 to 319 for GENX320
|
||||
events = np.zeros((32768, 6), dtype=np.uint16)
|
||||
|
||||
# Initialize the sensor.
|
||||
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()
|
||||
|
||||
# Reads up to 32768 events from the camera.
|
||||
# Returns the number of valid events (0-32768) or a negative error code.
|
||||
# Note that old events in the buffer are not cleared to save CPU time.
|
||||
event_count = csi0.ioctl(csi.IOCTL_GENX320_READ_EVENTS, events)
|
||||
events_slice = events[:event_count]
|
||||
indices = np.nonzero(events_slice[:, 0] == TARGET_EVENT_TYPE)[0]
|
||||
if len(indices):
|
||||
target_events = np.take(events_slice, indices, axis=0)
|
||||
|
||||
# Render events into a histogram image.
|
||||
# If clear=True, the image is reset to "brightness" before drawing.
|
||||
# For each PIX_ON_EVENT, add "contrast" to the bin value;
|
||||
# for each PIX_OFF_EVENT, subtract it and clamp to [0, 255].
|
||||
# If clear=False, histogram accumulates over multiple calls.
|
||||
img.draw_event_histogram(target_events, clear=True, brightness=128, contrast=16)
|
||||
|
||||
# Push the image to the jpeg buffer for the IDE to pull and display.
|
||||
# The IDE pulls frames off the camera at a much lower rate than the
|
||||
# onboard camera frame rate printed below.
|
||||
img.flush()
|
||||
|
||||
print(len(target_events), clock.fps())
|
@ -20,6 +20,7 @@ img = image.Image(320, 320, image.GRAYSCALE)
|
||||
|
||||
# Stores camera events
|
||||
# Shape: (EVT_res, 6) where EVT_res is the event resolution
|
||||
# EVT_res: must be a power of two between 1024 and 65536.
|
||||
# Columns:
|
||||
# [0] Event type
|
||||
# [1] Seconds timestamp
|
||||
@ -32,7 +33,7 @@ events = np.zeros((2048, 6), dtype=np.uint16)
|
||||
# Initialize the sensor.
|
||||
csi0 = csi.CSI(cid=csi.GENX320)
|
||||
csi0.reset()
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT)
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events.shape[0])
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
|
@ -14,6 +14,7 @@ from ulab import numpy as np
|
||||
|
||||
# Stores camera events
|
||||
# Shape: (EVT_res, 6) where EVT_res is the event resolution
|
||||
# EVT_res: must be a power of two between 1024 and 65536.
|
||||
# Columns:
|
||||
# [0] Event type
|
||||
# [1] Seconds timestamp
|
||||
@ -26,7 +27,7 @@ events = np.zeros((2048, 6), dtype=np.uint16)
|
||||
# Initialize the sensor.
|
||||
csi0 = csi.CSI(cid=csi.GENX320)
|
||||
csi0.reset()
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT)
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events.shape[0])
|
||||
|
||||
clock = time.clock()
|
||||
t = time.ticks_us()
|
||||
|
@ -18,6 +18,7 @@ TARGET_EVENT_TYPE = csi.PIX_ON_EVENT # Change to PIX_OFF_EVENT to filter low ev
|
||||
|
||||
# Stores camera events
|
||||
# Shape: (EVT_res, 6) where EVT_res is the event resolution
|
||||
# EVT_res: must be a power of two between 1024 and 65536.
|
||||
# Columns:
|
||||
# [0] Event type
|
||||
# [1] Seconds timestamp
|
||||
@ -30,7 +31,7 @@ events = np.zeros((2048, 6), dtype=np.uint16)
|
||||
# Initialize the sensor.
|
||||
csi0 = csi.CSI(cid=csi.GENX320)
|
||||
csi0.reset()
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT)
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events.shape[0])
|
||||
|
||||
clock = time.clock()
|
||||
t = time.ticks_us()
|
||||
|
@ -11,13 +11,14 @@ import time
|
||||
# https://micropython-ulab.readthedocs.io/en/latest/index.html
|
||||
from ulab import numpy as np
|
||||
|
||||
EXPOSURE_FRAMES = 10
|
||||
EXPOSURE_FRAMES = 30
|
||||
|
||||
# Surface to draw the histogram image on.
|
||||
img = image.Image(320, 320, image.GRAYSCALE)
|
||||
|
||||
# Stores camera events
|
||||
# Shape: (EVT_res, 6) where EVT_res is the event resolution
|
||||
# EVT_res: must be a power of two between 1024 and 65536.
|
||||
# Columns:
|
||||
# [0] Event type
|
||||
# [1] Seconds timestamp
|
||||
@ -25,12 +26,12 @@ img = image.Image(320, 320, image.GRAYSCALE)
|
||||
# [3] Microseconds timestamp
|
||||
# [4] X coordinate 0 to 319 for GENX320
|
||||
# [5] Y coordinate 0 to 319 for GENX320
|
||||
events = np.zeros((2048, 6), dtype=np.uint16)
|
||||
events = np.zeros((32768, 6), dtype=np.uint16)
|
||||
|
||||
# Initialize the sensor.
|
||||
csi0 = csi.CSI(cid=csi.GENX320)
|
||||
csi0.reset()
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT)
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events.shape[0])
|
||||
|
||||
clock = time.clock()
|
||||
i = 0
|
||||
|
@ -15,13 +15,14 @@ from ulab import numpy as np
|
||||
|
||||
TARGET_EVENT_TYPE = csi.PIX_ON_EVENT # Change to PIX_OFF_EVENT to filter low events.
|
||||
|
||||
EXPOSURE_FRAMES = 10
|
||||
EXPOSURE_FRAMES = 30
|
||||
|
||||
# Surface to draw the histogram image on.
|
||||
img = image.Image(320, 320, image.GRAYSCALE)
|
||||
|
||||
# Stores camera events
|
||||
# Shape: (EVT_res, 6) where EVT_res is the event resolution
|
||||
# EVT_res: must be a power of two between 1024 and 65536.
|
||||
# Columns:
|
||||
# [0] Event type
|
||||
# [1] Seconds timestamp
|
||||
@ -34,7 +35,7 @@ events = np.zeros((32768, 6), dtype=np.uint16)
|
||||
# Initialize the sensor.
|
||||
csi0 = csi.CSI(cid=csi.GENX320)
|
||||
csi0.reset()
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT)
|
||||
csi0.ioctl(csi.IOCTL_GENX320_SET_MODE, csi.GENX320_MODE_EVENT, events.shape[0])
|
||||
|
||||
clock = time.clock()
|
||||
i = 0
|
||||
@ -59,7 +60,7 @@ while True:
|
||||
# For each PIX_ON_EVENT, add "contrast" to the bin value;
|
||||
# for each PIX_OFF_EVENT, subtract it and clamp to [0, 255].
|
||||
# If clear=False, histogram accumulates over multiple calls.
|
||||
img.draw_event_histogram(target_events, clear=c, brightness=128, contrast=64)
|
||||
img.draw_event_histogram(target_events, clear=c, brightness=128, contrast=16)
|
||||
|
||||
# Push the image to the jpeg buffer for the IDE to pull and display.
|
||||
# The IDE pulls frames off the camera at a much lower rate than the
|
||||
|
Loading…
Reference in New Issue
Block a user