Make set_windowing much more flexible

This commit is contained in:
Kwabena W. Agyeman 2021-05-03 21:41:12 -07:00
parent b05415b373
commit 3e9c435540
3 changed files with 62 additions and 44 deletions

View File

@ -282,42 +282,52 @@ static mp_obj_t py_sensor_get_framerate()
return mp_obj_new_int(sensor.framerate); return mp_obj_new_int(sensor.framerate);
} }
static mp_obj_t py_sensor_set_windowing(mp_obj_t roi_obj) static mp_obj_t py_sensor_set_windowing(uint n_args, const mp_obj_t *args)
{ {
int x, y, w, h; if (sensor.framesize == FRAMESIZE_INVALID) {
int res_w = resolution[sensor.framesize][0]; mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Frame size not set yet!"));
int res_h = resolution[sensor.framesize][1]; }
mp_obj_t *array; rectangle_t temp;
mp_uint_t array_len; temp.x = 0;
mp_obj_get_array(roi_obj, &array_len, &array); temp.y = 0;
temp.w = resolution[sensor.framesize][0];
temp.h = resolution[sensor.framesize][1];
if (array_len == 4) { mp_obj_t *array = (mp_obj_t *) args;
x = mp_obj_get_int(array[0]); mp_uint_t array_len = n_args;
y = mp_obj_get_int(array[1]);
w = mp_obj_get_int(array[2]); if (n_args == 1) {
h = mp_obj_get_int(array[3]); mp_obj_get_array(args[0], &array_len, &array);
} else if (array_len == 2) { }
w = mp_obj_get_int(array[0]);
h = mp_obj_get_int(array[1]); rectangle_t r;
x = (res_w / 2) - (w / 2);
y = (res_h / 2) - (h / 2); if (array_len == 2) {
r.w = mp_obj_get_int(array[0]);
r.h = mp_obj_get_int(array[1]);
r.x = (temp.w / 2) - (r.w / 2);
r.y = (temp.h / 2) - (r.h / 2);
} else if (array_len == 4) {
r.x = mp_obj_get_int(array[0]);
r.y = mp_obj_get_int(array[1]);
r.w = mp_obj_get_int(array[2]);
r.h = mp_obj_get_int(array[3]);
} else { } else {
mp_raise_msg(&mp_type_ValueError, mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("The tuple/list must either be (x, y, w, h) or (w, h)"));
MP_ERROR_TEXT("The tuple/list must either be (x, y, w, h) or (w, h)"));
} }
if (w < 8 || h < 8) { if ((r.w < 1) || (r.h < 1)) {
mp_raise_msg(&mp_type_ValueError, mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid ROI dimensions!"));
MP_ERROR_TEXT("The selected window is too small"));
} }
if (x < 0 || (x + w) > res_w || y < 0 || (y + h) > res_h) { if (!rectangle_overlap(&r, &temp)) {
mp_raise_msg(&mp_type_ValueError, mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("ROI does not overlap on the image!"));
MP_ERROR_TEXT("The selected window is outside the bounds of the frame"));
} }
if (sensor_set_windowing(x, y, w, h) != 0) { rectangle_intersected(&r, &temp);
if (sensor_set_windowing(r.x, r.y, r.w, r.h) != 0) {
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Failed to set windowing!")); mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Failed to set windowing!"));
} }
@ -915,7 +925,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_framesize_obj, py_sensor_se
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_framesize_obj, py_sensor_get_framesize); STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_framesize_obj, py_sensor_get_framesize);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_framerate_obj, py_sensor_set_framerate); STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_framerate_obj, py_sensor_set_framerate);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_framerate_obj, py_sensor_get_framerate); STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_framerate_obj, py_sensor_get_framerate);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_windowing_obj, py_sensor_set_windowing); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_sensor_set_windowing_obj, 1, 4, py_sensor_set_windowing);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_windowing_obj, py_sensor_get_windowing); STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_windowing_obj, py_sensor_get_windowing);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_gainceiling_obj, py_sensor_set_gainceiling); STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_gainceiling_obj, py_sensor_set_gainceiling);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_contrast_obj, py_sensor_set_contrast); STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_contrast_obj, py_sensor_set_contrast);

View File

@ -592,18 +592,22 @@ int sensor_set_framerate(int framerate)
int sensor_set_windowing(int x, int y, int w, int h) int sensor_set_windowing(int x, int y, int w, int h)
{ {
// py_sensor_set_windowing ensures this the window is at least 8x8 if ((MAIN_FB()->x == x) && (MAIN_FB()->y == y) && (MAIN_FB()->u == w) && (MAIN_FB()->v == h)) {
// and that it is fully inside the sensor output framesize window. // No change
return 0;
}
if (sensor.pixformat == PIXFORMAT_JPEG) { if (sensor.pixformat == PIXFORMAT_JPEG) {
return -1; return -1;
} }
// We force everything to be a multiple of 2 so that when you switch between // Skip the first frame.
// grayscale/rgb565/bayer/jpeg the frame doesn't need to move around for bayer to work. MAIN_FB()->bpp = -1;
MAIN_FB()->x = (x / 2) * 2;
MAIN_FB()->y = (y / 2) * 2; MAIN_FB()->x = x;
MAIN_FB()->w = MAIN_FB()->u = (w / 2) * 2; MAIN_FB()->y = y;
MAIN_FB()->h = MAIN_FB()->v = (h / 2) * 2; MAIN_FB()->w = MAIN_FB()->u = w;
MAIN_FB()->h = MAIN_FB()->v = h;
return 0; return 0;
} }

View File

@ -723,20 +723,24 @@ int sensor_set_framerate(int framerate)
int sensor_set_windowing(int x, int y, int w, int h) int sensor_set_windowing(int x, int y, int w, int h)
{ {
// py_sensor_set_windowing ensures this the window is at least 8x8 if ((MAIN_FB()->x == x) && (MAIN_FB()->y == y) && (MAIN_FB()->u == w) && (MAIN_FB()->v == h)) {
// and that it is fully inside the sensor output framesize window. // No change
return 0;
}
if (sensor.pixformat == PIXFORMAT_JPEG) { if (sensor.pixformat == PIXFORMAT_JPEG) {
return -1; return -1;
} }
dcmi_abort(); dcmi_abort();
// We force everything to be a multiple of 2 so that when you switch between // Skip the first frame.
// grayscale/rgb565/bayer/jpeg the frame doesn't need to move around for bayer to work. MAIN_FB()->bpp = -1;
MAIN_FB()->x = (x / 2) * 2;
MAIN_FB()->y = (y / 2) * 2; MAIN_FB()->x = x;
MAIN_FB()->w = MAIN_FB()->u = (w / 2) * 2; MAIN_FB()->y = y;
MAIN_FB()->h = MAIN_FB()->v = (h / 2) * 2; MAIN_FB()->w = MAIN_FB()->u = w;
MAIN_FB()->h = MAIN_FB()->v = h;
// Pickout a good buffer count for the user. // Pickout a good buffer count for the user.
framebuffer_auto_adjust_buffers(); framebuffer_auto_adjust_buffers();