Update image API

This commit is contained in:
iabdalkader 2014-04-04 21:07:09 +02:00
parent be7d0d317e
commit 91099e9edc
2 changed files with 238 additions and 197 deletions

View File

@ -245,11 +245,13 @@ int main(void)
rng_init(); rng_init();
/* Add functions to the global python namespace */ /* Add functions to the global python namespace */
rt_store_name(qstr_from_str("help"), rt_make_function_n(0, py_help)); rt_store_global(qstr_from_str("help"), rt_make_function_n(0, py_help));
rt_store_name(qstr_from_str("open"), rt_make_function_n(2, py_file_open)); rt_store_global(qstr_from_str("open"), rt_make_function_n(2, py_file_open));
rt_store_name(qstr_from_str("vcp_connected"), rt_make_function_n(0, py_vcp_connected)); rt_store_global(qstr_from_str("vcp_connected"), rt_make_function_n(0, py_vcp_connected));
rt_store_name(qstr_from_str("info"), rt_make_function_n(0, py_info)); rt_store_global(qstr_from_str("info"), rt_make_function_n(0, py_info));
rt_store_name(qstr_from_str("gc_collect"), rt_make_function_n(0, py_gc_collect)); rt_store_global(qstr_from_str("gc_collect"), rt_make_function_n(0, py_gc_collect));
py_image_init();
/* Export Python modules to the global python namespace */ /* Export Python modules to the global python namespace */
for (module_t *p = exported_modules; p->name != NULL; p++) { for (module_t *p = exported_modules; p->name != NULL; p++) {
@ -261,6 +263,7 @@ int main(void)
} }
} }
/* Try to mount the flash fs */ /* Try to mount the flash fs */
bool reset_filesystem = false; bool reset_filesystem = false;
FRESULT res = f_mount(&fatfs0, "0:", 1); FRESULT res = f_mount(&fatfs0, "0:", 1);

View File

