From 6436eb15dc9fadcd870b86f7eed949ec1e590af4 Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Sun, 1 Apr 2018 15:54:43 -0400 Subject: [PATCH] Normalize bilteral filter sigma values. Its easy to pick sigma now and it works great. Features get nice and smooth. --- src/omv/img/filter.c | 28 ++++++++++++------- src/omv/py/py_image.c | 4 +-- .../color_bilateral_filter.py | 2 +- .../grayscale_bilateral_filter.py | 2 +- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/omv/img/filter.c b/src/omv/img/filter.c index a3ad8efbe..aa3de9a89 100644 --- a/src/omv/img/filter.c +++ b/src/omv/img/filter.c @@ -1122,9 +1122,9 @@ void imlib_morph(image_t *img, const int ksize, const int *krn, const float m, c } } -static float gaussian(int x, float sigma) +static float gaussian(float x, float sigma) { - return fast_expf((x * x) / (-2.0f * sigma * sigma)) / (sigma * 2.506628f); // sqrt(2 * PI) + return fast_expf((x * x) / (-2.0f * sigma * sigma)) / (fabsf(sigma) * 2.506628f); // sqrt(2 * PI) } static float distance(int x, int y) @@ -1146,16 +1146,18 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl float *gi_lut = fb_alloc((COLOR_BINARY_MAX - COLOR_BINARY_MIN + 1) * sizeof(float)); + float max_color = IM_DIV(1.0f, COLOR_BINARY_MAX - COLOR_BINARY_MIN); for (int i = COLOR_BINARY_MIN; i <= COLOR_BINARY_MAX; i++) { - gi_lut[i] = gaussian(i, color_sigma); + gi_lut[i] = gaussian(i * max_color, color_sigma); } int n = (ksize * 2) + 1; float *gs_lut = fb_alloc(n * n * sizeof(float)); + float max_space = IM_DIV(1.0f, distance(ksize, ksize)); for (int y = -ksize; y <= ksize; y++) { for (int x = -ksize; x <= ksize; x++) { - gs_lut[(n * (y + ksize)) + (x + ksize)] = gaussian(distance(x, y), space_sigma); + gs_lut[(n * (y + ksize)) + (x + ksize)] = gaussian(distance(x, y) * max_space, space_sigma); } } @@ -1222,16 +1224,18 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl float *gi_lut = fb_alloc((COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN + 1) * sizeof(float)); + float max_color = IM_DIV(1.0f, COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN); for (int i = COLOR_GRAYSCALE_MIN; i <= COLOR_GRAYSCALE_MAX; i++) { - gi_lut[i] = gaussian(i, color_sigma); + gi_lut[i] = gaussian(i * max_color, color_sigma); } int n = (ksize * 2) + 1; float *gs_lut = fb_alloc(n * n * sizeof(float)); + float max_space = IM_DIV(1.0f, distance(ksize, ksize)); for (int y = -ksize; y <= ksize; y++) { for (int x = -ksize; x <= ksize; x++) { - gs_lut[(n * (y + ksize)) + (x + ksize)] = gaussian(distance(x, y), space_sigma); + gs_lut[(n * (y + ksize)) + (x + ksize)] = gaussian(distance(x, y) * max_space, space_sigma); } } @@ -1300,24 +1304,28 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl float *g_gi_lut = fb_alloc((COLOR_G6_MAX - COLOR_G6_MIN + 1) * sizeof(float)); float *b_gi_lut = fb_alloc((COLOR_B5_MAX - COLOR_B5_MIN + 1) * sizeof(float)); + float r_max_color = IM_DIV(1.0f, COLOR_R5_MAX - COLOR_R5_MIN); for (int i = COLOR_R5_MIN; i <= COLOR_R5_MAX; i++) { - r_gi_lut[i] = gaussian(i, color_sigma); + r_gi_lut[i] = gaussian(i * r_max_color, color_sigma); } + float g_max_color = IM_DIV(1.0f, COLOR_G6_MAX - COLOR_G6_MIN); for (int i = COLOR_G6_MIN; i <= COLOR_G6_MAX; i++) { - g_gi_lut[i] = gaussian(i, color_sigma); + g_gi_lut[i] = gaussian(i * g_max_color, color_sigma); } + float b_max_color = IM_DIV(1.0f, COLOR_B5_MAX - COLOR_B5_MIN); for (int i = COLOR_B5_MIN; i <= COLOR_B5_MAX; i++) { - b_gi_lut[i] = gaussian(i, color_sigma); + b_gi_lut[i] = gaussian(i * b_max_color, color_sigma); } int n = (ksize * 2) + 1; float *gs_lut = fb_alloc(n * n * sizeof(float)); + float max_space = IM_DIV(1.0f, distance(ksize, ksize)); for (int y = -ksize; y <= ksize; y++) { for (int x = -ksize; x <= ksize; x++) { - gs_lut[(n * (y + ksize)) + (x + ksize)] = gaussian(distance(x, y), space_sigma); + gs_lut[(n * (y + ksize)) + (x + ksize)] = gaussian(distance(x, y) * max_space, space_sigma); } } diff --git a/src/omv/py/py_image.c b/src/omv/py/py_image.c index a7cac73c0..5d5d0d731 100644 --- a/src/omv/py/py_image.c +++ b/src/omv/py/py_image.c @@ -1997,10 +1997,10 @@ STATIC mp_obj_t py_image_bilateral(uint n_args, const mp_obj_t *args, mp_map_t * int arg_ksize = py_helper_arg_to_ksize(args[1]); float arg_color_sigma = - py_helper_keyword_float(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color_sigma), 6); + py_helper_keyword_float(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color_sigma), 0.1); PY_ASSERT_TRUE_MSG((0 <= arg_color_sigma), "Error: 0 <= color_sigma!"); float arg_space_sigma = - py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_space_sigma), 6); + py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_space_sigma), 1); PY_ASSERT_TRUE_MSG((0 <= arg_space_sigma), "Error: 0 <= space_sigma!"); bool arg_threshold = py_helper_keyword_int(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_threshold), false); diff --git a/usr/examples/04-Image-Filters/color_bilateral_filter.py b/usr/examples/04-Image-Filters/color_bilateral_filter.py index 1e1c24e6c..1bdbbb7eb 100644 --- a/usr/examples/04-Image-Filters/color_bilateral_filter.py +++ b/usr/examples/04-Image-Filters/color_bilateral_filter.py @@ -23,7 +23,7 @@ while(True): # A larger value is less strict. # Run the kernel on every pixel of the image. - img.bilateral(3, color_sigma=5, space_sigma=5) + img.bilateral(3, color_sigma=0.1, space_sigma=1) # Note that the bilateral filter can introduce image defects if you set # color_sigma/space_sigma to aggresively. Increase the sigma values until diff --git a/usr/examples/04-Image-Filters/grayscale_bilateral_filter.py b/usr/examples/04-Image-Filters/grayscale_bilateral_filter.py index 35a3f9427..6b3a67b21 100644 --- a/usr/examples/04-Image-Filters/grayscale_bilateral_filter.py +++ b/usr/examples/04-Image-Filters/grayscale_bilateral_filter.py @@ -23,7 +23,7 @@ while(True): # A larger value is less strict. # Run the kernel on every pixel of the image. - img.bilateral(3, color_sigma=20, space_sigma=20) + img.bilateral(3, color_sigma=0.1, space_sigma=1) # Note that the bilateral filter can introduce image defects if you set # color_sigma/space_sigma to aggresively. Increase the sigma values until