mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Argument Parsing Done Correctly
All of our argument parsing code has now been updated to handle positional as well as keyword arguments in our python libraries. Basically, python allows you to pass some number of positional arguments to functions/methods followed by keyword arguments (you cannot have more positional arguments after keyword arguments). Previously, our code would only look for keyword arguments. Now, it works better and will grab as many positional arguments as it can followed by processing keyword arguments. Note: If the case of a positional argument value for a parameter being passed followed by a keyword for that same parameter the keyword value is taken (since it comes aftward). Because arguments were passed in keyword form before this update has no affect on current code. However, moving forward, argument positions are now locked and cannot be moved around.
This commit is contained in:
parent
2feed8b291
commit
e0e112468e
@ -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