@ -83,6 +83,60 @@ static void py_image_print(void (*print)(void *env, const char *fmt, ...), void
print(env, "<image width:%d height:%d bpp:%d>", self->_cobj.w, self->_cobj.h, self->_cobj.bpp); print(env, "<image width:%d height:%d bpp:%d>", self->_cobj.w, self->_cobj.h, self->_cobj.bpp);
} }
static mp_obj_t py_image_save(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
{
rectangle_t r;
image_t *image = py_image_cobj(args[0]);
const char *path = mp_obj_str_get_str(args[1]);
mp_map_elem_t *kw_subimage = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("subimage")), MP_MAP_LOOKUP);
if (kw_subimage != NULL) {
mp_obj_t *array;
mp_obj_get_array_fixed_n(kw_subimage->value, 4, &array);
r.x = mp_obj_get_int(array[0]);
r.y = mp_obj_get_int(array[1]);
r.w = mp_obj_get_int(array[2]);
r.h = mp_obj_get_int(array[3]);
}
int res;
if ((res=imlib_save_image(image, path, &r)) != FR_OK) {
nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
}
return mp_const_true;
}
static mp_obj_t py_image_blit(mp_obj_t dst_image_obj, mp_obj_t offset_obj, mp_obj_t src_image_obj)
{
int x,y;
image_t *src_image = NULL;
image_t *dst_image = NULL;
/* sanity checks */
PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QQVGA);
PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE);
/* get C image pointer */
src_image = py_image_cobj(src_image_obj);
dst_image = py_image_cobj(dst_image_obj);
/* get x,y */
mp_obj_t *array;
mp_obj_get_array_fixed_n(offset_obj, 2, &array);
x = mp_obj_get_int(array[0]);
y = mp_obj_get_int(array[1]);
if ((src_image->w+x)>dst_image->w ||
(src_image->h+y)>dst_image->h) {
printf("src image > dst image\n");
return mp_const_none;
}
imlib_blit(dst_image, src_image, x, y);
return mp_const_true;
}
static mp_obj_t py_image_histeq(mp_obj_t image_obj) static mp_obj_t py_image_histeq(mp_obj_t image_obj)
{ {
struct image *image; struct image *image;
@ -90,61 +144,24 @@ static mp_obj_t py_image_histeq(mp_obj_t image_obj)
image = (struct image*) py_image_cobj(image_obj); image = (struct image*) py_image_cobj(image_obj);
/* sanity checks */ /* sanity checks */
PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); PY_ASSERT_TRUE(image->bpp == 1);
imlib_histeq(image); imlib_histeq(image);
return mp_const_none; return mp_const_none;
} }
static mp_obj_t py_image_median(mp_obj_t image_obj, mp_obj_t ksize) static mp_obj_t py_image_median(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
{ {
struct image *image; int ksize = 1;
/* get image pointer */ /* get image pointer */
image = (struct image*) py_image_cobj(image_obj); image_t *image = py_image_cobj(args[0]);
/* sanity checks */ mp_map_elem_t *kw_ksize = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("size")), MP_MAP_LOOKUP);
//PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); if (kw_ksize != NULL) {
ksize = mp_obj_get_int(kw_ksize->value);
}
imlib_median_filter(image, mp_obj_get_int(ksize)); imlib_median_filter(image, ksize);
return mp_const_none;
}
static mp_obj_t py_image_draw_rectangle(mp_obj_t image_obj, mp_obj_t rectangle_obj)
{
struct rectangle r;
struct image *image;
mp_obj_t *array;
mp_obj_get_array_fixed_n(rectangle_obj, 4, &array);
r.x = mp_obj_get_int(array[0]);
r.y = mp_obj_get_int(array[1]);
r.w = mp_obj_get_int(array[2]);
r.h = mp_obj_get_int(array[3]);
/* get image pointer */
image = py_image_cobj(image_obj);
imlib_draw_rectangle(image, &r);
return mp_const_none;
}
static mp_obj_t py_image_draw_circle(mp_obj_t image_obj, mp_obj_t c_obj, mp_obj_t r_obj)
{
int cx, cy, r;
mp_obj_t *array;
struct image *image;
/* get image pointer */
image = py_image_cobj(image_obj);
/* center */
mp_obj_get_array_fixed_n(c_obj, 2, &array);
cx = mp_obj_get_int(array[0]);
cy = mp_obj_get_int(array[1]);
/* radius */
r = mp_obj_get_int(r_obj);
imlib_draw_circle(image, cx, cy, r);
return mp_const_none; return mp_const_none;
} }
@ -172,7 +189,61 @@ static mp_obj_t py_image_threshold(mp_obj_t image_obj, mp_obj_t color_obj, mp_ob
return mp_const_none; return mp_const_none;
} }
static mp_obj_t py_image_count_blobs(mp_obj_t image_obj) static mp_obj_t py_image_draw_circle(mp_obj_t image_obj, mp_obj_t c_obj, mp_obj_t r_obj)
{
int cx, cy, r;
mp_obj_t *array;
struct image *image;
/* get image pointer */
image = py_image_cobj(image_obj);
/* center */
mp_obj_get_array_fixed_n(c_obj, 2, &array);
cx = mp_obj_get_int(array[0]);
cy = mp_obj_get_int(array[1]);
/* radius */
r = mp_obj_get_int(r_obj);
imlib_draw_circle(image, cx, cy, r);
return mp_const_none;
}
static mp_obj_t py_image_draw_rectangle(mp_obj_t image_obj, mp_obj_t rectangle_obj)
{
struct rectangle r;
struct image *image;
mp_obj_t *array;
mp_obj_get_array_fixed_n(rectangle_obj, 4, &array);
r.x = mp_obj_get_int(array[0]);
r.y = mp_obj_get_int(array[1]);
r.w = mp_obj_get_int(array[2]);
r.h = mp_obj_get_int(array[3]);
/* get image pointer */
image = py_image_cobj(image_obj);
imlib_draw_rectangle(image, &r);
return mp_const_none;
}
static mp_obj_t py_image_draw_keypoints(mp_obj_t image_obj, mp_obj_t surf_obj)
{
surf_t *surf = NULL;
image_t *image = NULL;
/* get C image pointer */
image = py_image_cobj(image_obj);
/* get C cascade pointer */
surf = py_surf_cobj(surf_obj);
surf_draw_ipts(image, surf->ipts);
return mp_const_none;
}
static mp_obj_t py_image_find_blobs(mp_obj_t image_obj)
{ {
/* C stuff */ /* C stuff */
array_t *blobs; array_t *blobs;
@ -208,7 +279,7 @@ static mp_obj_t py_image_count_blobs(mp_obj_t image_obj)
return objects_list; return objects_list;
} }
static mp_obj_t py_image_detect_objects(mp_obj_t image_obj, mp_obj_t cascade_obj) static mp_obj_t py_image_find_features(mp_obj_t image_obj, mp_obj_t cascade_obj)
{ {
struct image *image = NULL; struct image *image = NULL;
struct cascade *cascade = NULL; struct cascade *cascade = NULL;
@ -248,82 +319,7 @@ static mp_obj_t py_image_detect_objects(mp_obj_t image_obj, mp_obj_t cascade_obj
return objects_list; return objects_list;
} }
static mp_obj_t py_image_load_cascade(mp_obj_t path_obj) static mp_obj_t py_image_find_template(mp_obj_t image_obj, mp_obj_t template_obj, mp_obj_t threshold)
{
py_cascade_obj_t *o =NULL;
/* detection parameters */
struct cascade cascade = {
.step = 2,
.scale_factor = 1.25f,
};
const char *path = mp_obj_str_get_str(path_obj);
int res = imlib_load_cascade(&cascade, path);
if (res != FR_OK) {
nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
}
o = m_new_obj(py_cascade_obj_t);
o->base.type = &py_cascade_type;
o->_cobj = cascade;
return o;
}
static mp_obj_t py_image_load_template(mp_obj_t path_obj)
{
mp_obj_t image_obj =NULL;
struct image *image;
const char *path = mp_obj_str_get_str(path_obj);
image_obj = py_image(0, 0, 0, 0);
/* get image pointer */
image = py_image_cobj(image_obj);
int res = imlib_load_template(image, path);
if (res != FR_OK) {
nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
}
return image_obj;
}
static mp_obj_t py_image_save_template(mp_obj_t image_obj, mp_obj_t rectangle_obj, mp_obj_t path_obj)
{
struct image t;
struct image *image = NULL;
struct rectangle r;
mp_obj_t *array;
const char *path = mp_obj_str_get_str(path_obj);
mp_obj_get_array_fixed_n(rectangle_obj, 4, &array);
r.x = mp_obj_get_int(array[0]);
r.y = mp_obj_get_int(array[1]);
r.w = mp_obj_get_int(array[2]);
r.h = mp_obj_get_int(array[3]);
/* get C image pointer */
image = py_image_cobj(image_obj);
t.w = r.w;
t.h = r.h;
t.data = xalloc(sizeof(*t.data)*t.w*t.h); /* TODO this is not really needed */
imlib_subimage(image, &t, r.x, r.y);
int res = imlib_save_template(&t, path);
xfree(t.data);
if (res != FR_OK) {
nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
}
return mp_const_true;
}
static mp_obj_t py_image_template_match(mp_obj_t image_obj, mp_obj_t template_obj, mp_obj_t threshold)
{ {
struct rectangle r; struct rectangle r;
struct image *image = NULL; struct image *image = NULL;
@ -353,41 +349,39 @@ static mp_obj_t py_image_template_match(mp_obj_t image_obj, mp_obj_t template_ob
return obj; return obj;
} }
static mp_obj_t py_image_blit(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)
{ {
struct image *image = NULL;
struct image *template = NULL;
/* sanity checks */
PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QQVGA);
PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE);
/* get C image pointer */
image = py_image_cobj(image_obj);
template= py_image_cobj(template_obj);
imlib_blit(image, template, 0, 0);
return mp_const_true;
}
static mp_obj_t py_image_surf_detector(mp_obj_t image_obj, mp_obj_t upright, mp_obj_t thresh)
{
struct image *image;
py_surf_obj_t *o =NULL; py_surf_obj_t *o =NULL;
surf_t surf = { surf_t surf = {
.upright=mp_obj_get_int(upright), .upright=false,
.octaves=5, .octaves=2,
.init_sample=2, .init_sample=2,
.thresh=mp_obj_get_float(thresh), .thresh=0.0004f,
}; };
/* get image pointer */ /* get image pointer */
image = (struct image*) py_image_cobj(image_obj); image_t *image = py_image_cobj(args[0]);
/* sanity checks */ /* sanity checks */
PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE);
/* read KW args */
mp_map_elem_t *kw_upright = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("upright")), MP_MAP_LOOKUP);
if (kw_upright != NULL) {
surf.upright = mp_obj_get_int(kw_upright->value);
}
mp_map_elem_t *kw_octaves = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("octaves")), MP_MAP_LOOKUP);
if (kw_octaves != NULL) {
surf.octaves = mp_obj_get_int(kw_octaves->value);
}
mp_map_elem_t *kw_thresh = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("thresh")), MP_MAP_LOOKUP);
if (kw_thresh != NULL) {
surf.thresh = mp_obj_get_float(kw_thresh->value);
}
/* run SURF detector */ /* run SURF detector */
surf_detector(image, &surf); surf_detector(image, &surf);
@ -397,73 +391,111 @@ static mp_obj_t py_image_surf_detector(mp_obj_t image_obj, mp_obj_t upright, mp_
return o; return o;
} }
static mp_obj_t py_image_surf_match(mp_obj_t image_obj, mp_obj_t surf1_obj, mp_obj_t surf2_obj) static mp_obj_t py_image_find_keypoints_match(mp_obj_t image_obj, mp_obj_t surf1_obj)
{ {
surf_t *surf1 = NULL; surf_t *surf1 = NULL, surf2;
surf_t *surf2 = NULL;
image_t *image = NULL; image_t *image = NULL;
/* get C image pointer */ /* get C image pointer */
image = py_image_cobj(image_obj); image = py_image_cobj(image_obj);
/* get C cascade pointer */ /* get C cascade pointer */
surf1 = py_surf_cobj(surf1_obj); surf1 = py_surf_cobj(surf1_obj);
surf2 = py_surf_cobj(surf2_obj); surf2 = *surf1; //use same parameters
/* run SURF detector */
surf_detector(image, &surf2);
/* Detect objects */ /* Detect objects */
array_t *match = surf_match(surf1, surf2); array_t *match = surf_match(surf1, &surf2);
// TODO return matching kpts
surf_draw_ipts(image, match); surf_draw_ipts(image, match);
array_free(match); //TODO array_free(match);
array_free(surf2->ipts); //TODO array_free(surf2.ipts);
return mp_const_none; return mp_const_none;
} }
static mp_obj_t py_image_surf_draw_ipts(mp_obj_t image_obj, mp_obj_t surf_obj) static mp_obj_t py_image_load_image(mp_obj_t path_obj)
{ {
surf_t *surf = NULL; mp_obj_t image_obj =NULL;
image_t *image = NULL; struct image *image;
const char *path = mp_obj_str_get_str(path_obj);
image_obj = py_image(0, 0, 0, 0);
/* get C image pointer */ /* get image pointer */
image = py_image_cobj(image_obj); image = py_image_cobj(image_obj);
/* get C cascade pointer */ int res = imlib_load_image(image, path);
surf = py_surf_cobj(surf_obj); if (res != FR_OK) {
nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
}
surf_draw_ipts(image, surf->ipts); return image_obj;
return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_blit_obj, py_image_blit); static mp_obj_t py_image_load_cascade(mp_obj_t path_obj)
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_load_cascade_obj, py_image_load_cascade); {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_load_template_obj, py_image_load_template); py_cascade_obj_t *o =NULL;
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_save_template_obj, py_image_save_template);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_template_match_obj, py_image_template_match); /* detection parameters */
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_histeq_obj, py_image_histeq); struct cascade cascade = {
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_median_obj, py_image_median); .step = 2,
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_draw_rectangle_obj, py_image_draw_rectangle); .scale_factor = 1.25f,
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_draw_circle_obj, py_image_draw_circle); };
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_threshold_obj, py_image_threshold);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_count_blobs_obj, py_image_count_blobs); const char *path = mp_obj_str_get_str(path_obj);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_detect_objects_obj, py_image_detect_objects); int res = imlib_load_cascade(&cascade, path);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_surf_detector_obj, py_image_surf_detector); if (res != FR_OK) {
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_surf_match_obj, py_image_surf_match); nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_surf_draw_ipts_obj, py_image_surf_draw_ipts); }
o = m_new_obj(py_cascade_obj_t);
o->base.type = &py_cascade_type;
o->_cobj = cascade;
return o;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_save_obj, 2, py_image_save);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_blit_obj, py_image_blit);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_histeq_obj, py_image_histeq);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_median_obj, 1, py_image_median);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_threshold_obj, py_image_threshold);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_draw_circle_obj, py_image_draw_circle);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_draw_rectangle_obj, py_image_draw_rectangle);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_draw_keypoints_obj, py_image_draw_keypoints);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_find_blobs_obj, py_image_find_blobs);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_find_template_obj, py_image_find_template);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_find_features_obj, py_image_find_features);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_find_keypoints_obj, 1, py_image_find_keypoints);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_find_keypoints_match_obj, py_image_find_keypoints_match);
//STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_load_cascade_obj, py_image_load_cascade);
//STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_load_image_obj, py_image_load_image);
static const mp_method_t py_image_methods[] = { static const mp_method_t py_image_methods[] = {
{"blit", &py_image_blit_obj}, /* basic image functions */
{"load_cascade", &py_image_load_cascade_obj}, {"save", &py_image_save_obj},
{"load_template", &py_image_load_template_obj}, {"blit", &py_image_blit_obj},
{"save_template", &py_image_save_template_obj}, {"histeq", &py_image_histeq_obj},
{"template_match", &py_image_template_match_obj}, {"median", &py_image_median_obj},
{"histeq", &py_image_histeq_obj}, {"threshold", &py_image_threshold_obj},
{"median", &py_image_median_obj},
{"draw_rectangle", &py_image_draw_rectangle_obj}, /* drawing functions */
{"draw_circle", &py_image_draw_circle_obj}, {"draw_circle", &py_image_draw_circle_obj},
{"threshold", &py_image_threshold_obj}, {"draw_rectangle", &py_image_draw_rectangle_obj},
{"count_blobs", &py_image_count_blobs_obj}, {"draw_keypoints", &py_image_draw_keypoints_obj},
{"detect_objects", &py_image_detect_objects_obj},
{"surf_detector", &py_image_surf_detector_obj}, /* objects/feature detection */
{"surf_match", &py_image_surf_match_obj}, {"find_blobs", &py_image_find_blobs_obj},
{"surf_draw_ipts", &py_image_surf_draw_ipts_obj}, {"find_template", &py_image_find_template_obj},
{"find_features", &py_image_find_features_obj},
{"find_keypoints", &py_image_find_keypoints_obj},
{"find_keypoints_match",&py_image_find_keypoints_match_obj},
{ NULL, NULL }, { NULL, NULL },
}; };
@ -486,6 +518,12 @@ mp_obj_t py_image(int w, int h, int bpp, void *pixels)
return o; return o;
} }
void py_image_init()
{
rt_store_global(qstr_from_str("Image"), rt_make_function_n(1, py_image_load_image));
rt_store_global(qstr_from_str("HaarCascade"), rt_make_function_n(1, py_image_load_cascade));
}
#if 0 #if 0
typedef struct _mp_obj_array_it_t { typedef struct _mp_obj_array_it_t {
mp_obj_base_t base; mp_obj_base_t base;