Merge pull request #321 from kwagyeman/master

Argument Parsing Done Correctly
This commit is contained in:
Ibrahim Abd Elkader 2018-03-05 16:04:44 +02:00 committed by GitHub
commit 411f63ebca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1707 additions and 1640 deletions

View File

@ -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))

View File

@ -8,6 +8,7 @@
*/
#ifndef __PY_ASSERT_H__
#define __PY_ASSERT_H__
#include "mp.h"
#define PY_ASSERT_TRUE(cond) \
do { \
if ((cond) == 0) { \

View File

@ -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]);
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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!"));
}

View File

@ -39,6 +39,7 @@ Q(height)
Q(format)
Q(size)
Q(get_pixel)
Q(rgbtuple)
Q(set_pixel)
Q(draw_line)
Q(draw_rectangle)