mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #321 from kwagyeman/master
Argument Parsing Done Correctly
This commit is contained in:
commit
411f63ebca
@ -67,6 +67,9 @@
|
||||
#define UINT64_T_MASK (UINT64_T_BITS - 1)
|
||||
#define UINT64_T_SHIFT IM_LOG2(UINT64_T_MASK)
|
||||
|
||||
#define IM_DEG2RAD(x) (((x)*M_PI)/180)
|
||||
#define IM_RAD2DEG(x) (((x)*180)/M_PI)
|
||||
|
||||
/////////////////
|
||||
// Point Stuff //
|
||||
/////////////////
|
||||
@ -359,6 +362,23 @@ void image_copy(image_t *dst, image_t *src);
|
||||
size_t image_size(image_t *ptr);
|
||||
bool image_get_mask_pixel(image_t *ptr, int x, int y);
|
||||
|
||||
#define IMAGE_IS_MUTABLE(image) \
|
||||
({ \
|
||||
__typeof__ (image) _image = (image); \
|
||||
(_image->bpp == IMAGE_BPP_BINARY) || \
|
||||
(_image->bpp == IMAGE_BPP_GRAYSCALE) || \
|
||||
(_image->bpp == IMAGE_BPP_RGB565); \
|
||||
})
|
||||
|
||||
#define IMAGE_IS_MUTABLE_BAYER(image) \
|
||||
({ \
|
||||
__typeof__ (image) _image = (image); \
|
||||
(_image->bpp == IMAGE_BPP_BINARY) || \
|
||||
(_image->bpp == IMAGE_BPP_GRAYSCALE) || \
|
||||
(_image->bpp == IMAGE_BPP_RGB565) || \
|
||||
(_image->bpp == IMAGE_BPP_BAYER); \
|
||||
})
|
||||
|
||||
#define IMAGE_BINARY_LINE_LEN(image) (((image)->w + UINT32_T_MASK) >> UINT32_T_SHIFT)
|
||||
#define IMAGE_BINARY_LINE_LEN_BYTES(image) (IMAGE_BINARY_LINE_LEN(image) * sizeof(uint32_t))
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
*/
|
||||
#ifndef __PY_ASSERT_H__
|
||||
#define __PY_ASSERT_H__
|
||||
#include "mp.h"
|
||||
#define PY_ASSERT_TRUE(cond) \
|
||||
do { \
|
||||
if ((cond) == 0) { \
|
||||
|
||||
@ -223,7 +223,7 @@ calling:
|
||||
mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
{
|
||||
py_fir_deinit();
|
||||
switch (py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_type), FIR_SHIELD)) {
|
||||
switch (py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_type), FIR_SHIELD)) {
|
||||
case FIR_NONE:
|
||||
return mp_const_none;
|
||||
case FIR_SHIELD:
|
||||
@ -234,8 +234,8 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
soft_i2c_init();
|
||||
|
||||
// pasre refresh rate and ADC resolution
|
||||
uint32_t IR_refresh_rate = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_refresh), 64); // 64Hz
|
||||
uint32_t ADC_resolution = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_resolution), 18); // 18-bits
|
||||
uint32_t IR_refresh_rate = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_refresh), 64); // 64Hz
|
||||
uint32_t ADC_resolution = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_resolution), 18); // 18-bits
|
||||
|
||||
// sanitize values
|
||||
ADC_resolution = ((ADC_resolution > 18)? 18:(ADC_resolution < 15)? 15:ADC_resolution) - 15;
|
||||
@ -394,14 +394,14 @@ mp_obj_t py_fir_draw_ta(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
float Ta = mp_obj_get_float(args[1]);
|
||||
float min = -17.7778, max = 37.7778; // 0F to 100F
|
||||
|
||||
int alpha = IM_MIN(IM_MAX(py_helper_lookup_int(kw_args,
|
||||
int alpha = IM_MIN(IM_MAX(py_helper_keyword_int(n_args, args, 2, kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_alpha), 128), 0), 256);
|
||||
|
||||
mp_map_elem_t *kw_scale = mp_map_lookup(kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_scale), MP_MAP_LOOKUP);
|
||||
if (kw_scale != NULL) {
|
||||
mp_obj_t scale_obj = py_helper_keyword_object(n_args, args, 3, kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_scale));
|
||||
if (scale_obj) {
|
||||
mp_obj_t *arg_scale;
|
||||
mp_obj_get_array_fixed_n(kw_scale->value, 2, &arg_scale);
|
||||
mp_obj_get_array_fixed_n(scale_obj, 2, &arg_scale);
|
||||
min = mp_obj_get_float(arg_scale[0]);
|
||||
max = mp_obj_get_float(arg_scale[1]);
|
||||
}
|
||||
@ -449,14 +449,14 @@ mp_obj_t py_fir_draw_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
max = IM_MAX(max, temp);
|
||||
}
|
||||
|
||||
int alpha = IM_MIN(IM_MAX(py_helper_lookup_int(kw_args,
|
||||
int alpha = IM_MIN(IM_MAX(py_helper_keyword_int(n_args, args, 2, kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_alpha), 128), 0), 256);
|
||||
|
||||
mp_map_elem_t *kw_scale = mp_map_lookup(kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_scale), MP_MAP_LOOKUP);
|
||||
if (kw_scale != NULL) {
|
||||
mp_obj_t scale_obj = py_helper_keyword_object(n_args, args, 3, kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_scale));
|
||||
if (scale_obj) {
|
||||
mp_obj_t *arg_scale;
|
||||
mp_obj_get_array_fixed_n(kw_scale->value, 2, &arg_scale);
|
||||
mp_obj_get_array_fixed_n(scale_obj, 2, &arg_scale);
|
||||
min = mp_obj_get_float(arg_scale[0]);
|
||||
max = mp_obj_get_float(arg_scale[1]);
|
||||
}
|
||||
|
||||
@ -28,10 +28,10 @@ typedef struct py_gif_obj {
|
||||
static mp_obj_t py_gif_open(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
{
|
||||
py_gif_obj_t *gif = m_new_obj(py_gif_obj_t);
|
||||
gif->width = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_width), MAIN_FB()->w);
|
||||
gif->height = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_height), MAIN_FB()->h);
|
||||
gif->color = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color), MAIN_FB()->bpp>=2);
|
||||
gif->loop = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_loop), true);
|
||||
gif->width = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_width), MAIN_FB()->w);
|
||||
gif->height = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_height), MAIN_FB()->h);
|
||||
gif->color = py_helper_keyword_int(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color), MAIN_FB()->bpp>=2);
|
||||
gif->loop = py_helper_keyword_int(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_loop), true);
|
||||
gif->base.type = &py_gif_type;
|
||||
|
||||
file_write_open(&gif->fp, mp_obj_str_get_str(args[0]));
|
||||
@ -78,7 +78,7 @@ static mp_obj_t py_gif_add_frame(uint n_args, const mp_obj_t *args, mp_map_t *kw
|
||||
PY_ASSERT_FALSE_MSG((arg_gif->width != arg_img->w) ||
|
||||
(arg_gif->height != arg_img->h), "Unexpected image geometry!");
|
||||
|
||||
int delay = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_delay), 10);
|
||||
int delay = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_delay), 10);
|
||||
|
||||
gif_add_frame(&arg_gif->fp, arg_img, delay);
|
||||
return mp_const_none;
|
||||
|
||||
@ -1,136 +1,229 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2018 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* MicroPython helper functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "py_helper.h"
|
||||
|
||||
int py_helper_lookup_int(mp_map_t *kw_args, mp_obj_t kw, int default_val)
|
||||
extern void *py_image_cobj(mp_obj_t img_obj);
|
||||
|
||||
image_t *py_helper_arg_to_image_mutable(const mp_obj_t arg)
|
||||
{
|
||||
image_t *arg_img = py_image_cobj(arg);
|
||||
PY_ASSERT_TRUE_MSG(IMAGE_IS_MUTABLE(arg_img), "Image format is not supported!");
|
||||
return arg_img;
|
||||
}
|
||||
|
||||
image_t *py_helper_arg_to_image_mutable_bayer(const mp_obj_t arg)
|
||||
{
|
||||
image_t *arg_img = py_image_cobj(arg);
|
||||
PY_ASSERT_TRUE_MSG(IMAGE_IS_MUTABLE_BAYER(arg_img), "Image format is not supported!");
|
||||
return arg_img;
|
||||
}
|
||||
|
||||
image_t *py_helper_arg_to_image_grayscale(const mp_obj_t arg)
|
||||
{
|
||||
image_t *arg_img = py_image_cobj(arg);
|
||||
PY_ASSERT_TRUE_MSG(arg_img->bpp == IMAGE_BPP_GRAYSCALE, "Image format is not supported!");
|
||||
return arg_img;
|
||||
}
|
||||
|
||||
image_t *py_helper_arg_to_image_color(const mp_obj_t arg)
|
||||
{
|
||||
image_t *arg_img = py_image_cobj(arg);
|
||||
PY_ASSERT_TRUE_MSG(arg_img->bpp == IMAGE_BPP_RGB565, "Image format is not supported!");
|
||||
return arg_img;
|
||||
}
|
||||
|
||||
image_t *py_helper_keyword_to_image_mutable(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, image_t *default_val)
|
||||
{
|
||||
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_arg != NULL) {
|
||||
default_val = mp_obj_get_int(kw_arg->value);
|
||||
if (kw_arg) {
|
||||
default_val = py_helper_arg_to_image_mutable(kw_arg->value);
|
||||
} else if (n_args > arg_index) {
|
||||
default_val = py_helper_arg_to_image_mutable(args[arg_index]);
|
||||
}
|
||||
|
||||
return default_val;
|
||||
}
|
||||
|
||||
float py_helper_lookup_float(mp_map_t *kw_args, mp_obj_t kw, float default_val)
|
||||
image_t *py_helper_keyword_to_image_mutable_mask(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args)
|
||||
{
|
||||
return py_helper_keyword_to_image_mutable(n_args, args, arg_index, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
}
|
||||
|
||||
void py_helper_keyword_rectangle(image_t *img, uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, rectangle_t *r)
|
||||
{
|
||||
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_arg != NULL) {
|
||||
default_val = mp_obj_get_float(kw_arg->value);
|
||||
}
|
||||
return default_val;
|
||||
}
|
||||
|
||||
void py_helper_lookup_int_array(mp_map_t *kw_args, mp_obj_t kw, int *x, int size)
|
||||
{
|
||||
mp_map_elem_t *kw_array = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_array != NULL) {
|
||||
mp_obj_t *arg_array;
|
||||
mp_obj_get_array_fixed_n(kw_array->value, size, &arg_array);
|
||||
for (int i=0; i<size; i++) {
|
||||
x[i] = mp_obj_get_int(arg_array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void py_helper_lookup_float_array(mp_map_t *kw_args, mp_obj_t kw, float *x, int size)
|
||||
{
|
||||
mp_map_elem_t *kw_array = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_array != NULL) {
|
||||
mp_obj_t *arg_array;
|
||||
mp_obj_get_array_fixed_n(kw_array->value, size, &arg_array);
|
||||
for (int i=0; i<size; i++) {
|
||||
x[i] = mp_obj_get_float(arg_array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int py_helper_lookup_color(mp_map_t *kw_args, int default_color)
|
||||
{
|
||||
mp_map_elem_t *kw_color = mp_map_lookup(kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_color), MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_color != NULL) {
|
||||
if (mp_obj_is_integer(kw_color->value)) {
|
||||
default_color = mp_obj_get_int(kw_color->value);
|
||||
} else {
|
||||
mp_obj_t *arg_color;
|
||||
mp_obj_get_array_fixed_n(kw_color->value, 3, &arg_color);
|
||||
default_color = IM_RGB565(IM_R825(mp_obj_get_int(arg_color[0])),
|
||||
IM_G826(mp_obj_get_int(arg_color[1])),
|
||||
IM_B825(mp_obj_get_int(arg_color[2])));
|
||||
}
|
||||
}
|
||||
return default_color;
|
||||
}
|
||||
|
||||
void py_helper_lookup_offset(mp_map_t *kw_args, image_t *img, point_t *p)
|
||||
{
|
||||
mp_map_elem_t *kw_offset = mp_map_lookup(kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_offset), MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_offset == NULL) {
|
||||
p->x = 0;
|
||||
p->y = 0;
|
||||
} else {
|
||||
mp_obj_t *arg_offset;
|
||||
mp_obj_get_array_fixed_n(kw_offset->value, 2, &arg_offset);
|
||||
p->x = mp_obj_get_int(arg_offset[0]);
|
||||
p->y = mp_obj_get_int(arg_offset[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void py_helper_lookup_rectangle(mp_map_t *kw_args, image_t *img, rectangle_t *r)
|
||||
{
|
||||
py_helper_lookup_rectangle_2(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_roi), img, r);
|
||||
}
|
||||
|
||||
void py_helper_lookup_rectangle_2(mp_map_t *kw_args, mp_obj_t kw, image_t *img, rectangle_t *r)
|
||||
{
|
||||
mp_map_elem_t *kw_rectangle = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_rectangle == NULL) {
|
||||
r->x = 0;
|
||||
r->y = 0;
|
||||
r->w = img->w;
|
||||
r->h = img->h;
|
||||
} else {
|
||||
if (kw_arg) {
|
||||
mp_obj_t *arg_rectangle;
|
||||
mp_obj_get_array_fixed_n(kw_rectangle->value, 4, &arg_rectangle);
|
||||
mp_obj_get_array_fixed_n(kw_arg->value, 4, &arg_rectangle);
|
||||
r->x = mp_obj_get_int(arg_rectangle[0]);
|
||||
r->y = mp_obj_get_int(arg_rectangle[1]);
|
||||
r->w = mp_obj_get_int(arg_rectangle[2]);
|
||||
r->h = mp_obj_get_int(arg_rectangle[3]);
|
||||
|
||||
if ((r->w <= 0) || (r->h <= 0)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_AssertionError, "Invalid ROI dimensions!"));
|
||||
}
|
||||
|
||||
rectangle_t tmp;
|
||||
tmp.x = 0;
|
||||
tmp.y = 0;
|
||||
tmp.w = img->w;
|
||||
tmp.h = img->h;
|
||||
|
||||
if (!rectangle_overlap(r, &tmp)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_AssertionError, "ROI does not overlap the image!"));
|
||||
}
|
||||
|
||||
rectangle_intersected(r, &tmp);
|
||||
} else if (n_args > arg_index) {
|
||||
mp_obj_t *arg_rectangle;
|
||||
mp_obj_get_array_fixed_n(args[arg_index], 4, &arg_rectangle);
|
||||
r->x = mp_obj_get_int(arg_rectangle[0]);
|
||||
r->y = mp_obj_get_int(arg_rectangle[1]);
|
||||
r->w = mp_obj_get_int(arg_rectangle[2]);
|
||||
r->h = mp_obj_get_int(arg_rectangle[3]);
|
||||
} else {
|
||||
r->x = 0;
|
||||
r->y = 0;
|
||||
r->w = img->w;
|
||||
r->h = img->h;
|
||||
}
|
||||
|
||||
if ((r->w <= 0) || (r->h <= 0)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_AssertionError, "Invalid ROI dimensions!"));
|
||||
PY_ASSERT_TRUE_MSG((r->w >= 1) && (r->h >= 1), "Invalid ROI dimensions!");
|
||||
rectangle_t temp;
|
||||
temp.x = 0;
|
||||
temp.y = 0;
|
||||
temp.w = img->w;
|
||||
temp.h = img->h;
|
||||
|
||||
PY_ASSERT_TRUE_MSG(rectangle_overlap(r, &temp), "ROI does not overlap on the image!");
|
||||
rectangle_intersected(r, &temp);
|
||||
}
|
||||
|
||||
void py_helper_keyword_rectangle_roi(image_t *img, uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, rectangle_t *r)
|
||||
{
|
||||
py_helper_keyword_rectangle(img, n_args, args, arg_index, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_roi), r);
|
||||
}
|
||||
|
||||
int py_helper_keyword_int(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, int default_val)
|
||||
{
|
||||
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_arg) {
|
||||
default_val = mp_obj_get_int(kw_arg->value);
|
||||
} else if (n_args > arg_index) {
|
||||
default_val = mp_obj_get_int(args[arg_index]);
|
||||
}
|
||||
|
||||
return default_val;
|
||||
}
|
||||
|
||||
float py_helper_keyword_float(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, float default_val)
|
||||
{
|
||||
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_arg) {
|
||||
default_val = mp_obj_get_float(kw_arg->value);
|
||||
} else if (n_args > arg_index) {
|
||||
default_val = mp_obj_get_float(args[arg_index]);
|
||||
}
|
||||
|
||||
return default_val;
|
||||
}
|
||||
|
||||
void py_helper_keyword_int_array(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, int *x, int size)
|
||||
{
|
||||
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_arg) {
|
||||
mp_obj_t *arg_array;
|
||||
mp_obj_get_array_fixed_n(kw_arg->value, size, &arg_array);
|
||||
for (int i = 0; i < size; i++) x[i] = mp_obj_get_int(arg_array[i]);
|
||||
} else if (n_args > arg_index) {
|
||||
mp_obj_t *arg_array;
|
||||
mp_obj_get_array_fixed_n(args[arg_index], size, &arg_array);
|
||||
for (int i = 0; i < size; i++) x[i] = mp_obj_get_int(arg_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void py_helper_keyword_float_array(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, float *x, int size)
|
||||
{
|
||||
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_arg) {
|
||||
mp_obj_t *arg_array;
|
||||
mp_obj_get_array_fixed_n(kw_arg->value, size, &arg_array);
|
||||
for (int i = 0; i < size; i++) x[i] = mp_obj_get_float(arg_array[i]);
|
||||
} else if (n_args > arg_index) {
|
||||
mp_obj_t *arg_array;
|
||||
mp_obj_get_array_fixed_n(args[arg_index], size, &arg_array);
|
||||
for (int i = 0; i < size; i++) x[i] = mp_obj_get_float(arg_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint py_helper_consume_array(uint n_args, const mp_obj_t *args, uint arg_index, size_t len, const mp_obj_t **items)
|
||||
{
|
||||
if (MP_OBJ_IS_TYPE(args[arg_index], &mp_type_tuple) || MP_OBJ_IS_TYPE(args[arg_index], &mp_type_list)) {
|
||||
mp_obj_get_array_fixed_n(args[arg_index], len, (mp_obj_t **) items);
|
||||
return arg_index + 1;
|
||||
} else {
|
||||
PY_ASSERT_TRUE_MSG((n_args - arg_index) >= len, "Not enough positional arguments!");
|
||||
*items = args + arg_index;
|
||||
return arg_index + len;
|
||||
}
|
||||
}
|
||||
|
||||
int py_helper_keyword_color(image_t *img, uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, int default_val)
|
||||
{
|
||||
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color), MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_arg) {
|
||||
if (mp_obj_is_integer(kw_arg->value)) {
|
||||
default_val = mp_obj_get_int(kw_arg->value);
|
||||
} else {
|
||||
mp_obj_t *arg_color;
|
||||
mp_obj_get_array_fixed_n(kw_arg->value, 3, &arg_color);
|
||||
default_val = COLOR_R5_G6_B5_TO_RGB565(COLOR_R8_TO_R5(mp_obj_get_int(arg_color[0])),
|
||||
COLOR_G8_TO_G6(mp_obj_get_int(arg_color[1])),
|
||||
COLOR_B8_TO_B5(mp_obj_get_int(arg_color[2])));
|
||||
switch(img->bpp) {
|
||||
case IMAGE_BPP_BINARY: {
|
||||
default_val = COLOR_RGB565_TO_BINARY(default_val);
|
||||
break;
|
||||
}
|
||||
case IMAGE_BPP_GRAYSCALE: {
|
||||
default_val = COLOR_RGB565_TO_GRAYSCALE(default_val);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (n_args > arg_index) {
|
||||
if (mp_obj_is_integer(args[arg_index])) {
|
||||
default_val = mp_obj_get_int(args[arg_index]);
|
||||
} else {
|
||||
mp_obj_t *arg_color;
|
||||
mp_obj_get_array_fixed_n(args[arg_index], 3, &arg_color);
|
||||
default_val = COLOR_R5_G6_B5_TO_RGB565(COLOR_R8_TO_R5(mp_obj_get_int(arg_color[0])),
|
||||
COLOR_G8_TO_G6(mp_obj_get_int(arg_color[1])),
|
||||
COLOR_B8_TO_B5(mp_obj_get_int(arg_color[2])));
|
||||
switch(img->bpp) {
|
||||
case IMAGE_BPP_BINARY: {
|
||||
default_val = COLOR_RGB565_TO_BINARY(default_val);
|
||||
break;
|
||||
}
|
||||
case IMAGE_BPP_GRAYSCALE: {
|
||||
default_val = COLOR_RGB565_TO_GRAYSCALE(default_val);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return default_val;
|
||||
}
|
||||
|
||||
void py_helper_arg_to_thresholds(const mp_obj_t arg, list_t *thresholds)
|
||||
@ -139,7 +232,6 @@ void py_helper_arg_to_thresholds(const mp_obj_t arg, list_t *thresholds)
|
||||
mp_obj_t *arg_thresholds;
|
||||
mp_obj_get_array(arg, &arg_thresholds_len, &arg_thresholds);
|
||||
if (!arg_thresholds_len) return;
|
||||
|
||||
for(mp_uint_t i = 0; i < arg_thresholds_len; i++) {
|
||||
mp_uint_t arg_threshold_len;
|
||||
mp_obj_t *arg_threshold;
|
||||
@ -147,9 +239,11 @@ void py_helper_arg_to_thresholds(const mp_obj_t arg, list_t *thresholds)
|
||||
if (arg_threshold_len) {
|
||||
color_thresholds_list_lnk_data_t lnk_data;
|
||||
lnk_data.LMin = (arg_threshold_len > 0) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[0]),
|
||||
IM_MAX(COLOR_L_MAX, COLOR_GRAYSCALE_MAX)), IM_MIN(COLOR_L_MIN, COLOR_GRAYSCALE_MIN)) : IM_MIN(COLOR_L_MIN, COLOR_GRAYSCALE_MIN);
|
||||
IM_MAX(COLOR_L_MAX, COLOR_GRAYSCALE_MAX)), IM_MIN(COLOR_L_MIN, COLOR_GRAYSCALE_MIN)) :
|
||||
IM_MIN(COLOR_L_MIN, COLOR_GRAYSCALE_MIN);
|
||||
lnk_data.LMax = (arg_threshold_len > 1) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[1]),
|
||||
IM_MAX(COLOR_L_MAX, COLOR_GRAYSCALE_MAX)), IM_MIN(COLOR_L_MIN, COLOR_GRAYSCALE_MIN)) : IM_MAX(COLOR_L_MAX, COLOR_GRAYSCALE_MAX);
|
||||
IM_MAX(COLOR_L_MAX, COLOR_GRAYSCALE_MAX)), IM_MIN(COLOR_L_MIN, COLOR_GRAYSCALE_MIN)) :
|
||||
IM_MAX(COLOR_L_MAX, COLOR_GRAYSCALE_MAX);
|
||||
lnk_data.AMin = (arg_threshold_len > 2) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[2]), COLOR_A_MAX), COLOR_A_MIN) : COLOR_A_MIN;
|
||||
lnk_data.AMax = (arg_threshold_len > 3) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[3]), COLOR_A_MAX), COLOR_A_MIN) : COLOR_A_MAX;
|
||||
lnk_data.BMin = (arg_threshold_len > 4) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[4]), COLOR_B_MAX), COLOR_B_MIN) : COLOR_B_MIN;
|
||||
@ -167,11 +261,39 @@ void py_helper_arg_to_thresholds(const mp_obj_t arg, list_t *thresholds)
|
||||
}
|
||||
}
|
||||
|
||||
void py_helper_keyword_thresholds(mp_map_t *kw_args, mp_obj_t kw, list_t *thresholds)
|
||||
void py_helper_keyword_thresholds(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, list_t *thresholds)
|
||||
{
|
||||
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_thresholds), MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_arg) {
|
||||
py_helper_arg_to_thresholds(kw_arg->value, thresholds);
|
||||
} else if (n_args > arg_index) {
|
||||
py_helper_arg_to_thresholds(args[arg_index], thresholds);
|
||||
}
|
||||
}
|
||||
|
||||
int py_helper_arg_to_ksize(const mp_obj_t arg)
|
||||
{
|
||||
int ksize = mp_obj_get_int(arg);
|
||||
PY_ASSERT_TRUE_MSG(ksize >= 0, "KernelSize must be >= 0!");
|
||||
return ksize;
|
||||
}
|
||||
|
||||
int py_helper_ksize_to_n(int ksize)
|
||||
{
|
||||
return ((ksize * 2) + 1) * ((ksize * 2) + 1);
|
||||
}
|
||||
|
||||
mp_obj_t py_helper_keyword_object(uint n_args, const mp_obj_t *args, uint arg_index, mp_map_t *kw_args, mp_obj_t kw)
|
||||
{
|
||||
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_arg != NULL) {
|
||||
py_helper_arg_to_thresholds(kw_arg->value, thresholds);
|
||||
if (kw_arg) {
|
||||
return kw_arg->value;
|
||||
} else if (n_args > arg_index) {
|
||||
return args[arg_index];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,23 +1,39 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2018 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* MicroPython helper functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PY_HELPER_H__
|
||||
#define __PY_HELPER_H__
|
||||
#include <mp.h>
|
||||
#include "py_assert.h"
|
||||
#include "imlib.h"
|
||||
int py_helper_lookup_int(mp_map_t *kw_args, mp_obj_t kw, int default_val);
|
||||
float py_helper_lookup_float(mp_map_t *kw_args, mp_obj_t kw, float default_val);
|
||||
void py_helper_lookup_int_array(mp_map_t *kw_args, mp_obj_t kw, int *x, int size);
|
||||
void py_helper_lookup_float_array(mp_map_t *kw_args, mp_obj_t kw, float *x, int size);
|
||||
int py_helper_lookup_color(mp_map_t *kw_args, int default_color);
|
||||
void py_helper_lookup_offset(mp_map_t *kw_args, image_t *img, point_t *p);
|
||||
void py_helper_lookup_rectangle(mp_map_t *kw_args, image_t *img, rectangle_t *r);
|
||||
void py_helper_lookup_rectangle_2(mp_map_t *kw_args, mp_obj_t kw, image_t *img, rectangle_t *r);
|
||||
image_t *py_helper_arg_to_image_mutable(const mp_obj_t arg);
|
||||
image_t *py_helper_arg_to_image_mutable_bayer(const mp_obj_t arg);
|
||||
image_t *py_helper_arg_to_image_grayscale(const mp_obj_t arg);
|
||||
image_t *py_helper_arg_to_image_color(const mp_obj_t arg);
|
||||
image_t *py_helper_keyword_to_image_mutable(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, image_t *default_val);
|
||||
image_t *py_helper_keyword_to_image_mutable_mask(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args);
|
||||
void py_helper_keyword_rectangle(image_t *img, uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, rectangle_t *r);
|
||||
void py_helper_keyword_rectangle_roi(image_t *img, uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, rectangle_t *r);
|
||||
int py_helper_keyword_int(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, int default_val);
|
||||
float py_helper_keyword_float(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, float default_val);
|
||||
void py_helper_keyword_int_array(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, int *x, int size);
|
||||
void py_helper_keyword_float_array(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, mp_obj_t kw, float *x, int size);
|
||||
uint py_helper_consume_array(uint n_args, const mp_obj_t *args, uint arg_index, size_t len, const mp_obj_t **items);
|
||||
int py_helper_keyword_color(image_t *img, uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, int default_val);
|
||||
void py_helper_arg_to_thresholds(const mp_obj_t arg, list_t *thresholds);
|
||||
void py_helper_keyword_thresholds(mp_map_t *kw_args, mp_obj_t kw, list_t *thresholds);
|
||||
void py_helper_keyword_thresholds(uint n_args, const mp_obj_t *args, uint arg_index,
|
||||
mp_map_t *kw_args, list_t *thresholds);
|
||||
int py_helper_arg_to_ksize(const mp_obj_t arg);
|
||||
int py_helper_ksize_to_n(int ksize);
|
||||
mp_obj_t py_helper_keyword_object(uint n_args, const mp_obj_t *args, uint arg_index, mp_map_t *kw_args, mp_obj_t kw);
|
||||
#endif // __PY_HELPER__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -151,7 +151,7 @@ static mp_obj_t py_lcd_deinit()
|
||||
static mp_obj_t py_lcd_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
{
|
||||
py_lcd_deinit();
|
||||
switch (py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_type), LCD_SHIELD)) {
|
||||
switch (py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_type), LCD_SHIELD)) {
|
||||
case LCD_NONE:
|
||||
return mp_const_none;
|
||||
case LCD_SHIELD:
|
||||
@ -278,10 +278,8 @@ static mp_obj_t py_lcd_display(uint n_args, const mp_obj_t *args, mp_map_t *kw_a
|
||||
image_t *arg_img = py_image_cobj(args[0]);
|
||||
PY_ASSERT_TRUE_MSG(IM_IS_MUTABLE(arg_img), "Image format is not supported.");
|
||||
|
||||
rectangle_t arg_r;
|
||||
py_helper_lookup_rectangle(kw_args, arg_img, &arg_r);
|
||||
rectangle_t rect;
|
||||
if (!rectangle_subimg(arg_img, &arg_r, &rect)) ff_no_intersection(NULL);
|
||||
py_helper_keyword_rectangle_roi(arg_img, n_args, args, 1, kw_args, &rect);
|
||||
|
||||
// Fit X.
|
||||
int l_pad = 0, r_pad = 0;
|
||||
|
||||
@ -28,8 +28,8 @@ typedef struct py_mjpeg_obj {
|
||||
static mp_obj_t py_mjpeg_open(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
{
|
||||
py_mjpeg_obj_t *mjpeg = m_new_obj(py_mjpeg_obj_t);
|
||||
mjpeg->width = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_width), MAIN_FB()->w);
|
||||
mjpeg->height = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_height), MAIN_FB()->h);
|
||||
mjpeg->width = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_width), MAIN_FB()->w);
|
||||
mjpeg->height = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_height), MAIN_FB()->h);
|
||||
mjpeg->frames = 0; // private
|
||||
mjpeg->bytes = 0; // private
|
||||
mjpeg->base.type = &py_mjpeg_type;
|
||||
@ -65,7 +65,7 @@ static mp_obj_t py_mjpeg_add_frame(uint n_args, const mp_obj_t *args, mp_map_t *
|
||||
|| (arg_mjpeg->height != arg_img->h),
|
||||
"Unexpected image geometry");
|
||||
|
||||
int arg_q = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_quality), 50);
|
||||
int arg_q = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_quality), 50);
|
||||
arg_q = IM_MIN(IM_MAX(arg_q, 1), 100);
|
||||
mjpeg_add_frame(&arg_mjpeg->fp, &arg_mjpeg->frames, &arg_mjpeg->bytes, arg_img, arg_q);
|
||||
return mp_const_none;
|
||||
|
||||
@ -346,8 +346,8 @@ static mp_obj_t py_sensor_set_colorbar(mp_obj_t enable) {
|
||||
|
||||
static mp_obj_t py_sensor_set_auto_gain(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
int enable = mp_obj_get_int(args[0]);
|
||||
float gain_db = py_helper_lookup_float(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gain_db), NAN);
|
||||
float gain_db_ceiling = py_helper_lookup_float(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gain_db_ceiling), NAN);
|
||||
float gain_db = py_helper_keyword_float(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gain_db), NAN);
|
||||
float gain_db_ceiling = py_helper_keyword_float(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gain_db_ceiling), NAN);
|
||||
if (sensor_set_auto_gain(enable, gain_db, gain_db_ceiling) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!"));
|
||||
}
|
||||
@ -363,7 +363,7 @@ static mp_obj_t py_sensor_get_gain_db() {
|
||||
}
|
||||
|
||||
static mp_obj_t py_sensor_set_auto_exposure(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
int exposure_us = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_exposure_us), -1);
|
||||
int exposure_us = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_exposure_us), -1);
|
||||
if (sensor_set_auto_exposure(mp_obj_get_int(args[0]), exposure_us) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!"));
|
||||
}
|
||||
@ -381,7 +381,7 @@ static mp_obj_t py_sensor_get_exposure_us() {
|
||||
static mp_obj_t py_sensor_set_auto_whitebal(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
int enable = mp_obj_get_int(args[0]);
|
||||
float rgb_gain_db[3] = {NAN, NAN, NAN};
|
||||
py_helper_lookup_float_array(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_gain_db), rgb_gain_db, 3);
|
||||
py_helper_keyword_float_array(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_gain_db), rgb_gain_db, 3);
|
||||
if (sensor_set_auto_whitebal(enable, rgb_gain_db[0], rgb_gain_db[1], rgb_gain_db[2]) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!"));
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ Q(height)
|
||||
Q(format)
|
||||
Q(size)
|
||||
Q(get_pixel)
|
||||
Q(rgbtuple)
|
||||
Q(set_pixel)
|
||||
Q(draw_line)
|
||||
Q(draw_rectangle)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user