mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #745 from bitbank2/master
optimized more image filters
This commit is contained in:
commit
1746744c28
@ -939,9 +939,14 @@ void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool thres
|
|||||||
buf.w = img->w;
|
buf.w = img->w;
|
||||||
buf.h = brows;
|
buf.h = brows;
|
||||||
buf.bpp = img->bpp;
|
buf.bpp = img->bpp;
|
||||||
|
uint8_t *u8BiasTable;
|
||||||
float max_bias = bias, min_bias = 1.0f - bias;
|
float max_bias = bias, min_bias = 1.0f - bias;
|
||||||
|
|
||||||
|
u8BiasTable = fb_alloc(256, FB_ALLOC_NO_HINT);
|
||||||
|
for (int i=0; i<256; i++) {
|
||||||
|
u8BiasTable[i] = (uint8_t)fast_floorf((float)i * bias);
|
||||||
|
}
|
||||||
|
|
||||||
switch(img->bpp) {
|
switch(img->bpp) {
|
||||||
case IMAGE_BPP_BINARY: {
|
case IMAGE_BPP_BINARY: {
|
||||||
buf.data = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(img) * brows, FB_ALLOC_NO_HINT);
|
buf.data = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(img) * brows, FB_ALLOC_NO_HINT);
|
||||||
@ -958,15 +963,26 @@ 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++) {
|
if (x >= ksize && x < img->w-ksize && y >= ksize && y < img->h-ksize) {
|
||||||
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,y+j);
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,x+k);
|
||||||
|
min &= pixel;
|
||||||
|
max |= pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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++) {
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
|
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
|
||||||
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
min = IM_MIN(min, pixel);
|
min &= pixel;
|
||||||
max = IM_MAX(max, pixel);
|
max |= pixel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1014,20 +1030,30 @@ void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool thres
|
|||||||
}
|
}
|
||||||
|
|
||||||
int min = COLOR_GRAYSCALE_MAX, max = COLOR_GRAYSCALE_MIN;
|
int min = COLOR_GRAYSCALE_MAX, max = COLOR_GRAYSCALE_MIN;
|
||||||
|
if (x >= ksize && x < img->w-ksize && y >= ksize && y < img->h-ksize) {
|
||||||
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
|
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,y+j);
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,x+k);
|
||||||
|
if (pixel < min) min = pixel;
|
||||||
|
else if (pixel > max) max = pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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 j = -ksize; j <= ksize; j++) {
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
|
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
|
||||||
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
|
if (pixel < min) min = pixel;
|
||||||
for (int k = -ksize; k <= ksize; k++) {
|
else if (pixel > max) max = pixel;
|
||||||
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
|
}
|
||||||
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
|
||||||
min = IM_MIN(min, pixel);
|
|
||||||
max = IM_MAX(max, pixel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pixel = fast_floorf((min*min_bias)+(max*max_bias));
|
int pixel = min + u8BiasTable[max-min];
|
||||||
|
|
||||||
if (threshold) {
|
if (threshold) {
|
||||||
if (((pixel - offset) < IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)) ^ invert) {
|
if (((pixel - offset) < IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)) ^ invert) {
|
||||||
@ -1073,29 +1099,47 @@ void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool thres
|
|||||||
int r_min = COLOR_R5_MAX, r_max = COLOR_R5_MIN;
|
int r_min = COLOR_R5_MAX, r_max = COLOR_R5_MIN;
|
||||||
int g_min = COLOR_G6_MAX, g_max = COLOR_G6_MIN;
|
int g_min = COLOR_G6_MAX, g_max = COLOR_G6_MIN;
|
||||||
int b_min = COLOR_B5_MAX, b_max = COLOR_B5_MIN;
|
int b_min = COLOR_B5_MAX, b_max = COLOR_B5_MIN;
|
||||||
|
if (x >= ksize && x < img->w-ksize && y >= ksize && y < img->h-ksize) {
|
||||||
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
|
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,y+j);
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,x+k);
|
||||||
|
int r_pixel = COLOR_RGB565_TO_R5(pixel);
|
||||||
|
int g_pixel = COLOR_RGB565_TO_G6(pixel);
|
||||||
|
int b_pixel = COLOR_RGB565_TO_B5(pixel);
|
||||||
|
if (r_pixel < r_min) r_min = r_pixel;
|
||||||
|
else if (r_pixel > r_max) r_max = r_pixel;
|
||||||
|
if (g_pixel < g_min) g_min = g_pixel;
|
||||||
|
else if (g_pixel > g_max) g_max = g_pixel;
|
||||||
|
if (b_pixel < b_min) b_min = b_pixel;
|
||||||
|
else if (b_pixel > b_max) b_max = b_pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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 j = -ksize; j <= ksize; j++) {
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
|
||||||
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
|
int r_pixel = COLOR_RGB565_TO_R5(pixel);
|
||||||
for (int k = -ksize; k <= ksize; k++) {
|
int g_pixel = COLOR_RGB565_TO_G6(pixel);
|
||||||
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
|
int b_pixel = COLOR_RGB565_TO_B5(pixel);
|
||||||
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
if (r_pixel < r_min) r_min = r_pixel;
|
||||||
int r_pixel = COLOR_RGB565_TO_R5(pixel);
|
else if (r_pixel > r_max) r_max = r_pixel;
|
||||||
int g_pixel = COLOR_RGB565_TO_G6(pixel);
|
if (g_pixel < g_min) g_min = g_pixel;
|
||||||
int b_pixel = COLOR_RGB565_TO_B5(pixel);
|
else if (g_pixel > g_max) g_max = g_pixel;
|
||||||
r_min = IM_MIN(r_min, r_pixel);
|
if (b_pixel < b_min) b_min = b_pixel;
|
||||||
r_max = IM_MAX(r_max, r_pixel);
|
else if (b_pixel > b_max) b_max = b_pixel;
|
||||||
g_min = IM_MIN(g_min, g_pixel);
|
}
|
||||||
g_max = IM_MAX(g_max, g_pixel);
|
|
||||||
b_min = IM_MIN(b_min, b_pixel);
|
|
||||||
b_max = IM_MAX(b_max, b_pixel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pixel = COLOR_R5_G6_B5_TO_RGB565(fast_floorf((r_min*min_bias)+(r_max*max_bias)),
|
r_min += u8BiasTable[r_max-r_min];
|
||||||
fast_floorf((g_min*min_bias)+(g_max*max_bias)),
|
g_min += u8BiasTable[g_max-g_min];
|
||||||
fast_floorf((b_min*min_bias)+(b_max*max_bias)));
|
b_min += u8BiasTable[b_max-b_min];
|
||||||
|
int pixel = COLOR_R5_G6_B5_TO_RGB565(r_min, g_min, b_min);
|
||||||
|
|
||||||
if (threshold) {
|
if (threshold) {
|
||||||
if (((COLOR_RGB565_TO_Y(pixel) - offset) < COLOR_RGB565_TO_Y(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x))) ^ invert) {
|
if (((COLOR_RGB565_TO_Y(pixel) - offset) < COLOR_RGB565_TO_Y(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x))) ^ invert) {
|
||||||
@ -1129,6 +1173,7 @@ void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool thres
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fb_free();
|
||||||
}
|
}
|
||||||
#endif // IMLIB_ENABLE_MIDPOINT
|
#endif // IMLIB_ENABLE_MIDPOINT
|
||||||
|
|
||||||
@ -1141,6 +1186,7 @@ void imlib_morph(image_t *img, const int ksize, const int *krn, const float m, c
|
|||||||
buf.w = img->w;
|
buf.w = img->w;
|
||||||
buf.h = brows;
|
buf.h = brows;
|
||||||
buf.bpp = img->bpp;
|
buf.bpp = img->bpp;
|
||||||
|
const int32_t m_int = (int32_t)(65536.0 * m); // m is 1/kernel_weight
|
||||||
|
|
||||||
switch(img->bpp) {
|
switch(img->bpp) {
|
||||||
case IMAGE_BPP_BINARY: {
|
case IMAGE_BPP_BINARY: {
|
||||||
@ -1158,17 +1204,28 @@ void imlib_morph(image_t *img, const int ksize, const int *krn, const float m, c
|
|||||||
|
|
||||||
int acc = 0, ptr = 0;
|
int acc = 0, ptr = 0;
|
||||||
|
|
||||||
for (int j = -ksize; j <= ksize; j++) {
|
if (x >= ksize && x < img->w-ksize && y >= ksize && y < img->h-ksize) {
|
||||||
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,y+j);
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
acc += krn[ptr++] * IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,x+k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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++) {
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
acc += krn[ptr++] * IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
|
acc += krn[ptr++] * IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
|
||||||
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int32_t tmp = (acc * m_int) >> 16;
|
||||||
int pixel = IM_MAX(IM_MIN(fast_floorf(acc * m) + b, COLOR_BINARY_MAX), COLOR_BINARY_MIN);
|
int pixel = tmp + b;
|
||||||
|
if (pixel < 0) pixel = 0;
|
||||||
|
else if (pixel > 1) pixel = 1;
|
||||||
|
|
||||||
if (threshold) {
|
if (threshold) {
|
||||||
if (((pixel - offset) < IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x)) ^ invert) {
|
if (((pixel - offset) < IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x)) ^ invert) {
|
||||||
@ -1211,19 +1268,30 @@ void imlib_morph(image_t *img, const int ksize, const int *krn, const float m, c
|
|||||||
continue; // Short circuit.
|
continue; // Short circuit.
|
||||||
}
|
}
|
||||||
|
|
||||||
int acc = 0, ptr = 0;
|
int32_t acc = 0, ptr = 0;
|
||||||
|
|
||||||
for (int j = -ksize; j <= ksize; j++) {
|
if (x >= ksize && x < img->w-ksize && y >= ksize && y < img->h-ksize) {
|
||||||
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,y+j);
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
acc += krn[ptr++] * IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,x+k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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++) {
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
acc += krn[ptr++] * IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
|
acc += krn[ptr++] * IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
|
||||||
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int32_t tmp = (acc * m_int)>>16;
|
||||||
int pixel = IM_MAX(IM_MIN(fast_floorf(acc * m) + b, COLOR_GRAYSCALE_MAX), COLOR_GRAYSCALE_MIN);
|
int pixel = tmp + b;
|
||||||
|
if (pixel > COLOR_GRAYSCALE_MAX) pixel = COLOR_GRAYSCALE_MAX;
|
||||||
|
else if (pixel < 0) pixel = 0;
|
||||||
|
|
||||||
if (threshold) {
|
if (threshold) {
|
||||||
if (((pixel - offset) < IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)) ^ invert) {
|
if (((pixel - offset) < IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)) ^ invert) {
|
||||||
@ -1266,24 +1334,45 @@ void imlib_morph(image_t *img, const int ksize, const int *krn, const float m, c
|
|||||||
continue; // Short circuit.
|
continue; // Short circuit.
|
||||||
}
|
}
|
||||||
|
|
||||||
int r_acc = 0, g_acc = 0, b_acc = 0, ptr = 0;
|
int32_t tmp, r_acc = 0, g_acc = 0, b_acc = 0, ptr = 0;
|
||||||
|
|
||||||
for (int j = -ksize; j <= ksize; j++) {
|
if (x >= ksize && x < img->w-ksize && y >= ksize && y < img->h-ksize) {
|
||||||
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,y+j);
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
for (int k = -ksize; k <= ksize; k++) {
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,x+k);
|
||||||
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
|
r_acc += krn[ptr] * COLOR_RGB565_TO_R5(pixel);
|
||||||
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
g_acc += krn[ptr] * COLOR_RGB565_TO_G6(pixel);
|
||||||
r_acc += krn[ptr] * COLOR_RGB565_TO_R5(pixel);
|
b_acc += krn[ptr++] * COLOR_RGB565_TO_B5(pixel);
|
||||||
g_acc += krn[ptr] * COLOR_RGB565_TO_G6(pixel);
|
}
|
||||||
b_acc += krn[ptr++] * COLOR_RGB565_TO_B5(pixel);
|
}
|
||||||
|
} else {
|
||||||
|
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)));
|
||||||
|
r_acc += krn[ptr] * COLOR_RGB565_TO_R5(pixel);
|
||||||
|
g_acc += krn[ptr] * COLOR_RGB565_TO_G6(pixel);
|
||||||
|
b_acc += krn[ptr++] * COLOR_RGB565_TO_B5(pixel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tmp = (r_acc * m_int) >> 16;
|
||||||
int pixel = COLOR_R5_G6_B5_TO_RGB565(IM_MAX(IM_MIN(fast_floorf(r_acc * m) + b, COLOR_R5_MAX), COLOR_R5_MIN),
|
r_acc = tmp + b;
|
||||||
IM_MAX(IM_MIN(fast_floorf(g_acc * m) + b, COLOR_G6_MAX), COLOR_G6_MIN),
|
if (r_acc > COLOR_R5_MAX) r_acc = COLOR_R5_MAX;
|
||||||
IM_MAX(IM_MIN(fast_floorf(b_acc * m) + b, COLOR_B5_MAX), COLOR_B5_MIN));
|
else if (r_acc < 0) r_acc = 0;
|
||||||
|
tmp = (g_acc * m_int) >> 16;
|
||||||
|
g_acc = tmp + b;
|
||||||
|
if (g_acc > COLOR_G6_MAX) g_acc = COLOR_G6_MAX;
|
||||||
|
else if (g_acc < 0) g_acc = 0;
|
||||||
|
tmp = (b_acc * m_int) >> 16;
|
||||||
|
b_acc = tmp + b;
|
||||||
|
if (b_acc > COLOR_B5_MAX) b_acc = COLOR_B5_MAX;
|
||||||
|
else if (b_acc < 0) b_acc = 0;
|
||||||
|
|
||||||
|
int pixel = COLOR_R5_G6_B5_TO_RGB565(r_acc, g_acc, b_acc);
|
||||||
|
|
||||||
if (threshold) {
|
if (threshold) {
|
||||||
if (((COLOR_RGB565_TO_Y(pixel) - offset) < COLOR_RGB565_TO_Y(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x))) ^ invert) {
|
if (((COLOR_RGB565_TO_Y(pixel) - offset) < COLOR_RGB565_TO_Y(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x))) ^ invert) {
|
||||||
@ -1341,11 +1430,11 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl
|
|||||||
switch(img->bpp) {
|
switch(img->bpp) {
|
||||||
case IMAGE_BPP_BINARY: {
|
case IMAGE_BPP_BINARY: {
|
||||||
buf.data = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(img) * brows, FB_ALLOC_NO_HINT);
|
buf.data = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(img) * brows, FB_ALLOC_NO_HINT);
|
||||||
float *gi_lut = fb_alloc((COLOR_BINARY_MAX - COLOR_BINARY_MIN + 1) * sizeof(float), FB_ALLOC_NO_HINT);
|
float *gi_lut_ptr = fb_alloc((COLOR_BINARY_MAX - COLOR_BINARY_MIN + 1) * sizeof(float) *2, FB_ALLOC_NO_HINT);
|
||||||
|
float *gi_lut = &gi_lut_ptr[1];
|
||||||
float max_color = IM_DIV(1.0f, COLOR_BINARY_MAX - COLOR_BINARY_MIN);
|
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 * max_color, color_sigma);
|
gi_lut[-i] = gi_lut[i] = gaussian(i * max_color, color_sigma);
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = (ksize * 2) + 1;
|
int n = (ksize * 2) + 1;
|
||||||
@ -1370,7 +1459,7 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl
|
|||||||
|
|
||||||
int this_pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x);
|
int this_pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x);
|
||||||
float i_acc = 0, w_acc = 0;
|
float i_acc = 0, w_acc = 0;
|
||||||
|
int ptr = 0;
|
||||||
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)));
|
||||||
@ -1378,7 +1467,7 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl
|
|||||||
for (int k = -ksize; k <= ksize; k++) {
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
|
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
|
||||||
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
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)];
|
float w = gi_lut[(this_pixel - pixel)] * gs_lut[ptr++];
|
||||||
i_acc += pixel * w;
|
i_acc += pixel * w;
|
||||||
w_acc += w;
|
w_acc += w;
|
||||||
}
|
}
|
||||||
@ -1418,11 +1507,11 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl
|
|||||||
}
|
}
|
||||||
case IMAGE_BPP_GRAYSCALE: {
|
case IMAGE_BPP_GRAYSCALE: {
|
||||||
buf.data = fb_alloc(IMAGE_GRAYSCALE_LINE_LEN_BYTES(img) * brows, FB_ALLOC_NO_HINT);
|
buf.data = fb_alloc(IMAGE_GRAYSCALE_LINE_LEN_BYTES(img) * brows, FB_ALLOC_NO_HINT);
|
||||||
float *gi_lut = fb_alloc((COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN + 1) * sizeof(float), FB_ALLOC_NO_HINT);
|
float *gi_lut_ptr = fb_alloc((COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN + 1) * sizeof(float) * 2, FB_ALLOC_NO_HINT);
|
||||||
|
float *gi_lut = &gi_lut_ptr[256]; // point to the middle
|
||||||
float max_color = IM_DIV(1.0f, COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN);
|
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 * max_color, color_sigma);
|
gi_lut[-i] = gi_lut[i] = gaussian(i * max_color, color_sigma);
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = (ksize * 2) + 1;
|
int n = (ksize * 2) + 1;
|
||||||
@ -1447,17 +1536,29 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl
|
|||||||
|
|
||||||
int this_pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x);
|
int this_pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x);
|
||||||
float i_acc = 0, w_acc = 0;
|
float i_acc = 0, w_acc = 0;
|
||||||
|
int ptr = 0;
|
||||||
|
if (x >= ksize && x < img->w-ksize && y >= ksize && y < img->h-ksize) {
|
||||||
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
|
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y+j);
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x+k);
|
||||||
|
float w = gi_lut[this_pixel - pixel] * gs_lut[ptr++];
|
||||||
|
i_acc += pixel * w;
|
||||||
|
w_acc += w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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 j = -ksize; j <= ksize; j++) {
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
|
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
|
||||||
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
|
float w = gi_lut[(this_pixel - pixel)] * gs_lut[ptr++];
|
||||||
for (int k = -ksize; k <= ksize; k++) {
|
i_acc += pixel * w;
|
||||||
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
|
w_acc += w;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1495,23 +1596,19 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl
|
|||||||
}
|
}
|
||||||
case IMAGE_BPP_RGB565: {
|
case IMAGE_BPP_RGB565: {
|
||||||
buf.data = fb_alloc(IMAGE_RGB565_LINE_LEN_BYTES(img) * brows, FB_ALLOC_NO_HINT);
|
buf.data = fb_alloc(IMAGE_RGB565_LINE_LEN_BYTES(img) * brows, FB_ALLOC_NO_HINT);
|
||||||
float *r_gi_lut = fb_alloc((COLOR_R5_MAX - COLOR_R5_MIN + 1) * sizeof(float), FB_ALLOC_NO_HINT);
|
float *rb_gi_ptr = fb_alloc((COLOR_R5_MAX - COLOR_R5_MIN + 1) * sizeof(float) *2, FB_ALLOC_NO_HINT);
|
||||||
float *g_gi_lut = fb_alloc((COLOR_G6_MAX - COLOR_G6_MIN + 1) * sizeof(float), FB_ALLOC_NO_HINT);
|
float *g_gi_ptr = fb_alloc((COLOR_G6_MAX - COLOR_G6_MIN + 1) * sizeof(float) *2, FB_ALLOC_NO_HINT);
|
||||||
float *b_gi_lut = fb_alloc((COLOR_B5_MAX - COLOR_B5_MIN + 1) * sizeof(float), FB_ALLOC_NO_HINT);
|
float *rb_gi_lut = &rb_gi_ptr[32]; // center
|
||||||
|
float *g_gi_lut = &g_gi_ptr[64];
|
||||||
|
|
||||||
float r_max_color = IM_DIV(1.0f, COLOR_R5_MAX - COLOR_R5_MIN);
|
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 * r_max_color, color_sigma);
|
rb_gi_lut[-i] = rb_gi_lut[i] = gaussian(i * r_max_color, color_sigma);
|
||||||
}
|
}
|
||||||
|
|
||||||
float g_max_color = IM_DIV(1.0f, COLOR_G6_MAX - COLOR_G6_MIN);
|
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 * g_max_color, color_sigma);
|
g_gi_lut[-i] = 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 * b_max_color, color_sigma);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = (ksize * 2) + 1;
|
int n = (ksize * 2) + 1;
|
||||||
@ -1541,27 +1638,49 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl
|
|||||||
float r_i_acc = 0, r_w_acc = 0;
|
float r_i_acc = 0, r_w_acc = 0;
|
||||||
float g_i_acc = 0, g_w_acc = 0;
|
float g_i_acc = 0, g_w_acc = 0;
|
||||||
float b_i_acc = 0, b_w_acc = 0;
|
float b_i_acc = 0, b_w_acc = 0;
|
||||||
|
int ptr = 0;
|
||||||
|
if (x >= ksize && x < img->w-ksize && y >= ksize && y < img->h-ksize) {
|
||||||
|
for (int j = -ksize; j <= ksize; j++) {
|
||||||
|
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,y+j);
|
||||||
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,x+k);
|
||||||
|
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[ptr++];
|
||||||
|
float r_w = rb_gi_lut[(r_this_pixel - r_pixel)] * gs;
|
||||||
|
float g_w = g_gi_lut[(g_this_pixel - g_pixel)] * gs;
|
||||||
|
float b_w = rb_gi_lut[(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // check boundary conditions
|
||||||
|
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 j = -ksize; j <= ksize; j++) {
|
for (int k = -ksize; k <= ksize; k++) {
|
||||||
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
|
||||||
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
|
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
||||||
|
int r_pixel = COLOR_RGB565_TO_R5(pixel);
|
||||||
for (int k = -ksize; k <= ksize; k++) {
|
int g_pixel = COLOR_RGB565_TO_G6(pixel);
|
||||||
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
|
int b_pixel = COLOR_RGB565_TO_B5(pixel);
|
||||||
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
|
float gs = gs_lut[ptr++];
|
||||||
int r_pixel = COLOR_RGB565_TO_R5(pixel);
|
float r_w = rb_gi_lut[(r_this_pixel - r_pixel)] * gs;
|
||||||
int g_pixel = COLOR_RGB565_TO_G6(pixel);
|
float g_w = g_gi_lut[(g_this_pixel - g_pixel)] * gs;
|
||||||
int b_pixel = COLOR_RGB565_TO_B5(pixel);
|
float b_w = rb_gi_lut[(b_this_pixel - b_pixel)] * gs;
|
||||||
float gs = gs_lut[(n * (j + ksize)) + (k + ksize)];
|
r_i_acc += r_pixel * r_w;
|
||||||
float r_w = r_gi_lut[abs(r_this_pixel - r_pixel)] * gs;
|
r_w_acc += r_w;
|
||||||
float g_w = g_gi_lut[abs(g_this_pixel - g_pixel)] * gs;
|
g_i_acc += g_pixel * g_w;
|
||||||
float b_w = b_gi_lut[abs(b_this_pixel - b_pixel)] * gs;
|
g_w_acc += g_w;
|
||||||
r_i_acc += r_pixel * r_w;
|
b_i_acc += b_pixel * b_w;
|
||||||
r_w_acc += r_w;
|
b_w_acc += b_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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1598,7 +1717,6 @@ void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, fl
|
|||||||
fb_free();
|
fb_free();
|
||||||
fb_free();
|
fb_free();
|
||||||
fb_free();
|
fb_free();
|
||||||
fb_free();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user