mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Add bilateral filtering support
Runs faster than median filtering with a large kernel size. That said, if sigma is set to low for the particular scene you can get corrupted pixels if there's too much change in a particular kernel area. Tried a few things to filter this out but was not successful. Not sure how to fix... but, turning the sigma up hides the issue. It has something to do with zeros in the luts used to speed the algorithm up causing instability.
This commit is contained in:
parent
c3c40680f5
commit
09c9d97a70
@ -747,7 +747,7 @@ void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool thres
|
|||||||
}
|
}
|
||||||
|
|
||||||
int min = COLOR_BINARY_MAX, max = COLOR_BINARY_MIN;
|
int min = COLOR_BINARY_MAX, max = COLOR_BINARY_MIN;
|
||||||
|
|
||||||
for (int j = -ksize; j <= ksize; j++) {
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
|
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
|
||||||
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
||||||
@ -1107,3 +1107,285 @@ void imlib_morph(image_t *img, const int ksize, const int *krn, const float m, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float gaussian(int x, float sigma)
|
||||||
|
{
|
||||||
|
return fast_expf((x * x) / (-2.0f * sigma * sigma)) / (sigma * 2.506628f); // sqrt(2 * PI)
|
||||||
|
}
|
||||||
|
|
||||||
|
static float distance(int x, int y)
|
||||||
|
{
|
||||||
|
return fast_sqrtf((x * x) + (y * y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, float space_sigma, bool threshold, int offset, bool invert, image_t *mask)
|
||||||
|
{
|
||||||
|
int brows = ksize + 1;
|
||||||
|
image_t buf;
|
||||||
|
buf.w = img->w;
|
||||||
|
buf.h = brows;
|
||||||
|
buf.bpp = img->bpp;
|
||||||
|
|
||||||
|
switch(img->bpp) {
|
||||||
|
case IMAGE_BPP_BINARY: {
|
||||||
|
buf.data = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(img) * brows);
|
||||||
|
|
||||||
|
float *gi_lut = fb_alloc((COLOR_BINARY_MAX - COLOR_BINARY_MIN + 1) * sizeof(float));
|
||||||
|
|
||||||
|
for (int i = COLOR_BINARY_MIN; i <= COLOR_BINARY_MAX; i++) {
|
||||||
|
gi_lut[i] = gaussian(i, color_sigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = (ksize * 2) + 1;
|
||||||
|
float *gs_lut = fb_alloc(n * n * sizeof(float));
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0, yy = img->h; y < yy; y++) {
|
||||||
|
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y);
|
||||||
|
uint32_t *buf_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&buf, (y % brows));
|
||||||
|
|
||||||
|
for (int x = 0, xx = img->w; x < xx; x++) {
|
||||||
|
if (mask && (!image_get_mask_pixel(mask, x, y))) {
|
||||||
|
IMAGE_PUT_BINARY_PIXEL_FAST(buf_row_ptr, x, IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x));
|
||||||
|
continue; // Short circuit.
|
||||||
|
}
|
||||||
|
|
||||||
|
int this_pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x);
|
||||||
|
float i_acc = 0, w_acc = 0;
|
||||||
|
|
||||||
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
|
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
|
||||||
|
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
||||||
|
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
|
||||||
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
|
float w = gi_lut[abs(this_pixel - pixel)] * gs_lut[(n * (j + ksize)) + (k + ksize)];
|
||||||
|
i_acc += pixel * w;
|
||||||
|
w_acc += w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pixel = fast_roundf(IM_MIN(IM_DIV(i_acc, w_acc), COLOR_BINARY_MAX));
|
||||||
|
|
||||||
|
if (threshold) {
|
||||||
|
if (((pixel - offset) < IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x)) ^ invert) {
|
||||||
|
pixel = COLOR_BINARY_MAX;
|
||||||
|
} else {
|
||||||
|
pixel = COLOR_BINARY_MIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IMAGE_PUT_BINARY_PIXEL_FAST(buf_row_ptr, x, pixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= ksize) { // Transfer buffer lines...
|
||||||
|
memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, (y - ksize)),
|
||||||
|
IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&buf, ((y - ksize) % brows)),
|
||||||
|
IMAGE_BINARY_LINE_LEN_BYTES(img));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy any remaining lines from the buffer image...
|
||||||
|
for (int y = img->h - ksize, yy = img->h; y < yy; y++) {
|
||||||
|
memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y),
|
||||||
|
IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&buf, (y % brows)),
|
||||||
|
IMAGE_BINARY_LINE_LEN_BYTES(img));
|
||||||
|
}
|
||||||
|
|
||||||
|
fb_free();
|
||||||
|
fb_free();
|
||||||
|
fb_free();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_GRAYSCALE: {
|
||||||
|
buf.data = fb_alloc(IMAGE_GRAYSCALE_LINE_LEN_BYTES(img) * brows);
|
||||||
|
|
||||||
|
float *gi_lut = fb_alloc((COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN + 1) * sizeof(float));
|
||||||
|
|
||||||
|
for (int i = COLOR_GRAYSCALE_MIN; i <= COLOR_GRAYSCALE_MAX; i++) {
|
||||||
|
gi_lut[i] = gaussian(i, color_sigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = (ksize * 2) + 1;
|
||||||
|
float *gs_lut = fb_alloc(n * n * sizeof(float));
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0, yy = img->h; y < yy; y++) {
|
||||||
|
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y);
|
||||||
|
uint8_t *buf_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&buf, (y % brows));
|
||||||
|
|
||||||
|
for (int x = 0, xx = img->w; x < xx; x++) {
|
||||||
|
if (mask && (!image_get_mask_pixel(mask, x, y))) {
|
||||||
|
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(buf_row_ptr, x, IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x));
|
||||||
|
continue; // Short circuit.
|
||||||
|
}
|
||||||
|
|
||||||
|
int this_pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x);
|
||||||
|
float i_acc = 0, w_acc = 0;
|
||||||
|
|
||||||
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
|
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
|
||||||
|
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
||||||
|
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
|
||||||
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
|
float w = gi_lut[abs(this_pixel - pixel)] * gs_lut[(n * (j + ksize)) + (k + ksize)];
|
||||||
|
i_acc += pixel * w;
|
||||||
|
w_acc += w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pixel = fast_roundf(IM_MIN(IM_DIV(i_acc, w_acc), COLOR_GRAYSCALE_MAX));
|
||||||
|
|
||||||
|
if (threshold) {
|
||||||
|
if (((pixel - offset) < IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)) ^ invert) {
|
||||||
|
pixel = COLOR_GRAYSCALE_BINARY_MAX;
|
||||||
|
} else {
|
||||||
|
pixel = COLOR_GRAYSCALE_BINARY_MIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(buf_row_ptr, x, pixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= ksize) { // Transfer buffer lines...
|
||||||
|
memcpy(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, (y - ksize)),
|
||||||
|
IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&buf, ((y - ksize) % brows)),
|
||||||
|
IMAGE_GRAYSCALE_LINE_LEN_BYTES(img));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy any remaining lines from the buffer image...
|
||||||
|
for (int y = img->h - ksize, yy = img->h; y < yy; y++) {
|
||||||
|
memcpy(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y),
|
||||||
|
IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&buf, (y % brows)),
|
||||||
|
IMAGE_GRAYSCALE_LINE_LEN_BYTES(img));
|
||||||
|
}
|
||||||
|
|
||||||
|
fb_free();
|
||||||
|
fb_free();
|
||||||
|
fb_free();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_RGB565: {
|
||||||
|
buf.data = fb_alloc(IMAGE_RGB565_LINE_LEN_BYTES(img) * brows);
|
||||||
|
|
||||||
|
float *r_gi_lut = fb_alloc((COLOR_R5_MAX - COLOR_R5_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));
|
||||||
|
|
||||||
|
for (int i = COLOR_R5_MIN; i <= COLOR_R5_MAX; i++) {
|
||||||
|
r_gi_lut[i] = gaussian(i, color_sigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = COLOR_G6_MIN; i <= COLOR_G6_MAX; i++) {
|
||||||
|
g_gi_lut[i] = gaussian(i, color_sigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = COLOR_B5_MIN; i <= COLOR_B5_MAX; i++) {
|
||||||
|
b_gi_lut[i] = gaussian(i, color_sigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = (ksize * 2) + 1;
|
||||||
|
float *gs_lut = fb_alloc(n * n * sizeof(float));
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0, yy = img->h; y < yy; y++) {
|
||||||
|
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y);
|
||||||
|
uint16_t *buf_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&buf, (y % brows));
|
||||||
|
|
||||||
|
for (int x = 0, xx = img->w; x < xx; x++) {
|
||||||
|
if (mask && (!image_get_mask_pixel(mask, x, y))) {
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(buf_row_ptr, x, IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x));
|
||||||
|
continue; // Short circuit.
|
||||||
|
}
|
||||||
|
|
||||||
|
int this_pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
|
||||||
|
int r_this_pixel = COLOR_RGB565_TO_R5(this_pixel);
|
||||||
|
int g_this_pixel = COLOR_RGB565_TO_G6(this_pixel);
|
||||||
|
int b_this_pixel = COLOR_RGB565_TO_B5(this_pixel);
|
||||||
|
float r_i_acc = 0, r_w_acc = 0;
|
||||||
|
float g_i_acc = 0, g_w_acc = 0;
|
||||||
|
float b_i_acc = 0, b_w_acc = 0;
|
||||||
|
|
||||||
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
|
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
|
||||||
|
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
||||||
|
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
|
||||||
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
|
int r_pixel = COLOR_RGB565_TO_R5(pixel);
|
||||||
|
int g_pixel = COLOR_RGB565_TO_G6(pixel);
|
||||||
|
int b_pixel = COLOR_RGB565_TO_B5(pixel);
|
||||||
|
float gs = gs_lut[(n * (j + ksize)) + (k + ksize)];
|
||||||
|
float r_w = r_gi_lut[abs(r_this_pixel - r_pixel)] * gs;
|
||||||
|
float g_w = g_gi_lut[abs(g_this_pixel - g_pixel)] * gs;
|
||||||
|
float b_w = b_gi_lut[abs(b_this_pixel - b_pixel)] * gs;
|
||||||
|
r_i_acc += r_pixel * r_w;
|
||||||
|
r_w_acc += r_w;
|
||||||
|
g_i_acc += g_pixel * g_w;
|
||||||
|
g_w_acc += g_w;
|
||||||
|
b_i_acc += b_pixel * b_w;
|
||||||
|
b_w_acc += b_w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pixel = COLOR_R5_G6_B5_TO_RGB565(fast_roundf(IM_MIN(IM_DIV(r_i_acc, r_w_acc), COLOR_R5_MAX)),
|
||||||
|
fast_roundf(IM_MIN(IM_DIV(g_i_acc, g_w_acc), COLOR_G6_MAX)),
|
||||||
|
fast_roundf(IM_MIN(IM_DIV(b_i_acc, b_w_acc), COLOR_B5_MAX)));
|
||||||
|
|
||||||
|
if (threshold) {
|
||||||
|
if (((COLOR_RGB565_TO_Y(pixel) - offset) < COLOR_RGB565_TO_Y(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x))) ^ invert) {
|
||||||
|
pixel = COLOR_RGB565_BINARY_MAX;
|
||||||
|
} else {
|
||||||
|
pixel = COLOR_RGB565_BINARY_MIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(buf_row_ptr, x, pixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= ksize) { // Transfer buffer lines...
|
||||||
|
memcpy(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, (y - ksize)),
|
||||||
|
IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&buf, ((y - ksize) % brows)),
|
||||||
|
IMAGE_RGB565_LINE_LEN_BYTES(img));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy any remaining lines from the buffer image...
|
||||||
|
for (int y = img->h - ksize, yy = img->h; y < yy; y++) {
|
||||||
|
memcpy(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y),
|
||||||
|
IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&buf, (y % brows)),
|
||||||
|
IMAGE_RGB565_LINE_LEN_BYTES(img));
|
||||||
|
}
|
||||||
|
|
||||||
|
fb_free();
|
||||||
|
fb_free();
|
||||||
|
fb_free();
|
||||||
|
fb_free();
|
||||||
|
fb_free();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1250,6 +1250,7 @@ void imlib_median_filter(image_t *img, const int ksize, float percentile, bool t
|
|||||||
void imlib_mode_filter(image_t *img, const int ksize, bool threshold, int offset, bool invert, image_t *mask);
|
void imlib_mode_filter(image_t *img, const int ksize, bool threshold, int offset, bool invert, image_t *mask);
|
||||||
void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool threshold, int offset, bool invert, image_t *mask);
|
void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool threshold, int offset, bool invert, image_t *mask);
|
||||||
void imlib_morph(image_t *img, const int ksize, const int *krn, const float m, const int b, bool threshold, int offset, bool invert, image_t *mask);
|
void imlib_morph(image_t *img, const int ksize, const int *krn, const float m, const int b, bool threshold, int offset, bool invert, image_t *mask);
|
||||||
|
void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, float space_sigma, bool threshold, int offset, bool invert, image_t *mask);
|
||||||
// Image Correction
|
// Image Correction
|
||||||
void imlib_logpolar_int(image_t *dst, image_t *src, rectangle_t *roi, bool linear, bool reverse); // helper/internal
|
void imlib_logpolar_int(image_t *dst, image_t *src, rectangle_t *roi, bool linear, bool reverse); // helper/internal
|
||||||
void imlib_logpolar(image_t *img, bool linear, bool reverse);
|
void imlib_logpolar(image_t *img, bool linear, bool reverse);
|
||||||
|
|||||||
@ -1981,6 +1981,34 @@ STATIC mp_obj_t py_image_laplacian(uint n_args, const mp_obj_t *args, mp_map_t *
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_laplacian_obj, 2, py_image_laplacian);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_laplacian_obj, 2, py_image_laplacian);
|
||||||
|
|
||||||
|
STATIC mp_obj_t py_image_bilateral(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
|
{
|
||||||
|
image_t *arg_img =
|
||||||
|
py_helper_arg_to_image_mutable(args[0]);
|
||||||
|
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_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_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);
|
||||||
|
int arg_offset =
|
||||||
|
py_helper_keyword_int(n_args, args, 5, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_offset), 0);
|
||||||
|
bool arg_invert =
|
||||||
|
py_helper_keyword_int(n_args, args, 6, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_invert), false);
|
||||||
|
image_t *arg_msk =
|
||||||
|
py_helper_keyword_to_image_mutable_mask(n_args, args, 7, kw_args);
|
||||||
|
|
||||||
|
fb_alloc_mark();
|
||||||
|
imlib_bilateral_filter(arg_img, arg_ksize, arg_color_sigma, arg_space_sigma, arg_threshold, arg_offset, arg_invert, arg_msk);
|
||||||
|
fb_alloc_free_till_mark();
|
||||||
|
return args[0];
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_bilateral_obj, 2, py_image_bilateral);
|
||||||
|
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
// Shadow Removal Methods
|
// Shadow Removal Methods
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
@ -4909,6 +4937,7 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
|||||||
{MP_ROM_QSTR(MP_QSTR_gaussian), MP_ROM_PTR(&py_image_gaussian_obj)},
|
{MP_ROM_QSTR(MP_QSTR_gaussian), MP_ROM_PTR(&py_image_gaussian_obj)},
|
||||||
{MP_ROM_QSTR(MP_QSTR_gaussian_blur), MP_ROM_PTR(&py_image_gaussian_obj)},
|
{MP_ROM_QSTR(MP_QSTR_gaussian_blur), MP_ROM_PTR(&py_image_gaussian_obj)},
|
||||||
{MP_ROM_QSTR(MP_QSTR_laplacian), MP_ROM_PTR(&py_image_laplacian_obj)},
|
{MP_ROM_QSTR(MP_QSTR_laplacian), MP_ROM_PTR(&py_image_laplacian_obj)},
|
||||||
|
{MP_ROM_QSTR(MP_QSTR_bilateral), MP_ROM_PTR(&py_image_bilateral_obj)},
|
||||||
/* Shadow Removal Methods */
|
/* Shadow Removal Methods */
|
||||||
#ifdef IMLIB_ENABLE_REMOVE_SHADOWS
|
#ifdef IMLIB_ENABLE_REMOVE_SHADOWS
|
||||||
{MP_ROM_QSTR(MP_QSTR_remove_shadows), MP_ROM_PTR(&py_image_remove_shadows_obj)},
|
{MP_ROM_QSTR(MP_QSTR_remove_shadows), MP_ROM_PTR(&py_image_remove_shadows_obj)},
|
||||||
|
|||||||
@ -536,6 +536,15 @@ Q(sharpen)
|
|||||||
// duplicate Q(invert)
|
// duplicate Q(invert)
|
||||||
// duplicate Q(mask)
|
// duplicate Q(mask)
|
||||||
|
|
||||||
|
// Bilateral
|
||||||
|
Q(bilateral)
|
||||||
|
Q(color_sigma)
|
||||||
|
Q(space_sigma)
|
||||||
|
// duplicate Q(threshold)
|
||||||
|
// duplicate Q(offset)
|
||||||
|
// duplicate Q(invert)
|
||||||
|
// duplicate Q(mask)
|
||||||
|
|
||||||
// Shadow Removal
|
// Shadow Removal
|
||||||
Q(remove_shadows)
|
Q(remove_shadows)
|
||||||
|
|
||||||
|
|||||||
33
usr/examples/04-Image-Filters/color_bilateral_filter.py
Normal file
33
usr/examples/04-Image-Filters/color_bilateral_filter.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Color Bilteral Filter Example
|
||||||
|
#
|
||||||
|
# This example shows off using the bilateral filter on color images.
|
||||||
|
|
||||||
|
import sensor, image, time
|
||||||
|
|
||||||
|
sensor.reset() # Initialize the camera sensor.
|
||||||
|
sensor.set_pixformat(sensor.RGB565) # or sensor.RGB565
|
||||||
|
sensor.set_framesize(sensor.QQVGA) # or sensor.QVGA (or others)
|
||||||
|
sensor.skip_frames(time = 2000) # Let new settings take affect.
|
||||||
|
clock = time.clock() # Tracks FPS.
|
||||||
|
|
||||||
|
while(True):
|
||||||
|
clock.tick() # Track elapsed milliseconds between snapshots().
|
||||||
|
img = sensor.snapshot() # Take a picture and return the image.
|
||||||
|
|
||||||
|
# color_sigma controls how close color wise pixels have to be to each other to be
|
||||||
|
# blured togheter. A smaller value means they have to be closer.
|
||||||
|
# A larger value is less strict.
|
||||||
|
|
||||||
|
# space_sigma controls how close space wise pixels have to be to each other to be
|
||||||
|
# blured togheter. A smaller value means they have to be closer.
|
||||||
|
# A larger value is less strict.
|
||||||
|
|
||||||
|
# Run the kernel on every pixel of the image.
|
||||||
|
img.bilateral(3, color_sigma=5, space_sigma=5)
|
||||||
|
|
||||||
|
# Note that the bilateral filter can introduce image defects if you set
|
||||||
|
# color_sigma/space_sigma to aggresively. Increase the sigma values until
|
||||||
|
# the defects go away if you see them.
|
||||||
|
|
||||||
|
print(clock.fps()) # Note: Your OpenMV Cam runs about half as fast while
|
||||||
|
# connected to your computer. The FPS should increase once disconnected.
|
||||||
33
usr/examples/04-Image-Filters/grayscale_bilateral_filter.py
Normal file
33
usr/examples/04-Image-Filters/grayscale_bilateral_filter.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Grayscale Bilteral Filter Example
|
||||||
|
#
|
||||||
|
# This example shows off using the bilateral filter on grayscale images.
|
||||||
|
|
||||||
|
import sensor, image, time
|
||||||
|
|
||||||
|
sensor.reset() # Initialize the camera sensor.
|
||||||
|
sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.RGB565
|
||||||
|
sensor.set_framesize(sensor.QQVGA) # or sensor.QVGA (or others)
|
||||||
|
sensor.skip_frames(time = 2000) # Let new settings take affect.
|
||||||
|
clock = time.clock() # Tracks FPS.
|
||||||
|
|
||||||
|
while(True):
|
||||||
|
clock.tick() # Track elapsed milliseconds between snapshots().
|
||||||
|
img = sensor.snapshot() # Take a picture and return the image.
|
||||||
|
|
||||||
|
# color_sigma controls how close color wise pixels have to be to each other to be
|
||||||
|
# blured togheter. A smaller value means they have to be closer.
|
||||||
|
# A larger value is less strict.
|
||||||
|
|
||||||
|
# space_sigma controls how close space wise pixels have to be to each other to be
|
||||||
|
# blured togheter. A smaller value means they have to be closer.
|
||||||
|
# A larger value is less strict.
|
||||||
|
|
||||||
|
# Run the kernel on every pixel of the image.
|
||||||
|
img.bilateral(3, color_sigma=20, space_sigma=20)
|
||||||
|
|
||||||
|
# Note that the bilateral filter can introduce image defects if you set
|
||||||
|
# color_sigma/space_sigma to aggresively. Increase the sigma values until
|
||||||
|
# the defects go away if you see them.
|
||||||
|
|
||||||
|
print(clock.fps()) # Note: Your OpenMV Cam runs about half as fast while
|
||||||
|
# connected to your computer. The FPS should increase once disconnected.
|
||||||
Loading…
Reference in New Issue
Block a user