mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Replace all mp_map_lookup()s with helper functions.
This commit is contained in:
parent
4bcdb251a3
commit
0f48c12a89
@ -161,16 +161,28 @@ static mp_obj_t py_image_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t va
|
|||||||
static int get_int_kw(mp_map_t *kw_args, mp_obj_t kw, int default_val)
|
static int get_int_kw(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);
|
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||||
|
|
||||||
if (kw_arg != NULL) {
|
if (kw_arg != NULL) {
|
||||||
default_val = mp_obj_get_int(kw_arg->value);
|
default_val = mp_obj_get_int(kw_arg->value);
|
||||||
}
|
}
|
||||||
return default_val;
|
return default_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float get_float_kw(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 != NULL) {
|
||||||
|
default_val = mp_obj_get_float(kw_arg->value);
|
||||||
|
}
|
||||||
|
return default_val;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_color_kw(mp_map_t *kw_args, int default_color)
|
static int get_color_kw(mp_map_t *kw_args, int default_color)
|
||||||
{
|
{
|
||||||
mp_map_elem_t *kw_color = mp_map_lookup(kw_args,
|
mp_map_elem_t *kw_color = mp_map_lookup(kw_args,
|
||||||
MP_OBJ_NEW_QSTR(MP_QSTR_color), MP_MAP_LOOKUP);
|
MP_OBJ_NEW_QSTR(MP_QSTR_color), MP_MAP_LOOKUP);
|
||||||
|
|
||||||
if (kw_color != NULL) {
|
if (kw_color != NULL) {
|
||||||
if (mp_obj_is_integer(kw_color->value)) {
|
if (mp_obj_is_integer(kw_color->value)) {
|
||||||
default_color = mp_obj_get_int(kw_color->value);
|
default_color = mp_obj_get_int(kw_color->value);
|
||||||
@ -188,7 +200,7 @@ static int get_color_kw(mp_map_t *kw_args, int default_color)
|
|||||||
static void get_rectangle_kw(mp_map_t *kw_args, image_t *img, rectangle_t *r)
|
static void get_rectangle_kw(mp_map_t *kw_args, image_t *img, rectangle_t *r)
|
||||||
{
|
{
|
||||||
mp_map_elem_t *kw_rectangle = mp_map_lookup(kw_args,
|
mp_map_elem_t *kw_rectangle = mp_map_lookup(kw_args,
|
||||||
MP_OBJ_NEW_QSTR(MP_QSTR_r), MP_MAP_LOOKUP);
|
MP_OBJ_NEW_QSTR(MP_QSTR_roi), MP_MAP_LOOKUP);
|
||||||
|
|
||||||
if (kw_rectangle == NULL) {
|
if (kw_rectangle == NULL) {
|
||||||
r->x = 0;
|
r->x = 0;
|
||||||
@ -834,15 +846,11 @@ static mp_obj_t py_image_histeq(mp_obj_t image_obj)
|
|||||||
|
|
||||||
static mp_obj_t py_image_median(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
static mp_obj_t py_image_median(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
{
|
{
|
||||||
int ksize = 1;
|
// Read args
|
||||||
/* get image pointer */
|
|
||||||
image_t *image = py_image_cobj(args[0]);
|
image_t *image = py_image_cobj(args[0]);
|
||||||
|
int ksize = get_int_kw(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_size), 1);
|
||||||
|
|
||||||
mp_map_elem_t *kw_ksize = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("size")), MP_MAP_LOOKUP);
|
// Call median filter
|
||||||
if (kw_ksize != NULL) {
|
|
||||||
ksize = mp_obj_get_int(kw_ksize->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
imlib_median_filter(image, ksize);
|
imlib_median_filter(image, ksize);
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
@ -859,7 +867,6 @@ static mp_obj_t py_image_threshold(mp_obj_t image_obj, mp_obj_t color_list_obj,
|
|||||||
PY_ASSERT_TRUE_MSG(sensor.framesize <= OMV_MAX_BLOB_FRAME,
|
PY_ASSERT_TRUE_MSG(sensor.framesize <= OMV_MAX_BLOB_FRAME,
|
||||||
"This function is only supported on "OMV_MAX_BLOB_FRAME_STR" and smaller frames");
|
"This function is only supported on "OMV_MAX_BLOB_FRAME_STR" and smaller frames");
|
||||||
|
|
||||||
|
|
||||||
/* read arguments */
|
/* read arguments */
|
||||||
image = py_image_cobj(image_obj);
|
image = py_image_cobj(image_obj);
|
||||||
int thresh = mp_obj_get_int(threshold);
|
int thresh = mp_obj_get_int(threshold);
|
||||||
@ -995,13 +1002,11 @@ static mp_obj_t py_image_find_blobs(mp_obj_t image_obj)
|
|||||||
|
|
||||||
static mp_obj_t py_image_find_features(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
static mp_obj_t py_image_find_features(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
{
|
{
|
||||||
struct image *image = NULL;
|
rectangle_t roi;
|
||||||
struct cascade *cascade = NULL;
|
image_t *image = NULL;
|
||||||
|
cascade_t *cascade = NULL;
|
||||||
|
|
||||||
array_t *objects_array=NULL;
|
// Sanity checks
|
||||||
mp_obj_t objects_list = mp_const_none;
|
|
||||||
|
|
||||||
/* sanity checks */
|
|
||||||
PY_ASSERT_TRUE_MSG(sensor.pixformat == PIXFORMAT_GRAYSCALE,
|
PY_ASSERT_TRUE_MSG(sensor.pixformat == PIXFORMAT_GRAYSCALE,
|
||||||
"This function is only supported on GRAYSCALE images");
|
"This function is only supported on GRAYSCALE images");
|
||||||
|
|
||||||
@ -1012,60 +1017,30 @@ static mp_obj_t py_image_find_features(uint n_args, const mp_obj_t *args, mp_map
|
|||||||
image = py_image_cobj(args[0]);
|
image = py_image_cobj(args[0]);
|
||||||
cascade = py_cascade_cobj(args[1]);
|
cascade = py_cascade_cobj(args[1]);
|
||||||
|
|
||||||
// Set defaults before reading keywords arguments
|
// Read keyword arguments
|
||||||
cascade->threshold = 0.5f;
|
get_rectangle_kw(kw_args, image, &roi);
|
||||||
cascade->scale_factor = 1.5f;
|
cascade->threshold = get_float_kw(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_threshold), 0.5f);
|
||||||
|
cascade->scale_factor = get_float_kw(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_scale), 1.5f);
|
||||||
|
|
||||||
// Read keyword arguments (threshold, scale and roi)
|
// Make sure ROI is not negative
|
||||||
mp_map_elem_t *kw_thresh = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("threshold")), MP_MAP_LOOKUP);
|
PY_ASSERT_TRUE_MSG((roi.x < 0) || (roi.y < 0) || (roi.w < 0) || (roi.h < 0),
|
||||||
if (kw_thresh != NULL) {
|
"Region of interest is negative!");
|
||||||
cascade->threshold = mp_obj_get_float(kw_thresh->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_map_elem_t *kw_scalef = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("scale")), MP_MAP_LOOKUP);
|
|
||||||
if (kw_scalef != NULL) {
|
|
||||||
cascade->scale_factor = mp_obj_get_float(kw_scalef->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
rectangle_t roi = {
|
|
||||||
.x = 0,
|
|
||||||
.y = 0,
|
|
||||||
.w = image->w,
|
|
||||||
.h = image->h,
|
|
||||||
};
|
|
||||||
|
|
||||||
mp_map_elem_t *kw_roi = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("roi")), MP_MAP_LOOKUP);
|
|
||||||
if (kw_roi != NULL) {
|
|
||||||
mp_obj_t *array;
|
|
||||||
mp_obj_get_array_fixed_n(kw_roi->value, 4, &array);
|
|
||||||
|
|
||||||
// If one of those is negative roi.(x) will overflow uint16_t
|
|
||||||
// And this error will be detected when checking ROI's bounds
|
|
||||||
uint16_t x = roi.x = mp_obj_get_int(array[0]);
|
|
||||||
uint16_t y = roi.y = mp_obj_get_int(array[1]);
|
|
||||||
uint16_t w = roi.w = mp_obj_get_int(array[2]);
|
|
||||||
uint16_t h = roi.h = mp_obj_get_int(array[3]);
|
|
||||||
|
|
||||||
// Make sure ROI is bigger than feature size
|
// Make sure ROI is bigger than feature size
|
||||||
PY_ASSERT_TRUE_MSG((w > cascade->window.w &&
|
PY_ASSERT_TRUE_MSG((roi.w > cascade->window.w && roi.h > cascade->window.h),
|
||||||
h > cascade->window.h),
|
|
||||||
"Region of interest is smaller than detector window!");
|
"Region of interest is smaller than detector window!");
|
||||||
|
|
||||||
// Make sure ROI is smaller than image size
|
// Make sure ROI is smaller than image size
|
||||||
PY_ASSERT_TRUE_MSG(((x + w) < image->w &&
|
PY_ASSERT_TRUE_MSG(((roi.x+roi.w) < image->w && (roi.y+roi.h) < image->h),
|
||||||
(y + h) < image->h),
|
|
||||||
"Region of interest is bigger than frame size!");
|
"Region of interest is bigger than frame size!");
|
||||||
}
|
|
||||||
|
|
||||||
// Detect objects
|
// Detect objects
|
||||||
objects_array = imlib_detect_objects(image, cascade, &roi);
|
array_t *objects_array = imlib_detect_objects(image, cascade, &roi);
|
||||||
|
|
||||||
/* Create empty Python list */
|
// Add detected objects to a new Python list
|
||||||
objects_list = mp_obj_new_list(0, NULL);
|
mp_obj_t objects_list = mp_obj_new_list(0, NULL);
|
||||||
|
|
||||||
/* Add detected objects to the list */
|
|
||||||
for (int i=0; i<array_length(objects_array); i++) {
|
for (int i=0; i<array_length(objects_array); i++) {
|
||||||
struct rectangle *r = array_at(objects_array, i);
|
rectangle_t *r = array_at(objects_array, i);
|
||||||
mp_obj_t rec_obj[4] = {
|
mp_obj_t rec_obj[4] = {
|
||||||
mp_obj_new_int(r->x),
|
mp_obj_new_int(r->x),
|
||||||
mp_obj_new_int(r->y),
|
mp_obj_new_int(r->y),
|
||||||
@ -1075,7 +1050,7 @@ static mp_obj_t py_image_find_features(uint n_args, const mp_obj_t *args, mp_map
|
|||||||
mp_obj_list_append(objects_list, mp_obj_new_tuple(4, rec_obj));
|
mp_obj_list_append(objects_list, mp_obj_new_tuple(4, rec_obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the objects array */
|
// Free the objects array
|
||||||
array_free(objects_array);
|
array_free(objects_array);
|
||||||
|
|
||||||
return objects_list;
|
return objects_list;
|
||||||
@ -1118,53 +1093,31 @@ static mp_obj_t py_image_find_template(mp_obj_t image_obj, mp_obj_t template_obj
|
|||||||
|
|
||||||
static mp_obj_t py_image_find_keypoints(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
static mp_obj_t py_image_find_keypoints(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
{
|
{
|
||||||
int threshold = 20;
|
rectangle_t roi;
|
||||||
bool normalized = false;
|
|
||||||
|
|
||||||
int kpts_size = 0;
|
|
||||||
kp_t *kpts = NULL;
|
|
||||||
py_kp_obj_t *kp_obj =NULL;
|
|
||||||
|
|
||||||
image_t *image = py_image_cobj(args[0]);
|
image_t *image = py_image_cobj(args[0]);
|
||||||
rectangle_t roi={0, 0, image->w, image->h};
|
|
||||||
|
|
||||||
/* sanity checks */
|
// Sanity checks
|
||||||
PY_ASSERT_TRUE_MSG(sensor.pixformat == PIXFORMAT_GRAYSCALE,
|
PY_ASSERT_TRUE_MSG(sensor.pixformat == PIXFORMAT_GRAYSCALE,
|
||||||
"This function is only supported on GRAYSCALE images");
|
"This function is only supported on GRAYSCALE images");
|
||||||
|
|
||||||
PY_ASSERT_TRUE_MSG(sensor.framesize <= OMV_MAX_INT_FRAME,
|
PY_ASSERT_TRUE_MSG(sensor.framesize <= OMV_MAX_INT_FRAME,
|
||||||
"This function is only supported on "OMV_MAX_INT_FRAME_STR" and smaller frames");
|
"This function is only supported on "OMV_MAX_INT_FRAME_STR" and smaller frames");
|
||||||
|
|
||||||
/* read var args */
|
// Read keyword arguments
|
||||||
mp_map_elem_t *kw_thresh = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("threshold")), MP_MAP_LOOKUP);
|
get_rectangle_kw(kw_args, image, &roi);
|
||||||
if (kw_thresh != NULL) {
|
int threshold = get_int_kw(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_threshold), 32);
|
||||||
threshold = mp_obj_get_int(kw_thresh->value);
|
bool normalized = get_int_kw(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("normalized")), false);
|
||||||
}
|
|
||||||
|
|
||||||
mp_map_elem_t *kw_norm = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("normalized")), MP_MAP_LOOKUP);
|
// Run keypoint extractor on ROI
|
||||||
if (kw_norm != NULL) {
|
int kpts_size = 0;
|
||||||
normalized = mp_obj_get_int(kw_norm->value);
|
kp_t *kpts = fast_detect(image, threshold, &kpts_size, &roi);
|
||||||
}
|
|
||||||
|
|
||||||
mp_map_elem_t *kw_roi = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("roi")), MP_MAP_LOOKUP);
|
|
||||||
if (kw_roi != NULL) {
|
|
||||||
mp_obj_t *array;
|
|
||||||
mp_obj_get_array_fixed_n(kw_roi->value, 4, &array);
|
|
||||||
roi.x=mp_obj_get_int(array[0]);
|
|
||||||
roi.y=mp_obj_get_int(array[1]);
|
|
||||||
roi.w=mp_obj_get_int(array[2]);
|
|
||||||
roi.h=mp_obj_get_int(array[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* run keypoint extractor on ROI */
|
|
||||||
kpts = fast_detect(image, threshold, &kpts_size, &roi);
|
|
||||||
|
|
||||||
if (kpts_size) {
|
if (kpts_size) {
|
||||||
/* run keypoint descriptor */
|
// Run keypoint descriptor
|
||||||
freak_find_keypoints(image, kpts, kpts_size, normalized, normalized);
|
freak_find_keypoints(image, kpts, kpts_size, normalized, normalized);
|
||||||
|
|
||||||
/* return keypoints MP object */
|
// Return keypoints MP object
|
||||||
kp_obj = m_new_obj(py_kp_obj_t);
|
py_kp_obj_t * kp_obj = m_new_obj(py_kp_obj_t);
|
||||||
kp_obj->base.type = &py_kp_type;
|
kp_obj->base.type = &py_kp_type;
|
||||||
kp_obj->kpts = kpts;
|
kp_obj->kpts = kpts;
|
||||||
kp_obj->size = kpts_size;
|
kp_obj->size = kpts_size;
|
||||||
@ -1466,28 +1419,23 @@ mp_obj_t py_image_load_image(mp_obj_t path_obj)
|
|||||||
mp_obj_t py_image_load_cascade(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
mp_obj_t py_image_load_cascade(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
{
|
{
|
||||||
cascade_t cascade;
|
cascade_t cascade;
|
||||||
|
const char *path = mp_obj_str_get_str(args[0]);
|
||||||
py_cascade_obj_t *o = NULL;
|
|
||||||
mp_map_elem_t *kw_stages = NULL;
|
|
||||||
|
|
||||||
// Load cascade from file or flash
|
// Load cascade from file or flash
|
||||||
const char *path = mp_obj_str_get_str(args[0]);
|
|
||||||
int res = imlib_load_cascade(&cascade, path);
|
int res = imlib_load_cascade(&cascade, path);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
|
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit the number of stages if specified
|
// Read the number of stages
|
||||||
kw_stages = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("stages")), MP_MAP_LOOKUP);
|
int stages = get_int_kw(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("stages")), cascade.n_stages);
|
||||||
if (kw_stages != NULL) {
|
// Check the number of stages
|
||||||
int stages = mp_obj_get_int(kw_stages->value);
|
if (stages > 0 && stages < cascade.n_stages) {
|
||||||
if (stages > 0 && stages <= cascade.n_stages) {
|
|
||||||
cascade.n_stages = stages;
|
cascade.n_stages = stages;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Return micropython cascade object
|
// Return micropython cascade object
|
||||||
o = m_new_obj(py_cascade_obj_t);
|
py_cascade_obj_t *o = m_new_obj(py_cascade_obj_t);
|
||||||
o->base.type = &py_cascade_type;
|
o->base.type = &py_cascade_type;
|
||||||
o->_cobj = cascade;
|
o->_cobj = cascade;
|
||||||
return o;
|
return o;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user