static mp_obj_t py_image_draw_keypoints(mp_obj_t image_obj, mp_obj_t kpts_obj) { image_t *image = NULL; py_kp_obj_t *kpts=NULL; /* get pointer */ image = py_image_cobj(image_obj); kpts = (py_kp_obj_t*)kpts_obj; /* sanity checks */ PY_ASSERT_TRUE_MSG(image->bpp == 1, "This function is only supported on GRAYSCALE images"); PY_ASSERT_TYPE(kpts_obj, &py_kp_type); color_t cl = {.r=0xFF, .g=0xFF, .b=0xFF}; for (int i=0; i<kpts->size; i++) { kp_t *kp = &kpts->kpts[i]; float co = arm_cos_f32(kp->angle); float si = arm_sin_f32(kp->angle); imlib_draw_line(image, kp->x, kp->y, kp->x+(co*10), kp->y+(si*10)); imlib_draw_circle(image, kp->x, kp->y, 4, &cl); } return mp_const_none; } static mp_obj_t py_image_find_blobs(mp_obj_t image_obj) { /* C stuff */ array_t *blobs; struct image *image; mp_obj_t blob_obj[6]; /* MP List */ mp_obj_t objects_list = mp_const_none; /* get image pointer */ image = py_image_cobj(image_obj); /* run color dector */ blobs = imlib_count_blobs(image); /* Create empty Python list */ objects_list = mp_obj_new_list(0, NULL); if (array_length(blobs)) { for (int j=0; j<array_length(blobs); j++) { blob_t *r = array_at(blobs, j); blob_obj[0] = mp_obj_new_int(r->x); blob_obj[1] = mp_obj_new_int(r->y); blob_obj[2] = mp_obj_new_int(r->w); blob_obj[3] = mp_obj_new_int(r->h); blob_obj[4] = mp_obj_new_int(r->c); blob_obj[5] = mp_obj_new_int(r->id); mp_obj_list_append(objects_list, mp_obj_new_tuple(6, blob_obj)); } } array_free(blobs); return objects_list; }
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; color_t c = {.r=0xFF, .g=0xFF, .b=0xFF}; /* 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, &c); return mp_const_none; } static mp_obj_t py_image_draw_string(uint n_args, const mp_obj_t *args) { int x = mp_obj_get_int(args[1]); int y = mp_obj_get_int(args[2]); image_t *image =py_image_cobj(args[0]); const char *str = mp_obj_str_get_str(args[3]); color_t c = {.r=0xFF, .g=0xFF, .b=0xFF}; // check x, y PY_ASSERT_TRUE_MSG(x>=0 && x<image->w, "Image index out of range"); PY_ASSERT_TRUE_MSG(y>=0 && y<image->h, "Image index out of range"); PY_ASSERT_TRUE_MSG(image->bpp <= 2, "This function is not supported on JPEG images"); if (n_args == 5) { // get color mp_obj_t *array; mp_obj_get_array_fixed_n(args[4], 3, &array); c.r = mp_obj_get_int(array[0]); c.g = mp_obj_get_int(array[1]); c.b = mp_obj_get_int(array[2]); } imlib_draw_string(image, x, y, str, &c); return mp_const_none; } static mp_obj_t py_image_erode(mp_obj_t image_obj, mp_obj_t ksize_obj) { image_t *image = NULL; image = py_image_cobj(image_obj); /* sanity checks */ PY_ASSERT_TRUE_MSG(image->bpp == 1, "This function is only supported on GRAYSCALE images"); imlib_erode(image, mp_obj_get_int(ksize_obj)); return mp_const_none; }
static mp_obj_t py_image_blend(mp_obj_t dst_image_obj, mp_obj_t src_image_obj, mp_obj_t param_obj) { int x,y; float alpha; image_t *src_image = NULL; image_t *dst_image = NULL; /* get C image pointer */ src_image = py_image_cobj(src_image_obj); dst_image = py_image_cobj(dst_image_obj); /* get x,y,alpha */ mp_obj_t *array; mp_obj_get_array_fixed_n(param_obj, 3, &array); x = mp_obj_get_int(array[0]); y = mp_obj_get_int(array[1]); alpha = mp_obj_get_float(array[2]); 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_blend(src_image, dst_image, x, y, (uint8_t)(alpha*256)); return mp_const_none; }
static mp_obj_t py_image_save(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { int res; 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); rectangle_t r = { mp_obj_get_int(array[0]), mp_obj_get_int(array[1]), mp_obj_get_int(array[2]), mp_obj_get_int(array[3]), }; res = imlib_save_image(image, path, &r); } else { res = imlib_save_image(image, path, NULL); } if (res != FR_OK) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res))); } return mp_const_true; }
mp_obj_t py_imlib_detect_color(mp_obj_t image_obj, mp_obj_t color_obj, mp_obj_t threshold) { /* C stuff */ struct color color; struct rectangle rectangle; struct image *image; /* sanity checks */ PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_RGB565); mp_obj_t *col_obj; col_obj = mp_obj_get_array_fixed_n(color_obj, 3); color.h = mp_obj_get_int(col_obj[0]); color.s = mp_obj_get_int(col_obj[1]); color.v = mp_obj_get_int(col_obj[2]); /* get image pointer */ image = py_image_cobj(image_obj); imlib_detect_color(image, &color, &rectangle, mp_obj_get_int(threshold)); mp_obj_t rec_obj[4]; rec_obj[0] = mp_obj_new_int(rectangle.x); rec_obj[1] = mp_obj_new_int(rectangle.y); rec_obj[2] = mp_obj_new_int(rectangle.w); rec_obj[3] = mp_obj_new_int(rectangle.h); return rt_build_tuple(4, rec_obj); }
static mp_obj_t py_image_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { py_image_obj_t *o = self_in; image_t *image = py_image_cobj(self_in); if (value == MP_OBJ_NULL) { // delete return MP_OBJ_NULL; // op not supported } else if (value == MP_OBJ_SENTINEL) { // load mp_uint_t pixel; mp_uint_t index = mp_get_index(o->base.type, image->w*image->h, index_in, false); switch (image->bpp) { case 1: pixel = image->pixels[index]; break; case 2: pixel = image->pixels[index*2]<<8 | image->pixels[index*2+1]; break; default: return MP_OBJ_NULL; // op not supported } return mp_obj_new_int(pixel); } else { // store return mp_const_none; } }
mp_obj_t py_imlib_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); array = mp_obj_get_array_fixed_n(rectangle_obj, 4); 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 = malloc(sizeof(*t.data)*t.w*t.h); imlib_subimage(image, &t, r.x, r.y); int res = imlib_save_template(&t, path); free(t.data); if (res != FR_OK) { nlr_jump(mp_obj_new_exception_msg(qstr_from_str("Imlib"), ffs_strerror(res))); } return mp_const_true; }
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; struct cascade *cascade = NULL; array_t *objects_array=NULL; mp_obj_t objects_list = mp_const_none; /* sanity checks */ PY_ASSERT_TRUE_MSG(sensor.pixformat == PIXFORMAT_GRAYSCALE, "This function is only supported on GRAYSCALE images"); PY_ASSERT_TRUE_MSG(sensor.framesize <= OMV_MAX_INT_FRAME, "This function is only supported on "OMV_MAX_INT_FRAME_STR" and smaller frames"); /* read arguments */ image = py_image_cobj(args[0]); cascade = py_cascade_cobj(args[1]); /* set some defaults */ cascade->threshold = 0.65f; cascade->scale_factor = 1.65f; /* read kw args */ mp_map_elem_t *kw_thresh = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("threshold")), MP_MAP_LOOKUP); if (kw_thresh != NULL) { 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); } /* Detect objects */ objects_array = imlib_detect_objects(image, cascade); /* Create empty Python list */ objects_list = mp_obj_new_list(0, NULL); /* Add detected objects to the list */ for (int i=0; i<array_length(objects_array); i++) { struct rectangle *r = array_at(objects_array, i); mp_obj_t rec_obj[4] = { mp_obj_new_int(r->x), mp_obj_new_int(r->y), mp_obj_new_int(r->w), mp_obj_new_int(r->h), }; mp_obj_list_append(objects_list, mp_obj_new_tuple(4, rec_obj)); } /* Free the objects array */ array_free(objects_array); return objects_list; }
static mp_obj_t py_image_dilate(mp_obj_t image_obj, mp_obj_t ksize_obj) { image_t *image = NULL; image = py_image_cobj(image_obj); /* sanity checks */ PY_ASSERT_TRUE(image->bpp==1); imlib_dilate(image, mp_obj_get_int(ksize_obj)); return mp_const_none; }
static mp_obj_t py_image_size(mp_obj_t self_in) { uint32_t len; image_t *image = py_image_cobj(self_in); if (image->bpp > 2) { //JPEG len = image->bpp; } else { len = image->w*image->h*image->bpp; } return mp_obj_new_int(len); }
static mp_obj_t py_image_dilate(mp_obj_t image_obj, mp_obj_t ksize_obj) { image_t *image = NULL; image = py_image_cobj(image_obj); /* sanity checks */ PY_ASSERT_TRUE_MSG(image->bpp == 1, "This function is only supported on GRAYSCALE images"); imlib_dilate(image, mp_obj_get_int(ksize_obj)); return mp_const_none; }
static mp_obj_t py_image_histeq(mp_obj_t image_obj) { struct image *image; /* get image pointer */ image = (struct image*) py_image_cobj(image_obj); /* sanity checks */ PY_ASSERT_TRUE(image->bpp == 1); imlib_histeq(image); return mp_const_none; }
mp_obj_t py_imlib_histeq(mp_obj_t image_obj) { struct image *image; /* get image pointer */ image = (struct image*) py_image_cobj(image_obj); /* sanity checks */ PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); imlib_histeq(image); return mp_const_none; }
static mp_obj_t py_image_invert(mp_obj_t image_obj) { image_t *image; image = py_image_cobj(image_obj); /* Sanity checks */ PY_ASSERT_TRUE(image->bpp == 1); /* Threshold image */ imlib_invert(image); return mp_const_none; }
static mp_obj_t py_image_histeq(mp_obj_t image_obj) { struct image *image; /* get image pointer */ image = (struct image*) py_image_cobj(image_obj); /* sanity checks */ PY_ASSERT_TRUE_MSG(image->bpp == 1, "This function is only supported on GRAYSCALE images"); imlib_histeq(image); return mp_const_none; }
static mp_obj_t py_image_invert(mp_obj_t image_obj) { image_t *image; image = py_image_cobj(image_obj); /* Sanity checks */ PY_ASSERT_TRUE_MSG(image->bpp == 1, "This function is only supported on GRAYSCALE images"); /* Threshold image */ imlib_invert(image); return mp_const_none; }
static mp_obj_t py_image_median(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { int ksize = 1; /* get image pointer */ image_t *image = py_image_cobj(args[0]); mp_map_elem_t *kw_ksize = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("size")), MP_MAP_LOOKUP); if (kw_ksize != NULL) { ksize = mp_obj_get_int(kw_ksize->value); } imlib_median_filter(image, ksize); return mp_const_none; }
static mp_obj_t py_image_draw_line(mp_obj_t image_obj, mp_obj_t line_obj) { /* get image pointer */ struct image *image; image = py_image_cobj(image_obj); mp_obj_t *array; mp_obj_get_array_fixed_n(line_obj, 4, &array); int x0 = mp_obj_get_int(array[0]); int y0 = mp_obj_get_int(array[1]); int x1 = mp_obj_get_int(array[2]); int y1 = mp_obj_get_int(array[3]); imlib_draw_line(image, x0, y0, x1, y1); return mp_const_none; }
static mp_obj_t py_spi_write_image(mp_obj_t image_obj) { struct image *image; /* get image pointer */ image = (struct image*) py_image_cobj(image_obj); uint16_t *pixels = (uint16_t*)image->data; for (int j=0;j<image->h;j++) { for (int i=0;i<image->w;i++) { uint16_t c = pixels[j*image->w+i]; spi_write(c); spi_write(c>>8); } } return mp_const_none; }
static mp_obj_t py_image_binary(mp_obj_t image_obj, mp_obj_t threshold) { image_t *image; /* sanity checks */ PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QCIF); PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); /* read arguments */ image = py_image_cobj(image_obj); int thresh = mp_obj_get_int(threshold); /* Threshold image */ imlib_binary(image, thresh); 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_binary(mp_obj_t image_obj, mp_obj_t threshold) { image_t *image; /* sanity checks */ PY_ASSERT_TRUE_MSG(sensor.pixformat == PIXFORMAT_GRAYSCALE, "This function is only supported on GRAYSCALE images"); PY_ASSERT_TRUE_MSG(sensor.framesize <= OMV_MAX_RAW_FRAME, "This function is only supported on "OMV_MAX_RAW_FRAME_STR" and smaller frames"); /* read arguments */ image = py_image_cobj(image_obj); int thresh = mp_obj_get_int(threshold); /* Threshold image */ imlib_binary(image, thresh); return mp_const_none; }
static mp_int_t py_image_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { image_t *image = py_image_cobj(self_in); if (flags == MP_BUFFER_READ) { bufinfo->buf = (void*)image->pixels; if (image->bpp > 2) { //JPEG bufinfo->len = image->bpp; } else { bufinfo->len = image->w*image->h*image->bpp; } bufinfo->typecode = 'b'; return 0; } else { // disable write for now bufinfo->buf = NULL; bufinfo->len = 0; bufinfo->typecode = -1; return 1; } }
mp_obj_t py_imlib_load_cascade(mp_obj_t path_obj) { 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(qstr_from_str("Imlib"), ffs_strerror(res))); } o = m_new_obj(py_cascade_obj_t); o->base.type = &py_cascade_type; o->_cobj = cascade; return o; } mp_obj_t py_imlib_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(qstr_from_str("Imlib"), ffs_strerror(res))); } return image_obj; }
mp_obj_t py_imlib_detect_objects(mp_obj_t image_obj, mp_obj_t cascade_obj) { struct image *image = NULL; struct cascade *cascade = NULL; struct array *objects_array=NULL; mp_obj_t objects_list = mp_const_none; /* 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); /* get C cascade pointer */ cascade = py_cascade_cobj(cascade_obj); /* detect objects */ objects_array = imlib_detect_objects(image, cascade); int size = array_length(objects_array); if (size) { int i; objects_list = rt_build_list(0, NULL); for (i=0; i<size; i++) { struct rectangle *r = array_at(objects_array, 0); mp_obj_t rec_obj[4]; rec_obj[0] = mp_obj_new_int(r->x); rec_obj[1] = mp_obj_new_int(r->y); rec_obj[2] = mp_obj_new_int(r->w); rec_obj[3] = mp_obj_new_int(r->h); rt_list_append(objects_list, rt_build_tuple(4, rec_obj)); } } /* free objects array */ array_free(objects_array); return objects_list; }
static mp_obj_t py_sensor_snapshot() { mp_obj_t image = py_image(0, 0, 0, 0); sensor_snapshot((struct image*) py_image_cobj(image)); return image; }
static mp_obj_t py_image_threshold(mp_obj_t image_obj, mp_obj_t color_list_obj, mp_obj_t threshold) { color_t *color; image_t *image; /* sanity checks */ PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_RGB565); PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QCIF); /* read arguments */ image = py_image_cobj(image_obj); int thresh = mp_obj_get_int(threshold); /* returned image */ image_t bimage = { .w=image->w, .h=image->h, .bpp=1, .pixels=image->data+(image->w*image->h*image->bpp) }; /* copy color list */ uint len; mp_obj_t *color_arr; mp_obj_get_array(color_list_obj, &len, &color_arr); color = xalloc(len*sizeof*color); for (int i=0; i<len; i++) { mp_obj_t *color_obj; mp_obj_get_array_fixed_n(color_arr[i], 3, &color_obj); color[i].r = mp_obj_get_int(color_obj[0]); color[i].g = mp_obj_get_int(color_obj[1]); color[i].b = mp_obj_get_int(color_obj[2]); } /* Threshold image using reference color */ imlib_threshold(image, &bimage, color, len, thresh); return py_image_from_struct(&bimage); } static mp_obj_t py_image_rainbow(mp_obj_t src_image_obj) { image_t *src_image = NULL; /* get C image pointer */ src_image = py_image_cobj(src_image_obj); /* sanity checks */ PY_ASSERT_TRUE(src_image->bpp==1); image_t dst_image = { .w=src_image->w, .h=src_image->h, .bpp=2, .pixels=xalloc(src_image->w*src_image->h*2) }; imlib_rainbow(src_image, &dst_image); *src_image = dst_image; return src_image_obj; } static mp_obj_t py_image_compress(mp_obj_t image_obj, mp_obj_t quality) { image_t *image = py_image_cobj(image_obj); image_t cimage = { .w=image->w, .h=image->h, .bpp=0, .pixels= NULL }; jpeg_compress(image, &cimage, mp_obj_get_int(quality)); return py_image_from_struct(&cimage); } static mp_obj_t py_image_draw_line(mp_obj_t image_obj, mp_obj_t line_obj) { /* get image pointer */ struct image *image; image = py_image_cobj(image_obj); mp_obj_t *array; mp_obj_get_array_fixed_n(line_obj, 4, &array); int x0 = mp_obj_get_int(array[0]); int y0 = mp_obj_get_int(array[1]); int x1 = mp_obj_get_int(array[2]); int y1 = mp_obj_get_int(array[3]); imlib_draw_line(image, x0, y0, x1, y1); 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; color_t c = {.r=0xFF, .g=0xFF, .b=0xFF}; /* 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, &c); return mp_const_none; } static mp_obj_t py_image_draw_string(uint n_args, const mp_obj_t *args) { int x = mp_obj_get_int(args[1]); int y = mp_obj_get_int(args[2]); image_t *image =py_image_cobj(args[0]); const char *str = mp_obj_str_get_str(args[3]); color_t c = {.r=0xFF, .g=0xFF, .b=0xFF}; if (n_args == 5) { // get color mp_obj_t *array; mp_obj_get_array_fixed_n(args[4], 3, &array); c.r = mp_obj_get_int(array[0]); c.g = mp_obj_get_int(array[1]); c.b = mp_obj_get_int(array[2]); } imlib_draw_string(image, x, y, str, &c); return mp_const_none; } static mp_obj_t py_image_erode(mp_obj_t image_obj, mp_obj_t ksize_obj) { image_t *image = NULL; image = py_image_cobj(image_obj); /* sanity checks */ PY_ASSERT_TRUE(image->bpp==1); imlib_erode(image, mp_obj_get_int(ksize_obj)); return mp_const_none; }
static mp_obj_t py_lcd_display(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { 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 rect; py_helper_keyword_rectangle_roi(arg_img, n_args, args, 1, kw_args, &rect); // Fit X. int l_pad = 0, r_pad = 0; if (rect.w > width) { int adjust = rect.w - width; rect.w -= adjust; rect.x += adjust / 2; } else if (rect.w < width) { int adjust = width - rect.w; l_pad = adjust / 2; r_pad = (adjust + 1) / 2; } // Fit Y. int t_pad = 0, b_pad = 0; if (rect.h > height) { int adjust = rect.h - height; rect.h -= adjust; rect.y += adjust / 2; } else if (rect.h < height) { int adjust = height - rect.h; t_pad = adjust / 2; b_pad = (adjust + 1) / 2; } switch (type) { case LCD_NONE: return mp_const_none; case LCD_SHIELD: lcd_write_command_byte(0x2C); uint8_t *zero = fb_alloc0(width*2); uint16_t *line = fb_alloc(width*2); for (int i=0; i<t_pad; i++) { lcd_write_data(width*2, zero); } for (int i=0; i<rect.h; i++) { if (l_pad) { lcd_write_data(l_pad*2, zero); // l_pad < width } if (IM_IS_GS(arg_img)) { for (int j=0; j<rect.w; j++) { uint8_t pixel = IM_GET_GS_PIXEL(arg_img, (rect.x + j), (rect.y + i)); line[j] = IM_RGB565(IM_R825(pixel),IM_G826(pixel),IM_B825(pixel)); } lcd_write_data(rect.w*2, (uint8_t *) line); } else { lcd_write_data(rect.w*2, (uint8_t *) (((uint16_t *) arg_img->pixels) + ((rect.y + i) * arg_img->w) + rect.x)); } if (r_pad) { lcd_write_data(r_pad*2, zero); // r_pad < width } } for (int i=0; i<b_pad; i++) { lcd_write_data(width*2, zero); } fb_free(); fb_free(); return mp_const_none; } return mp_const_none; }
} static mp_obj_t py_image_find_template(mp_obj_t image_obj, mp_obj_t template_obj, mp_obj_t threshold) { struct rectangle r; struct image *image = NULL; struct image *template = NULL; mp_obj_t rec_obj[4]; mp_obj_t obj=mp_const_none; /* 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); float t = mp_obj_get_float(threshold); /* look for object */ float corr = imlib_template_match(image, template, &r); //printf("t:%f coor:%f\n", (double)t, (double)corr); if (corr > t) { rec_obj[0] = mp_obj_new_int(r.x); rec_obj[1] = mp_obj_new_int(r.y); rec_obj[2] = mp_obj_new_int(r.w); rec_obj[3] = mp_obj_new_int(r.h); obj = mp_obj_new_tuple(4, rec_obj); } return obj;
static mp_obj_t py_image_scale(mp_obj_t image_obj, mp_obj_t size_obj) { int w,h; mp_obj_t *array; image_t *src_image = NULL; /* get C image pointer */ src_image = py_image_cobj(image_obj); /* get x,y */ mp_obj_get_array_fixed_n(size_obj, 2, &array); w = mp_obj_get_int(array[0]); h = mp_obj_get_int(array[1]); image_t dst_image = { .w=w, .h=h, .bpp=src_image->bpp, .pixels=xalloc(w*h*src_image->bpp) }; imlib_scale(src_image, &dst_image, INTERP_BILINEAR); *src_image = dst_image; return image_obj; } static mp_obj_t py_image_scaled(mp_obj_t image_obj, mp_obj_t size_obj) { int w,h; mp_obj_t *array; image_t *src_image = NULL; /* get C image pointer */ src_image = py_image_cobj(image_obj); /* get x,y */ mp_obj_get_array_fixed_n(size_obj, 2, &array); w = mp_obj_get_int(array[0]); h = mp_obj_get_int(array[1]); image_t dst_image = { .w=w, .h=h, .bpp=src_image->bpp, .pixels=xalloc(w*h*src_image->bpp) }; imlib_scale(src_image, &dst_image, INTERP_NEAREST); return py_image_from_struct(&dst_image); } static mp_obj_t py_image_subimg(mp_obj_t image_obj, mp_obj_t subimg_obj) { rectangle_t r; image_t *image; mp_obj_t *array; /* image pointer */ image = py_image_cobj(image_obj); /* sub image */ mp_obj_get_array_fixed_n(subimg_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]); image_t subimg = { .w=r.w, .h=r.h, .bpp=image->bpp, .pixels=xalloc(r.w*r.h*image->bpp) }; imlib_subimage(image, &subimg, r.x, r.y); return py_image_from_struct(&subimg); } static mp_obj_t py_image_blit(mp_obj_t dst_image_obj, mp_obj_t src_image_obj, mp_obj_t offset_obj) { int x,y; image_t *src_image = NULL; image_t *dst_image = NULL; /* 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(src_image, dst_image, x, y); return mp_const_none; }