diff --git a/src/omv/imlib/imlib.h b/src/omv/imlib/imlib.h index b224dc4a0..b93353ffe 100644 --- a/src/omv/imlib/imlib.h +++ b/src/omv/imlib/imlib.h @@ -1338,7 +1338,9 @@ void imlib_flood_fill(image_t *img, int x, int y, float seed_threshold, float floating_threshold, int c, bool invert, bool clear_background, image_t *mask); // ISP Functions -void imlib_awb(image_t *img, bool max); +void imlib_awb_rgb_avg(image_t *img, uint32_t *r_out, uint32_t *g_out, uint32_t *b_out); +void imlib_awb_rgb_max(image_t *img, uint32_t *r_out, uint32_t *g_out, uint32_t *b_out); +void imlib_awb(image_t *img, uint32_t r_out, uint32_t g_out, uint32_t b_out); void imlib_ccm(image_t *img, float *ccm, bool offset); void imlib_gamma(image_t *img, float gamma, float scale, float offset); // Binary Functions diff --git a/src/omv/imlib/isp.c b/src/omv/imlib/isp.c index 3b0ad7b40..ae5f0422c 100644 --- a/src/omv/imlib/isp.c +++ b/src/omv/imlib/isp.c @@ -12,7 +12,7 @@ #ifdef IMLIB_ENABLE_ISP_OPS -static void imlib_rgb_avg(image_t *img, uint32_t *r_out, uint32_t *g_out, uint32_t *b_out) { +void imlib_awb_rgb_avg(image_t *img, uint32_t *r_out, uint32_t *g_out, uint32_t *b_out) { uint32_t area = img->w * img->h; uint32_t r_acc = 0, g_acc = 0, b_acc = 0; @@ -305,7 +305,7 @@ static void imlib_rgb_avg(image_t *img, uint32_t *r_out, uint32_t *g_out, uint32 } } -static void imlib_rgb_max(image_t *img, uint32_t *r_out, uint32_t *g_out, uint32_t *b_out) { +void imlib_awb_rgb_max(image_t *img, uint32_t *r_out, uint32_t *g_out, uint32_t *b_out) { uint32_t area = img->w * img->h; uint32_t r_acc = 0, g_acc = 0, b_acc = 0; @@ -712,15 +712,8 @@ static void imlib_rgb_max(image_t *img, uint32_t *r_out, uint32_t *g_out, uint32 } } -void imlib_awb(image_t *img, bool max) { +void imlib_awb(image_t *img, uint32_t r_out, uint32_t g_out, uint32_t b_out) { uint32_t area = img->w * img->h; - uint32_t r_out, g_out, b_out; - - if (max) { - imlib_rgb_max(img, &r_out, &g_out, &b_out); // white patch algorithm - } else { - imlib_rgb_avg(img, &r_out, &g_out, &b_out); // gray world algorithm - } int red_gain = IM_DIV(g_out * 32, r_out); red_gain = IM_MIN(red_gain, 128); @@ -1049,7 +1042,7 @@ void imlib_ccm(image_t *img, float *ccm, bool offset) { } void imlib_gamma(image_t *img, float gamma, float contrast, float brightness) { - gamma = IM_DIV(1.0, gamma); + gamma = IM_DIV(1.0f, gamma); switch (img->pixfmt) { case PIXFORMAT_BINARY: { float pScale = COLOR_BINARY_MAX - COLOR_BINARY_MIN; diff --git a/src/omv/modules/py_image.c b/src/omv/modules/py_image.c index 8834ae3b3..0296b1a07 100644 --- a/src/omv/modules/py_image.c +++ b/src/omv/modules/py_image.c @@ -1849,14 +1849,27 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_flood_fill_obj, 2, py_image_flood_fil // ISP Methods ////////////// -STATIC mp_obj_t py_awb(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { - image_t *arg_img = - py_helper_arg_to_image(args[0], ARG_IMAGE_UNCOMPRESSED); - bool arg_max = - py_helper_keyword_float(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_max), false); +STATIC mp_obj_t py_awb(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_max }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_max, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; - imlib_awb(arg_img, arg_max); - return args[0]; + // Parse args. + image_t *image = py_helper_arg_to_image(pos_args[0], ARG_IMAGE_UNCOMPRESSED); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + uint32_t r_out, g_out, b_out; + + if (args[ARG_max].u_bool) { + imlib_awb_rgb_max(image, &r_out, &g_out, &b_out); // white patch algorithm + } else { + imlib_awb_rgb_avg(image, &r_out, &g_out, &b_out); // gray world algorithm + } + + imlib_awb(image, r_out, g_out, b_out); + return pos_args[0]; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_awb_obj, 1, py_awb); @@ -1882,20 +1895,27 @@ STATIC mp_obj_t py_ccm(mp_obj_t img_obj, mp_obj_t ccm_obj) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_ccm_obj, py_ccm); -STATIC mp_obj_t py_image_gamma(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { - image_t *arg_img = - py_helper_arg_to_image(args[0], ARG_IMAGE_UNCOMPRESSED); - float arg_gamma = - py_helper_keyword_float(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gamma), 1.0f); - float arg_contrast = - py_helper_keyword_float(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_contrast), 1.0f); - float arg_brightness = - py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_brightness), 0.0f); +STATIC mp_obj_t py_image_gamma(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_gamma, ARG_contrast, ARG_brightness }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_gamma, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE } }, + { MP_QSTR_contrast, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = MP_ROM_NONE } }, + { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = MP_ROM_NONE } }, + }; + + // Parse args. + image_t *image = py_helper_arg_to_image(pos_args[0], ARG_IMAGE_UNCOMPRESSED); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + float gamma = py_helper_arg_to_float(args[ARG_gamma].u_obj, 1.0f); + float contrast = py_helper_arg_to_float(args[ARG_contrast].u_obj, 1.0f); + float brightness = py_helper_arg_to_float(args[ARG_brightness].u_obj, 0.0f); fb_alloc_mark(); - imlib_gamma(arg_img, arg_gamma, arg_contrast, arg_brightness); + imlib_gamma(image, gamma, contrast, brightness); fb_alloc_free_till_mark(); - return args[0]; + return pos_args[0]; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_gamma_obj, 1, py_image_gamma);