Normalize bilteral filter sigma values.

Its easy to pick sigma now and it works great. Features get nice and
smooth.
This commit is contained in:
Kwabena W. Agyeman 2018-04-01 15:54:43 -04:00
parent 6e02030cbc
commit 6436eb15dc
4 changed files with 22 additions and 14 deletions

View File

@ -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) 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 *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++) { 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; int n = (ksize * 2) + 1;
float *gs_lut = fb_alloc(n * n * sizeof(float)); 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 y = -ksize; y <= ksize; y++) {
for (int x = -ksize; x <= ksize; x++) { 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 *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++) { 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; int n = (ksize * 2) + 1;
float *gs_lut = fb_alloc(n * n * sizeof(float)); 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 y = -ksize; y <= ksize; y++) {
for (int x = -ksize; x <= ksize; x++) { 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 *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 *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++) { 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++) { 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++) { 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; int n = (ksize * 2) + 1;
float *gs_lut = fb_alloc(n * n * sizeof(float)); 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 y = -ksize; y <= ksize; y++) {
for (int x = -ksize; x <= ksize; x++) { 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);
} }
} }

View File

@ -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 = int arg_ksize =
py_helper_arg_to_ksize(args[1]); py_helper_arg_to_ksize(args[1]);
float arg_color_sigma = 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!"); PY_ASSERT_TRUE_MSG((0 <= arg_color_sigma), "Error: 0 <= color_sigma!");
float arg_space_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!"); PY_ASSERT_TRUE_MSG((0 <= arg_space_sigma), "Error: 0 <= space_sigma!");
bool arg_threshold = bool arg_threshold =
py_helper_keyword_int(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_threshold), false); py_helper_keyword_int(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_threshold), false);

View File

@ -23,7 +23,7 @@ while(True):
# A larger value is less strict. # A larger value is less strict.
# Run the kernel on every pixel of the image. # 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 # Note that the bilateral filter can introduce image defects if you set
# color_sigma/space_sigma to aggresively. Increase the sigma values until # color_sigma/space_sigma to aggresively. Increase the sigma values until

View File

@ -23,7 +23,7 @@ while(True):
# A larger value is less strict. # A larger value is less strict.
# Run the kernel on every pixel of the image. # 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 # Note that the bilateral filter can introduce image defects if you set
# color_sigma/space_sigma to aggresively. Increase the sigma values until # color_sigma/space_sigma to aggresively. Increase the sigma values until