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; }
mp_obj_t mlx90620_read() { float temp[64]; float max_temp = FLT_MIN; float min_temp = FLT_MAX; image_t img = { .w=4, .h=16, .bpp=1, .pixels=xalloc(16*4) }; // get raw temperatures mlx90620_read_to(temp); // normalize temp readings for (int i=0; i<64; i++) { if (temp[i] > max_temp) { max_temp = temp[i]; } else if (temp[i] < min_temp) { min_temp = temp[i]; } } for (int i=0; i<64; i++) { img.pixels[i] = (uint8_t)(((temp[i]-min_temp)/(max_temp-min_temp))*255.0f); } return py_image_from_struct(&img); } mp_obj_t mlx90620_read_raw() { float *t = m_new(float, 64); mp_obj_t t_list = mp_obj_new_list(0, NULL); // get raw temperatures mlx90620_read_to(t); // normalize temp readings for (int i=0; i<64; i++) { mp_obj_list_append(t_list, mp_obj_new_float(t[i])); } return t_list; } mp_obj_t mlx90620_init() { uint8_t cmd_buf[5]; uint8_t EEPROM_DATA[256]; // Init I2C soft_i2c_init(); // Read EEPROM data cmd_buf[0]=REG_EEPROM_DATA; soft_i2c_write_bytes(MLX_EEPROM_ADDR, cmd_buf, 1, false); soft_i2c_read_bytes(MLX_EEPROM_ADDR, EEPROM_DATA, 256, true); // Write oscillator trimming value uint8_t trim = EEPROM_DATA[OSC_TRIM_OFFSET]; memcpy(cmd_buf, (uint8_t [5]){WRITE_OSC_TRIM, (uint8_t)(trim-0xAA), trim, 0x56, 0x00}, 5); soft_i2c_write_bytes(MLX_SLAVE_ADDR, cmd_buf, sizeof(cmd_buf), true); // Write configuration register uint8_t lsb = 0x0A; //0x09==16Hz uint8_t msb = 0x74; memcpy(cmd_buf, (uint8_t [5]){SET_CONFIG_DATA, (uint8_t)(lsb-0x55), lsb, (uint8_t)(msb-0x55), msb}, 5); soft_i2c_write_bytes(MLX_SLAVE_ADDR, cmd_buf, sizeof(cmd_buf), true); // Calculate Ta constants v_th = (256 * EEPROM_DATA[VTH_H] + EEPROM_DATA[VTH_L]); k_t1 = (256 * EEPROM_DATA[KT1_H] + EEPROM_DATA[KT1_L]) / 1024.0f; k_t2 = (256 * EEPROM_DATA[KT2_H] + EEPROM_DATA[KT2_L]) / 1048576.0f; emissivity = ((unsigned int)256 * EEPROM_DATA[CAL_EMIS_H] + EEPROM_DATA[CAL_EMIS_L]) / 32768.0f; k_t1_sq = k_t1 * k_t1; a_cp = (int8_t)EEPROM_DATA[CAL_ACP]; b_cp = (int8_t)EEPROM_DATA[CAL_BCP]; tgc = (int8_t)EEPROM_DATA[CAL_TGC]; b_i_scale = EEPROM_DATA[CAL_BI_SCALE]; // Hack for (int i=0; i<8; i++) { EEPROM_DATA[i]=EEPROM_DATA[i+8]; EEPROM_DATA[i+64]=EEPROM_DATA[i+8+64]; } for (int i=0; i<64; i++) { // Read pixel offsets a_ij[i] = (int8_t)EEPROM_DATA[i]; // Read slope coefficients b_ij[i] = (int8_t)EEPROM_DATA[i+4]; } return mp_const_true; } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mlx90620_init_obj, mlx90620_init); STATIC MP_DEFINE_CONST_FUN_OBJ_0(mlx90620_read_obj, mlx90620_read); STATIC MP_DEFINE_CONST_FUN_OBJ_0(mlx90620_read_raw_obj, mlx90620_read_raw); static const mp_map_elem_t globals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_mlx) }, //{ MP_OBJ_NEW_QSTR(MP_QSTR_HZ_8), MP_OBJ_NEW_SMALL_INT(MLX_HZ_8)}, //{ MP_OBJ_NEW_QSTR(MP_QSTR_HZ_16), MP_OBJ_NEW_SMALL_INT(MLX_HZ_16)}, //{ MP_OBJ_NEW_QSTR(MP_QSTR_HZ_32), MP_OBJ_NEW_SMALL_INT(MLX_HZ_32)}, //{ MP_OBJ_NEW_QSTR(MP_QSTR_HZ_64), MP_OBJ_NEW_SMALL_INT(MLX_HZ_64)}, { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&mlx90620_init_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mlx90620_read_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_read_raw), (mp_obj_t)&mlx90620_read_raw_obj }, }; STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table); static const mp_obj_module_t mlx_module = { .base = { &mp_type_module }, .name = MP_QSTR_mlx, .globals = (mp_obj_t)&globals_dict, }; const mp_obj_module_t *py_mlx90620_init() { return &mlx_module; }
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; }
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_MSG(sensor.pixformat == PIXFORMAT_RGB565, "This function is only supported on RGB565 images"); PY_ASSERT_TRUE_MSG(sensor.framesize <= OMV_MAX_BLOB_FRAME, "This function is only supported on "OMV_MAX_BLOB_FRAME_STR" and smaller frames"); /* 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_MSG(src_image->bpp == 1, "This function is only supported on GRAYSCALE images"); 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 = JPEG_INIT_BUF, .pixels = xalloc(JPEG_INIT_BUF) }; jpeg_compress(image, &cimage, mp_obj_get_int(quality)); return py_image_from_struct(&cimage); }