diff --git a/src/omv/img/imlib.h b/src/omv/img/imlib.h index 403c4e0b0..74f6e30ef 100644 --- a/src/omv/img/imlib.h +++ b/src/omv/img/imlib.h @@ -1344,7 +1344,7 @@ void imlib_rotation_corr(image_t *img, float x_rotation, float y_rotation, float zoom, float fov, float *corners); // Statistics void imlib_get_similarity(image_t *img, const char *path, image_t *other, int scalar, float *avg, float *std, float *min, float *max); -void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_t *thresholds, bool invert); +void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_t *thresholds, bool invert, image_t *other); void imlib_get_percentile(percentile_t *out, image_bpp_t bpp, histogram_t *ptr, float percentile); void imlib_get_threshold(threshold_t *out, image_bpp_t bpp, histogram_t *ptr); void imlib_get_statistics(statistics_t *out, image_bpp_t bpp, histogram_t *ptr); diff --git a/src/omv/img/shadow_removal.c b/src/omv/img/shadow_removal.c index 3d9c3bd27..5b8ab9fff 100644 --- a/src/omv/img/shadow_removal.c +++ b/src/omv/img/shadow_removal.c @@ -202,7 +202,7 @@ void imlib_remove_shadows(image_t *img, const char *path, image_t *other, int sc h.LBins = fb_alloc(h.LBinCount * sizeof(float), FB_ALLOC_NO_HINT); h.ABins = fb_alloc(h.ABinCount * sizeof(float), FB_ALLOC_NO_HINT); h.BBins = fb_alloc(h.BBinCount * sizeof(float), FB_ALLOC_NO_HINT); - imlib_get_histogram(&h, &temp_image, &r, NULL, false); + imlib_get_histogram(&h, &temp_image, &r, NULL, false, NULL); statistics_t s; imlib_get_statistics(&s, temp_image.bpp, &h); diff --git a/src/omv/img/stats.c b/src/omv/img/stats.c index 1e8f4e6dc..200b74fdc 100644 --- a/src/omv/img/stats.c +++ b/src/omv/img/stats.c @@ -146,7 +146,7 @@ void imlib_get_similarity(image_t *img, const char *path, image_t *other, int sc } #endif //IMLIB_ENABLE_GET_SIMILARITY -void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_t *thresholds, bool invert) +void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_t *thresholds, bool invert, image_t *other) { switch(ptr->bpp) { case IMAGE_BPP_BINARY: { @@ -157,27 +157,55 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_ if ((!thresholds) || (!list_size(thresholds))) { // Fast histogram code when no color thresholds list... - for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { - uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y); - for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { - int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x); - ((uint32_t *) out->LBins)[fast_floorf((pixel - COLOR_BINARY_MIN) * mult)]++; + if (!other) { + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x); + ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_BINARY_MIN) * mult)]++; // needs to be roundf + } + } + } else { + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y), *other_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(other, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) ^ IMAGE_GET_BINARY_PIXEL_FAST(other_row_ptr, x); + ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_BINARY_MIN) * mult)]++; // needs to be roundf + } } } } else { // Reset pixel count. pixel_count = 0; - for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { - color_thresholds_list_lnk_data_t lnk_data; - iterator_get(thresholds, it, &lnk_data); + if (!other) { + for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { + color_thresholds_list_lnk_data_t lnk_data; + iterator_get(thresholds, it, &lnk_data); - for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { - uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y); - for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { - int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x); - if (COLOR_THRESHOLD_BINARY(pixel, &lnk_data, invert)) { - ((uint32_t *) out->LBins)[fast_floorf((pixel - COLOR_BINARY_MIN) * mult)]++; - pixel_count++; + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x); + if (COLOR_THRESHOLD_BINARY(pixel, &lnk_data, invert)) { + ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_BINARY_MIN) * mult)]++; // needs to be roundf + pixel_count++; + } + } + } + } + } else { + for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { + color_thresholds_list_lnk_data_t lnk_data; + iterator_get(thresholds, it, &lnk_data); + + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y), *other_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(other, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) ^ IMAGE_GET_BINARY_PIXEL_FAST(other_row_ptr, x); + if (COLOR_THRESHOLD_BINARY(pixel, &lnk_data, invert)) { + ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_BINARY_MIN) * mult)]++; // needs to be roundf + pixel_count++; + } } } } @@ -200,27 +228,55 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_ if ((!thresholds) || (!list_size(thresholds))) { // Fast histogram code when no color thresholds list... - for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { - uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y); - for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { - int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x); - ((uint32_t *) out->LBins)[fast_floorf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++; + if (!other) { + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x); + ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++; // needs to be roundf + } + } + } else { + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y), *other_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(other, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = abs(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x) - IMAGE_GET_GRAYSCALE_PIXEL_FAST(other_row_ptr, x)); + ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++; // needs to be roundf + } } } } else { // Reset pixel count. pixel_count = 0; - for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { - color_thresholds_list_lnk_data_t lnk_data; - iterator_get(thresholds, it, &lnk_data); + if (!other) { + for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { + color_thresholds_list_lnk_data_t lnk_data; + iterator_get(thresholds, it, &lnk_data); - for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { - uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y); - for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { - int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x); - if (COLOR_THRESHOLD_GRAYSCALE(pixel, &lnk_data, invert)) { - ((uint32_t *) out->LBins)[fast_floorf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++; - pixel_count++; + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x); + if (COLOR_THRESHOLD_GRAYSCALE(pixel, &lnk_data, invert)) { + ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++; // needs to be roundf + pixel_count++; + } + } + } + } + } else { + for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { + color_thresholds_list_lnk_data_t lnk_data; + iterator_get(thresholds, it, &lnk_data); + + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y), *other_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(other, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = abs(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x) - IMAGE_GET_GRAYSCALE_PIXEL_FAST(other_row_ptr, x)); + if (COLOR_THRESHOLD_GRAYSCALE(pixel, &lnk_data, invert)) { + ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++; // needs to be roundf + pixel_count++; + } } } } @@ -247,31 +303,71 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_ if ((!thresholds) || (!list_size(thresholds))) { // Fast histogram code when no color thresholds list... - for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { - uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y); - for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { - int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x); - ((uint32_t *) out->LBins)[fast_floorf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++; - ((uint32_t *) out->ABins)[fast_floorf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++; - ((uint32_t *) out->BBins)[fast_floorf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++; + if (!other) { + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x); + ((uint32_t *) out->LBins)[fast_roundf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++; // needs to be roundf + ((uint32_t *) out->ABins)[fast_roundf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++; // needs to be roundf + ((uint32_t *) out->BBins)[fast_roundf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++; // needs to be roundf + } + } + } else { + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y), *other_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(other, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), other_pixel = IMAGE_GET_RGB565_PIXEL_FAST(other_row_ptr, x); + int r = abs(COLOR_RGB565_TO_R5(pixel) - COLOR_RGB565_TO_R5(other_pixel)); + int g = abs(COLOR_RGB565_TO_G6(pixel) - COLOR_RGB565_TO_G6(other_pixel)); + int b = abs(COLOR_RGB565_TO_B5(pixel) - COLOR_RGB565_TO_B5(other_pixel)); + pixel = COLOR_R5_G6_B5_TO_RGB565(r, g, b); + ((uint32_t *) out->LBins)[fast_roundf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++; // needs to be roundf + ((uint32_t *) out->ABins)[fast_roundf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++; // needs to be roundf + ((uint32_t *) out->BBins)[fast_roundf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++; // needs to be roundf + } } } } else { // Reset pixel count. pixel_count = 0; - for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { - color_thresholds_list_lnk_data_t lnk_data; - iterator_get(thresholds, it, &lnk_data); + if (!other) { + for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { + color_thresholds_list_lnk_data_t lnk_data; + iterator_get(thresholds, it, &lnk_data); - for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { - uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y); - for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { - int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x); - if (COLOR_THRESHOLD_RGB565(pixel, &lnk_data, invert)) { - ((uint32_t *) out->LBins)[fast_floorf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++; - ((uint32_t *) out->ABins)[fast_floorf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++; - ((uint32_t *) out->BBins)[fast_floorf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++; - pixel_count++; + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x); + if (COLOR_THRESHOLD_RGB565(pixel, &lnk_data, invert)) { + ((uint32_t *) out->LBins)[fast_roundf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++; // needs to be roundf + ((uint32_t *) out->ABins)[fast_roundf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++; // needs to be roundf + ((uint32_t *) out->BBins)[fast_roundf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++; // needs to be roundf + pixel_count++; + } + } + } + } + } else { + for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { + color_thresholds_list_lnk_data_t lnk_data; + iterator_get(thresholds, it, &lnk_data); + + for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { + uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y), *other_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(other, y); + for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { + int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), other_pixel = IMAGE_GET_RGB565_PIXEL_FAST(other_row_ptr, x); + int r = abs(COLOR_RGB565_TO_R5(pixel) - COLOR_RGB565_TO_R5(other_pixel)); + int g = abs(COLOR_RGB565_TO_G6(pixel) - COLOR_RGB565_TO_G6(other_pixel)); + int b = abs(COLOR_RGB565_TO_B5(pixel) - COLOR_RGB565_TO_B5(other_pixel)); + pixel = COLOR_R5_G6_B5_TO_RGB565(r, g, b); + if (COLOR_THRESHOLD_RGB565(pixel, &lnk_data, invert)) { + ((uint32_t *) out->LBins)[fast_roundf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++; // needs to be roundf + ((uint32_t *) out->ABins)[fast_roundf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++; // needs to be roundf + ((uint32_t *) out->BBins)[fast_roundf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++; // needs to be roundf + pixel_count++; + } } } } diff --git a/src/omv/py/py_image.c b/src/omv/py/py_image.c index 75fbd8740..52e407c0b 100644 --- a/src/omv/py/py_image.c +++ b/src/omv/py/py_image.c @@ -1943,17 +1943,17 @@ STATIC mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *args, mp_map_t float arg_y_scale = py_helper_keyword_float(n_args, args, offset + 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_y_scale), 1.0f); PY_ASSERT_TRUE_MSG((0.0f <= arg_y_scale), "Error: 0.0 <= y_scale!"); - + int arg_alpha = py_helper_keyword_int(n_args, args, offset + 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_alpha), 256); PY_ASSERT_TRUE_MSG((0 <= arg_alpha) && (arg_alpha <= 256), "Error: 0 <= alpha <= 256!"); image_t *arg_msk = py_helper_keyword_to_image_mutable_mask(n_args, args, offset + 3, kw_args); - + const uint16_t *color_palette = NULL; { int palette; - + if (py_helper_keyword_int_maybe(n_args, args, offset + 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color_palette), &palette)) { if (palette == COLOR_PALETTE_RAINBOW) { color_palette = rainbow_table; @@ -1964,7 +1964,7 @@ STATIC mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *args, mp_map_t } } else { image_t *arg_color_palette = py_helper_keyword_to_image_mutable_color_palette(n_args, args, offset + 4, kw_args); - + if (arg_color_palette) { if (arg_color_palette->bpp != IMAGE_BPP_RGB565) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Color palette must be an RGB565 format image!")); if ((arg_color_palette->w * arg_color_palette->h) != 256) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Color palette image must have 256 pixels!")); @@ -1985,7 +1985,7 @@ STATIC mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *args, mp_map_t const uint8_t *alpha_palette = NULL; { image_t *arg_alpha_palette = py_helper_keyword_to_image_mutable_alpha_palette(n_args, args, offset + 5, kw_args); - + if (arg_alpha_palette) { if (arg_other->bpp != IMAGE_BPP_GRAYSCALE) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Can only specify an alpha palette when passing a grayscale image!")); if (arg_alpha_palette->bpp != IMAGE_BPP_GRAYSCALE) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Alpha palette must be an grayscale format image!")); @@ -2007,7 +2007,7 @@ STATIC mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *args, mp_map_t } imlib_draw_image(arg_img, arg_other, arg_cx, arg_cy, arg_x_scale, arg_y_scale, arg_alpha, arg_msk, color_palette, alpha_palette, hint); - + return args[0]; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_image_obj, 3, py_image_draw_image); @@ -4063,6 +4063,7 @@ static mp_obj_t py_image_get_histogram(uint n_args, const mp_obj_t *args, mp_map list_init(&thresholds, sizeof(color_thresholds_list_lnk_data_t)); py_helper_keyword_thresholds(n_args, args, 1, kw_args, &thresholds); bool invert = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_invert), false); + image_t *other = py_helper_keyword_to_image_mutable(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_difference), NULL); rectangle_t roi; py_helper_keyword_rectangle_roi(arg_img, n_args, args, 3, kw_args, &roi); @@ -4081,7 +4082,7 @@ static mp_obj_t py_image_get_histogram(uint n_args, const mp_obj_t *args, mp_map hist.LBins = fb_alloc(hist.LBinCount * sizeof(float), FB_ALLOC_NO_HINT); hist.ABins = NULL; hist.BBins = NULL; - imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert); + imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert, other); list_free(&thresholds); break; } @@ -4097,7 +4098,7 @@ static mp_obj_t py_image_get_histogram(uint n_args, const mp_obj_t *args, mp_map hist.LBins = fb_alloc(hist.LBinCount * sizeof(float), FB_ALLOC_NO_HINT); hist.ABins = NULL; hist.BBins = NULL; - imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert); + imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert, other); list_free(&thresholds); break; } @@ -4121,7 +4122,7 @@ static mp_obj_t py_image_get_histogram(uint n_args, const mp_obj_t *args, mp_map hist.LBins = fb_alloc(hist.LBinCount * sizeof(float), FB_ALLOC_NO_HINT); hist.ABins = fb_alloc(hist.ABinCount * sizeof(float), FB_ALLOC_NO_HINT); hist.BBins = fb_alloc(hist.BBinCount * sizeof(float), FB_ALLOC_NO_HINT); - imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert); + imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert, other); list_free(&thresholds); break; } @@ -4164,6 +4165,7 @@ static mp_obj_t py_image_get_statistics(uint n_args, const mp_obj_t *args, mp_ma list_init(&thresholds, sizeof(color_thresholds_list_lnk_data_t)); py_helper_keyword_thresholds(n_args, args, 1, kw_args, &thresholds); bool invert = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_invert), false); + image_t *other = py_helper_keyword_to_image_mutable(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_difference), NULL); rectangle_t roi; py_helper_keyword_rectangle_roi(arg_img, n_args, args, 3, kw_args, &roi); @@ -4182,7 +4184,7 @@ static mp_obj_t py_image_get_statistics(uint n_args, const mp_obj_t *args, mp_ma hist.LBins = fb_alloc(hist.LBinCount * sizeof(float), FB_ALLOC_NO_HINT); hist.ABins = NULL; hist.BBins = NULL; - imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert); + imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert, other); list_free(&thresholds); break; } @@ -4198,7 +4200,7 @@ static mp_obj_t py_image_get_statistics(uint n_args, const mp_obj_t *args, mp_ma hist.LBins = fb_alloc(hist.LBinCount * sizeof(float), FB_ALLOC_NO_HINT); hist.ABins = NULL; hist.BBins = NULL; - imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert); + imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert, other); list_free(&thresholds); break; } @@ -4222,7 +4224,7 @@ static mp_obj_t py_image_get_statistics(uint n_args, const mp_obj_t *args, mp_ma hist.LBins = fb_alloc(hist.LBinCount * sizeof(float), FB_ALLOC_NO_HINT); hist.ABins = fb_alloc(hist.ABinCount * sizeof(float), FB_ALLOC_NO_HINT); hist.BBins = fb_alloc(hist.BBinCount * sizeof(float), FB_ALLOC_NO_HINT); - imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert); + imlib_get_histogram(&hist, arg_img, &roi, &thresholds, invert, other); list_free(&thresholds); break; }