mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Modernize pooling methods.
This commit is contained in:
parent
6c36e939df
commit
949f738073
@ -13,46 +13,79 @@ void imlib_midpoint_pool(image_t *img_i, image_t *img_o, int x_div, int y_div, c
|
||||
{
|
||||
int min_bias = (256-bias);
|
||||
int max_bias = bias;
|
||||
if (IM_IS_GS(img_i)) {
|
||||
for (int y = 0, yy = img_i->h / y_div; y < yy; y++) {
|
||||
for (int x = 0, xx = img_i->w / x_div; x < xx; x++) {
|
||||
int min = 255, max = 0;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
const uint8_t pixel = IM_GET_GS_PIXEL(img_i, (x * x_div) + j, (y * y_div) + i);
|
||||
min = IM_MIN(min, pixel);
|
||||
max = IM_MAX(max, pixel);
|
||||
switch(img_i->bpp)
|
||||
{
|
||||
case IMAGE_BPP_BINARY:
|
||||
{
|
||||
for (int y = 0, yy = img_i->h / y_div, yyy = (img_i->h % y_div) / 2; y < yy; y++) {
|
||||
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img_o, y);
|
||||
for (int x = 0, xx = img_i->w / x_div, xxx = (img_i->w % x_div) / 2; x < xx; x++) {
|
||||
int min = COLOR_BINARY_MAX, max = COLOR_BINARY_MIN;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
int pixel = IMAGE_GET_BINARY_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||
min = IM_MIN(min, pixel);
|
||||
max = IM_MAX(max, pixel);
|
||||
}
|
||||
}
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row_ptr, x,
|
||||
((min*min_bias)+(max*max_bias))>>8);
|
||||
}
|
||||
IM_SET_GS_PIXEL(img_o, x, y,
|
||||
((min*min_bias)+(max*max_bias))>>8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (int y = 0, yy = img_i->h / y_div; y < yy; y++) {
|
||||
for (int x = 0, xx = img_i->w / x_div; x < xx; x++) {
|
||||
int r_min = 255, r_max = 0;
|
||||
int g_min = 255, g_max = 0;
|
||||
int b_min = 255, b_max = 0;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
const uint16_t pixel = IM_GET_RGB565_PIXEL(img_i, (x * x_div) + j, (y * y_div) + i);
|
||||
int red = IM_R565(pixel);
|
||||
int green = IM_G565(pixel);
|
||||
int blue = IM_B565(pixel);
|
||||
r_min = IM_MIN(r_min, red);
|
||||
r_max = IM_MAX(r_max, red);
|
||||
g_min = IM_MIN(g_min, green);
|
||||
g_max = IM_MAX(g_max, green);
|
||||
b_min = IM_MIN(b_min, blue);
|
||||
b_max = IM_MAX(b_max, blue);
|
||||
case IMAGE_BPP_GRAYSCALE:
|
||||
{
|
||||
for (int y = 0, yy = img_i->h, yyy = (img_i->h % y_div) / 2 / y_div; y < yy; y++) {
|
||||
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img_o, y);
|
||||
for (int x = 0, xx = img_i->w / x_div, xxx = (img_i->w % x_div) / 2; x < xx; x++) {
|
||||
int min = COLOR_GRAYSCALE_MAX, max = COLOR_GRAYSCALE_MIN;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
int pixel = IMAGE_GET_GRAYSCALE_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||
min = IM_MIN(min, pixel);
|
||||
max = IM_MAX(max, pixel);
|
||||
}
|
||||
}
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_ptr, x,
|
||||
((min*min_bias)+(max*max_bias))>>8);
|
||||
}
|
||||
IM_SET_RGB565_PIXEL(img_o, x, y,
|
||||
IM_RGB565(((r_min*min_bias)+(r_max*max_bias))>>8,
|
||||
((g_min*min_bias)+(g_max*max_bias))>>8,
|
||||
((b_min*min_bias)+(b_max*max_bias))>>8));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IMAGE_BPP_RGB565:
|
||||
{
|
||||
for (int y = 0, yy = img_i->h / y_div, yyy = (img_i->h % y_div) / 2; y < yy; y++) {
|
||||
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img_o, y);
|
||||
for (int x = 0, xx = img_i->w / x_div, xxx = (img_i->w % x_div) / 2; x < xx; x++) {
|
||||
int r_min = COLOR_R5_MAX, r_max = COLOR_R5_MIN;
|
||||
int g_min = COLOR_G6_MAX, g_max = COLOR_G6_MIN;
|
||||
int b_min = COLOR_B5_MAX, b_max = COLOR_B5_MIN;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
const uint16_t pixel = IM_GET_RGB565_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||
int r = COLOR_RGB565_TO_R5(pixel);
|
||||
int g = COLOR_RGB565_TO_G6(pixel);
|
||||
int b = COLOR_RGB565_TO_B5(pixel);
|
||||
r_min = IM_MIN(r_min, r);
|
||||
r_max = IM_MAX(r_max, r);
|
||||
g_min = IM_MIN(g_min, g);
|
||||
g_max = IM_MAX(g_max, g);
|
||||
b_min = IM_MIN(b_min, b);
|
||||
b_max = IM_MAX(b_max, b);
|
||||
}
|
||||
}
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr, x,
|
||||
COLOR_R5_G6_B5_TO_RGB565(((r_min*min_bias)+(r_max*max_bias))>>8,
|
||||
((g_min*min_bias)+(g_max*max_bias))>>8,
|
||||
((b_min*min_bias)+(b_max*max_bias))>>8));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -62,37 +95,66 @@ void imlib_midpoint_pool(image_t *img_i, image_t *img_o, int x_div, int y_div, c
|
||||
void imlib_mean_pool(image_t *img_i, image_t *img_o, int x_div, int y_div)
|
||||
{
|
||||
int n = x_div * y_div;
|
||||
if (IM_IS_GS(img_i)) {
|
||||
for (int y = 0, yy = img_i->h / y_div; y < yy; y++) {
|
||||
for (int x = 0, xx = img_i->w / x_div; x < xx; x++) {
|
||||
int acc = 0;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
const uint8_t pixel = IM_GET_GS_PIXEL(img_i, (x * x_div) + j, (y * y_div) + i);
|
||||
acc += pixel;
|
||||
switch(img_i->bpp)
|
||||
{
|
||||
case IMAGE_BPP_BINARY:
|
||||
{
|
||||
for (int y = 0, yy = img_i->h / y_div, yyy = (img_i->h % y_div) / 2; y < yy; y++) {
|
||||
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img_o, y);
|
||||
for (int x = 0, xx = img_i->w / x_div, xxx = (img_i->w % x_div) / 2; x < xx; x++) {
|
||||
int acc = 0;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
int pixel = IMAGE_GET_BINARY_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||
acc += pixel;
|
||||
}
|
||||
}
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row_ptr, x, acc / n);
|
||||
}
|
||||
IM_SET_GS_PIXEL(img_o, x, y,
|
||||
acc / n);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (int y = 0, yy = img_i->h / y_div; y < yy; y++) {
|
||||
for (int x = 0, xx = img_i->w / x_div; x < xx; x++) {
|
||||
int r_acc = 0;
|
||||
int g_acc = 0;
|
||||
int b_acc = 0;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
uint16_t pixel = IM_GET_RGB565_PIXEL(img_i, (x * x_div) + j, (y * y_div) + i);
|
||||
r_acc += IM_R565(pixel);
|
||||
g_acc += IM_G565(pixel);
|
||||
b_acc += IM_B565(pixel);
|
||||
case IMAGE_BPP_GRAYSCALE:
|
||||
{
|
||||
for (int y = 0, yy = img_i->h / y_div, yyy = (img_i->h % y_div) / 2; y < yy; y++) {
|
||||
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img_o, y);
|
||||
for (int x = 0, xx = img_i->w / x_div, xxx = (img_i->w % x_div) / 2; x < xx; x++) {
|
||||
int acc = 0;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
int pixel = IMAGE_GET_GRAYSCALE_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||
acc += pixel;
|
||||
}
|
||||
}
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_ptr, x, acc / n);
|
||||
}
|
||||
IM_SET_RGB565_PIXEL(img_o, x, y,
|
||||
IM_RGB565(r_acc / n, g_acc / n, b_acc / n));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IMAGE_BPP_RGB565:
|
||||
{
|
||||
for (int y = 0, yy = img_i->h / y_div, yyy = (img_i->h % y_div) / 2; y < yy; y++) {
|
||||
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img_o, y);
|
||||
for (int x = 0, xx = img_i->w / x_div, xxx = (img_i->w % x_div) / 2; x < xx; x++) {
|
||||
int r_acc = 0;
|
||||
int g_acc = 0;
|
||||
int b_acc = 0;
|
||||
for (int i = 0; i < y_div; i++) {
|
||||
for (int j = 0; j < x_div; j++) {
|
||||
int pixel = IMAGE_GET_RGB565_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||
r_acc += COLOR_RGB565_TO_R5(pixel);
|
||||
g_acc += COLOR_RGB565_TO_G6(pixel);
|
||||
b_acc += COLOR_RGB565_TO_B5(pixel);
|
||||
}
|
||||
}
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr, x, COLOR_R5_G6_B5_TO_RGB565(r_acc / n, g_acc / n, b_acc / n));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -648,20 +648,21 @@ static mp_obj_t py_image_mean_pool(mp_obj_t img_obj, mp_obj_t x_div_obj, mp_obj_
|
||||
{
|
||||
image_t *arg_img = py_helper_arg_to_image_mutable(img_obj);
|
||||
|
||||
int x_div = mp_obj_get_int(x_div_obj);
|
||||
PY_ASSERT_TRUE_MSG(x_div >= 1, "Width divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||
int y_div = mp_obj_get_int(y_div_obj);
|
||||
PY_ASSERT_TRUE_MSG(y_div >= 1, "Height divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||
int arg_x_div = mp_obj_get_int(x_div_obj);
|
||||
PY_ASSERT_TRUE_MSG(arg_x_div >= 1, "Width divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(arg_x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||
int arg_y_div = mp_obj_get_int(y_div_obj);
|
||||
PY_ASSERT_TRUE_MSG(arg_y_div >= 1, "Height divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(arg_y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||
|
||||
image_t out_img;
|
||||
out_img.w = arg_img->w / x_div;
|
||||
out_img.h = arg_img->h / y_div;
|
||||
out_img.w = arg_img->w / arg_x_div;
|
||||
out_img.h = arg_img->h / arg_y_div;
|
||||
out_img.bpp = arg_img->bpp;
|
||||
out_img.pixels = arg_img->pixels;
|
||||
PY_ASSERT_TRUE_MSG(image_size(&out_img) <= image_size(arg_img), "Can't pool in place!");
|
||||
|
||||
imlib_mean_pool(arg_img, &out_img, x_div, y_div);
|
||||
imlib_mean_pool(arg_img, &out_img, arg_x_div, arg_y_div);
|
||||
arg_img->w = out_img.w;
|
||||
arg_img->h = out_img.h;
|
||||
|
||||
@ -678,20 +679,20 @@ static mp_obj_t py_image_mean_pooled(mp_obj_t img_obj, mp_obj_t x_div_obj, mp_ob
|
||||
{
|
||||
image_t *arg_img = py_helper_arg_to_image_mutable(img_obj);
|
||||
|
||||
int x_div = mp_obj_get_int(x_div_obj);
|
||||
PY_ASSERT_TRUE_MSG(x_div >= 1, "Width divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||
int y_div = mp_obj_get_int(y_div_obj);
|
||||
PY_ASSERT_TRUE_MSG(y_div >= 1, "Height divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||
int arg_x_div = mp_obj_get_int(x_div_obj);
|
||||
PY_ASSERT_TRUE_MSG(arg_x_div >= 1, "Width divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(arg_x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||
int arg_y_div = mp_obj_get_int(y_div_obj);
|
||||
PY_ASSERT_TRUE_MSG(arg_y_div >= 1, "Height divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(arg_y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||
|
||||
image_t out_img;
|
||||
out_img.w = arg_img->w / x_div;
|
||||
out_img.h = arg_img->h / y_div;
|
||||
out_img.w = arg_img->w / arg_x_div;
|
||||
out_img.h = arg_img->h / arg_y_div;
|
||||
out_img.bpp = arg_img->bpp;
|
||||
out_img.pixels = xalloc(image_size(&out_img));
|
||||
|
||||
imlib_mean_pool(arg_img, &out_img, x_div, y_div);
|
||||
imlib_mean_pool(arg_img, &out_img, arg_x_div, arg_y_div);
|
||||
return py_image_from_struct(&out_img);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_mean_pooled_obj, py_image_mean_pooled);
|
||||
@ -702,23 +703,24 @@ static mp_obj_t py_image_midpoint_pool(uint n_args, const mp_obj_t *args, mp_map
|
||||
{
|
||||
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||
|
||||
int x_div = mp_obj_get_int(args[1]);
|
||||
PY_ASSERT_TRUE_MSG(x_div >= 1, "Width divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||
int y_div = mp_obj_get_int(args[2]);
|
||||
PY_ASSERT_TRUE_MSG(y_div >= 1, "Height divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||
int arg_x_div = mp_obj_get_int(args[1]);
|
||||
PY_ASSERT_TRUE_MSG(arg_x_div >= 1, "Width divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(arg_x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||
int arg_y_div = mp_obj_get_int(args[2]);
|
||||
PY_ASSERT_TRUE_MSG(arg_y_div >= 1, "Height divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(arg_y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||
|
||||
int bias = IM_MAX(IM_MIN(py_helper_keyword_float(n_args, args, 3, kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_bias), 0.5) * 256, 256), 0);
|
||||
int arg_bias = py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_bias), 0.5) * 256;
|
||||
PY_ASSERT_TRUE_MSG((0 <= arg_bias) && (arg_bias <= 256), "Error: 0 <= bias <= 1!");
|
||||
|
||||
image_t out_img;
|
||||
out_img.w = arg_img->w / x_div;
|
||||
out_img.h = arg_img->h / y_div;
|
||||
out_img.w = arg_img->w / arg_x_div;
|
||||
out_img.h = arg_img->h / arg_y_div;
|
||||
out_img.bpp = arg_img->bpp;
|
||||
out_img.pixels = arg_img->pixels;
|
||||
PY_ASSERT_TRUE_MSG(image_size(&out_img) <= image_size(arg_img), "Can't pool in place!");
|
||||
|
||||
imlib_midpoint_pool(arg_img, &out_img, x_div, y_div, bias);
|
||||
imlib_midpoint_pool(arg_img, &out_img, arg_x_div, arg_y_div, arg_bias);
|
||||
arg_img->w = out_img.w;
|
||||
arg_img->h = out_img.h;
|
||||
|
||||
@ -735,23 +737,23 @@ static mp_obj_t py_image_midpoint_pooled(uint n_args, const mp_obj_t *args, mp_m
|
||||
{
|
||||
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||
|
||||
int x_div = mp_obj_get_int(args[1]);
|
||||
PY_ASSERT_TRUE_MSG(x_div >= 1, "Width divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||
int y_div = mp_obj_get_int(args[2]);
|
||||
PY_ASSERT_TRUE_MSG(y_div >= 1, "Height divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||
int arg_x_div = mp_obj_get_int(args[1]);
|
||||
PY_ASSERT_TRUE_MSG(arg_x_div >= 1, "Width divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(arg_x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||
int arg_y_div = mp_obj_get_int(args[2]);
|
||||
PY_ASSERT_TRUE_MSG(arg_y_div >= 1, "Height divisor must be greater than >= 1");
|
||||
PY_ASSERT_TRUE_MSG(arg_y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||
|
||||
int bias = IM_MAX(IM_MIN(py_helper_keyword_float(n_args, args, 3, kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_bias), 0.5) * 256, 256), 0);
|
||||
int arg_bias = py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_bias), 0.5) * 256;
|
||||
PY_ASSERT_TRUE_MSG((0 <= arg_bias) && (arg_bias <= 256), "Error: 0 <= bias <= 1!");
|
||||
|
||||
image_t out_img;
|
||||
out_img.w = arg_img->w / x_div;
|
||||
out_img.h = arg_img->h / y_div;
|
||||
out_img.w = arg_img->w / arg_x_div;
|
||||
out_img.h = arg_img->h / arg_y_div;
|
||||
out_img.bpp = arg_img->bpp;
|
||||
out_img.pixels = xalloc(image_size(&out_img));
|
||||
|
||||
imlib_midpoint_pool(arg_img, &out_img, x_div, y_div, bias);
|
||||
imlib_midpoint_pool(arg_img, &out_img, arg_x_div, arg_y_div, arg_bias);
|
||||
return py_image_from_struct(&out_img);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_midpoint_pooled_obj, 3, py_image_midpoint_pooled);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user