mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #436 from kwagyeman/basic_method_updates
Basic method updates
This commit is contained in:
commit
1086c5842b
@ -63,7 +63,7 @@ static uint8_t *get_mcu()
|
|||||||
case 0:
|
case 0:
|
||||||
for (int y=jpeg_enc.y_offset; y<(jpeg_enc.y_offset + MCU_H); y++) {
|
for (int y=jpeg_enc.y_offset; y<(jpeg_enc.y_offset + MCU_H); y++) {
|
||||||
for (int x=jpeg_enc.x_offset; x<(jpeg_enc.x_offset + MCU_W); x++) {
|
for (int x=jpeg_enc.x_offset; x<(jpeg_enc.x_offset + MCU_W); x++) {
|
||||||
*Y0++ = COLOR_BINARY_TO_GRAYSCALE(IMAGE_GET_BINARY_PIXEL(jpeg_enc.img, x, y)) - 128;
|
*Y0++ = COLOR_BINARY_TO_GRAYSCALE(IMAGE_GET_BINARY_PIXEL(jpeg_enc.img, x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -213,7 +213,7 @@ static void imlib_replace_line_op(image_t *img, int line, void *other, void *dat
|
|||||||
|
|
||||||
void imlib_replace(image_t *img, const char *path, image_t *other, int scalar, bool hmirror, bool vflip, bool transpose, image_t *mask)
|
void imlib_replace(image_t *img, const char *path, image_t *other, int scalar, bool hmirror, bool vflip, bool transpose, image_t *mask)
|
||||||
{
|
{
|
||||||
bool in_place = img == other;
|
bool in_place = img->data == other->data;
|
||||||
image_t temp;
|
image_t temp;
|
||||||
|
|
||||||
if (in_place) {
|
if (in_place) {
|
||||||
|
|||||||
@ -13,47 +13,80 @@ 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 min_bias = (256-bias);
|
||||||
int max_bias = bias;
|
int max_bias = bias;
|
||||||
if (IM_IS_GS(img_i)) {
|
switch(img_i->bpp)
|
||||||
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++) {
|
case IMAGE_BPP_BINARY:
|
||||||
int min = 255, max = 0;
|
{
|
||||||
|
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 i = 0; i < y_div; i++) {
|
||||||
for (int j = 0; j < x_div; j++) {
|
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);
|
int pixel = IMAGE_GET_BINARY_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||||
min = IM_MIN(min, pixel);
|
min = IM_MIN(min, pixel);
|
||||||
max = IM_MAX(max, pixel);
|
max = IM_MAX(max, pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IM_SET_GS_PIXEL(img_o, x, y,
|
IMAGE_PUT_BINARY_PIXEL_FAST(row_ptr, x,
|
||||||
((min*min_bias)+(max*max_bias))>>8);
|
((min*min_bias)+(max*max_bias))>>8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
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++) {
|
case IMAGE_BPP_GRAYSCALE:
|
||||||
int r_min = 255, r_max = 0;
|
{
|
||||||
int g_min = 255, g_max = 0;
|
for (int y = 0, yy = img_i->h, yyy = (img_i->h % y_div) / 2 / y_div; y < yy; y++) {
|
||||||
int b_min = 255, b_max = 0;
|
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 i = 0; i < y_div; i++) {
|
||||||
for (int j = 0; j < x_div; j++) {
|
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 pixel = IMAGE_GET_GRAYSCALE_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||||
int red = IM_R565(pixel);
|
min = IM_MIN(min, pixel);
|
||||||
int green = IM_G565(pixel);
|
max = IM_MAX(max, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IM_SET_RGB565_PIXEL(img_o, x, y,
|
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_ptr, x,
|
||||||
IM_RGB565(((r_min*min_bias)+(r_max*max_bias))>>8,
|
((min*min_bias)+(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,
|
((g_min*min_bias)+(g_max*max_bias))>>8,
|
||||||
((b_min*min_bias)+(b_max*max_bias))>>8));
|
((b_min*min_bias)+(b_max*max_bias))>>8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // IMLIB_ENABLE_MIDPOINT_POOLING
|
#endif // IMLIB_ENABLE_MIDPOINT_POOLING
|
||||||
@ -62,38 +95,67 @@ 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)
|
void imlib_mean_pool(image_t *img_i, image_t *img_o, int x_div, int y_div)
|
||||||
{
|
{
|
||||||
int n = x_div * y_div;
|
int n = x_div * y_div;
|
||||||
if (IM_IS_GS(img_i)) {
|
switch(img_i->bpp)
|
||||||
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++) {
|
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;
|
int acc = 0;
|
||||||
for (int i = 0; i < y_div; i++) {
|
for (int i = 0; i < y_div; i++) {
|
||||||
for (int j = 0; j < x_div; j++) {
|
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);
|
int pixel = IMAGE_GET_BINARY_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||||
acc += pixel;
|
acc += pixel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IM_SET_GS_PIXEL(img_o, x, y,
|
IMAGE_PUT_BINARY_PIXEL_FAST(row_ptr, x, acc / n);
|
||||||
acc / n);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
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++) {
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 r_acc = 0;
|
||||||
int g_acc = 0;
|
int g_acc = 0;
|
||||||
int b_acc = 0;
|
int b_acc = 0;
|
||||||
for (int i = 0; i < y_div; i++) {
|
for (int i = 0; i < y_div; i++) {
|
||||||
for (int j = 0; j < x_div; j++) {
|
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);
|
int pixel = IMAGE_GET_RGB565_PIXEL(img_i, xxx + (x * x_div) + j, yyy + (y * y_div) + i);
|
||||||
r_acc += IM_R565(pixel);
|
r_acc += COLOR_RGB565_TO_R5(pixel);
|
||||||
g_acc += IM_G565(pixel);
|
g_acc += COLOR_RGB565_TO_G6(pixel);
|
||||||
b_acc += IM_B565(pixel);
|
b_acc += COLOR_RGB565_TO_B5(pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IM_SET_RGB565_PIXEL(img_o, x, y,
|
IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr, x, COLOR_R5_G6_B5_TO_RGB565(r_acc / n, g_acc / n, b_acc / n));
|
||||||
IM_RGB565(r_acc / n, g_acc / n, b_acc / n));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // IMLIB_ENABLE_MEAN_POOLING
|
#endif // IMLIB_ENABLE_MEAN_POOLING
|
||||||
|
|||||||
@ -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);
|
image_t *arg_img = py_helper_arg_to_image_mutable(img_obj);
|
||||||
|
|
||||||
int x_div = mp_obj_get_int(x_div_obj);
|
int arg_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(arg_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");
|
PY_ASSERT_TRUE_MSG(arg_x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||||
int y_div = mp_obj_get_int(y_div_obj);
|
int arg_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(arg_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");
|
PY_ASSERT_TRUE_MSG(arg_y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||||
|
|
||||||
image_t out_img;
|
image_t out_img;
|
||||||
out_img.w = arg_img->w / x_div;
|
out_img.w = arg_img->w / arg_x_div;
|
||||||
out_img.h = arg_img->h / y_div;
|
out_img.h = arg_img->h / arg_y_div;
|
||||||
out_img.bpp = arg_img->bpp;
|
out_img.bpp = arg_img->bpp;
|
||||||
out_img.pixels = arg_img->pixels;
|
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->w = out_img.w;
|
||||||
arg_img->h = out_img.h;
|
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);
|
image_t *arg_img = py_helper_arg_to_image_mutable(img_obj);
|
||||||
|
|
||||||
int x_div = mp_obj_get_int(x_div_obj);
|
int arg_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(arg_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");
|
PY_ASSERT_TRUE_MSG(arg_x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||||
int y_div = mp_obj_get_int(y_div_obj);
|
int arg_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(arg_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");
|
PY_ASSERT_TRUE_MSG(arg_y_div <= arg_img->h, "Height divisor must be less than <= img height");
|
||||||
|
|
||||||
image_t out_img;
|
image_t out_img;
|
||||||
out_img.w = arg_img->w / x_div;
|
out_img.w = arg_img->w / arg_x_div;
|
||||||
out_img.h = arg_img->h / y_div;
|
out_img.h = arg_img->h / arg_y_div;
|
||||||
out_img.bpp = arg_img->bpp;
|
out_img.bpp = arg_img->bpp;
|
||||||
out_img.pixels = xalloc(image_size(&out_img));
|
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);
|
return py_image_from_struct(&out_img);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_mean_pooled_obj, py_image_mean_pooled);
|
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]);
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
|
|
||||||
int x_div = mp_obj_get_int(args[1]);
|
int arg_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(arg_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");
|
PY_ASSERT_TRUE_MSG(arg_x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||||
int y_div = mp_obj_get_int(args[2]);
|
int arg_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(arg_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");
|
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,
|
int arg_bias = py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_bias), 0.5) * 256;
|
||||||
MP_OBJ_NEW_QSTR(MP_QSTR_bias), 0.5) * 256, 256), 0);
|
PY_ASSERT_TRUE_MSG((0 <= arg_bias) && (arg_bias <= 256), "Error: 0 <= bias <= 1!");
|
||||||
|
|
||||||
image_t out_img;
|
image_t out_img;
|
||||||
out_img.w = arg_img->w / x_div;
|
out_img.w = arg_img->w / arg_x_div;
|
||||||
out_img.h = arg_img->h / y_div;
|
out_img.h = arg_img->h / arg_y_div;
|
||||||
out_img.bpp = arg_img->bpp;
|
out_img.bpp = arg_img->bpp;
|
||||||
out_img.pixels = arg_img->pixels;
|
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->w = out_img.w;
|
||||||
arg_img->h = out_img.h;
|
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]);
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
|
|
||||||
int x_div = mp_obj_get_int(args[1]);
|
int arg_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(arg_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");
|
PY_ASSERT_TRUE_MSG(arg_x_div <= arg_img->w, "Width divisor must be less than <= img width");
|
||||||
int y_div = mp_obj_get_int(args[2]);
|
int arg_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(arg_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");
|
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,
|
int arg_bias = py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_bias), 0.5) * 256;
|
||||||
MP_OBJ_NEW_QSTR(MP_QSTR_bias), 0.5) * 256, 256), 0);
|
PY_ASSERT_TRUE_MSG((0 <= arg_bias) && (arg_bias <= 256), "Error: 0 <= bias <= 1!");
|
||||||
|
|
||||||
image_t out_img;
|
image_t out_img;
|
||||||
out_img.w = arg_img->w / x_div;
|
out_img.w = arg_img->w / arg_x_div;
|
||||||
out_img.h = arg_img->h / y_div;
|
out_img.h = arg_img->h / arg_y_div;
|
||||||
out_img.bpp = arg_img->bpp;
|
out_img.bpp = arg_img->bpp;
|
||||||
out_img.pixels = xalloc(image_size(&out_img));
|
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);
|
return py_image_from_struct(&out_img);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_midpoint_pooled_obj, 3, py_image_midpoint_pooled);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_midpoint_pooled_obj, 3, py_image_midpoint_pooled);
|
||||||
@ -761,6 +763,7 @@ static mp_obj_t py_image_to_bitmap(uint n_args, const mp_obj_t *args, mp_map_t *
|
|||||||
{
|
{
|
||||||
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
||||||
|
int channel = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
|
||||||
|
|
||||||
image_t out;
|
image_t out;
|
||||||
out.w = arg_img->w;
|
out.w = arg_img->w;
|
||||||
@ -777,15 +780,15 @@ static mp_obj_t py_image_to_bitmap(uint n_args, const mp_obj_t *args, mp_map_t *
|
|||||||
PY_ASSERT_TRUE_MSG((out.w >= (sizeof(uint32_t)/sizeof(uint8_t))) || copy,
|
PY_ASSERT_TRUE_MSG((out.w >= (sizeof(uint32_t)/sizeof(uint8_t))) || copy,
|
||||||
"Can't convert to bitmap in place!");
|
"Can't convert to bitmap in place!");
|
||||||
fb_alloc_mark();
|
fb_alloc_mark();
|
||||||
uint32_t *out_lin_ptr = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
uint32_t *out_row_ptr = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
||||||
for (int y = 0, yy = out.h; y < yy; y++) {
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, y);
|
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, y);
|
||||||
for (int x = 0, xx = out.w; x < xx; x++) {
|
for (int x = 0, xx = out.w; x < xx; x++) {
|
||||||
IMAGE_PUT_BINARY_PIXEL_FAST(out_lin_ptr, x,
|
IMAGE_PUT_BINARY_PIXEL_FAST(out_row_ptr, x,
|
||||||
COLOR_GRAYSCALE_TO_BINARY(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)));
|
COLOR_GRAYSCALE_TO_BINARY(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)));
|
||||||
}
|
}
|
||||||
memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&out, y),
|
memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&out, y),
|
||||||
out_lin_ptr, IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
out_row_ptr, IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
||||||
}
|
}
|
||||||
fb_free();
|
fb_free();
|
||||||
fb_alloc_free_till_mark();
|
fb_alloc_free_till_mark();
|
||||||
@ -795,15 +798,33 @@ static mp_obj_t py_image_to_bitmap(uint n_args, const mp_obj_t *args, mp_map_t *
|
|||||||
PY_ASSERT_TRUE_MSG((out.w >= (sizeof(uint32_t)/sizeof(uint16_t))) || copy,
|
PY_ASSERT_TRUE_MSG((out.w >= (sizeof(uint32_t)/sizeof(uint16_t))) || copy,
|
||||||
"Can't convert to bitmap in place!");
|
"Can't convert to bitmap in place!");
|
||||||
fb_alloc_mark();
|
fb_alloc_mark();
|
||||||
uint32_t *out_lin_ptr = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
uint32_t *out_row_ptr = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
||||||
for (int y = 0, yy = out.h; y < yy; y++) {
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
|
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
|
||||||
for (int x = 0, xx = out.w; x < xx; x++) {
|
for (int x = 0, xx = out.w; x < xx; x++) {
|
||||||
IMAGE_PUT_BINARY_PIXEL_FAST(out_lin_ptr, x,
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
|
||||||
COLOR_RGB565_TO_BINARY(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x)));
|
switch (channel) {
|
||||||
|
case 0: {
|
||||||
|
pixel = COLOR_RGB565_TO_R5(pixel) > (((COLOR_R5_MAX - COLOR_R5_MIN) / 2) + COLOR_R5_MIN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
pixel = COLOR_RGB565_TO_G6(pixel) > (((COLOR_G6_MAX - COLOR_G6_MIN) / 2) + COLOR_G6_MIN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
pixel = COLOR_RGB565_TO_B5(pixel) > (((COLOR_B5_MAX - COLOR_B5_MIN) / 2) + COLOR_B5_MIN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
pixel = COLOR_RGB565_TO_BINARY(pixel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IMAGE_PUT_BINARY_PIXEL_FAST(out_row_ptr, x, pixel);
|
||||||
}
|
}
|
||||||
memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&out, y),
|
memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&out, y),
|
||||||
out_lin_ptr, IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
out_row_ptr, IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
||||||
}
|
}
|
||||||
fb_free();
|
fb_free();
|
||||||
fb_alloc_free_till_mark();
|
fb_alloc_free_till_mark();
|
||||||
@ -826,6 +847,7 @@ static mp_obj_t py_image_to_grayscale(uint n_args, const mp_obj_t *args, mp_map_
|
|||||||
{
|
{
|
||||||
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
||||||
|
int channel = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
|
||||||
|
|
||||||
image_t out;
|
image_t out;
|
||||||
out.w = arg_img->w;
|
out.w = arg_img->w;
|
||||||
@ -835,7 +857,7 @@ static mp_obj_t py_image_to_grayscale(uint n_args, const mp_obj_t *args, mp_map_
|
|||||||
|
|
||||||
switch(arg_img->bpp) {
|
switch(arg_img->bpp) {
|
||||||
case IMAGE_BPP_BINARY: {
|
case IMAGE_BPP_BINARY: {
|
||||||
PY_ASSERT_TRUE_MSG((out.w == 1) || copy,
|
PY_ASSERT_TRUE_MSG((out.w <= (sizeof(uint32_t)/sizeof(uint8_t))) || copy,
|
||||||
"Can't convert to grayscale in place!");
|
"Can't convert to grayscale in place!");
|
||||||
for (int y = 0, yy = out.h; y < yy; y++) {
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
|
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
|
||||||
@ -856,8 +878,26 @@ static mp_obj_t py_image_to_grayscale(uint n_args, const mp_obj_t *args, mp_map_
|
|||||||
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
|
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
|
||||||
uint8_t *out_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&out, y);
|
uint8_t *out_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&out, y);
|
||||||
for (int x = 0, xx = out.w; x < xx; x++) {
|
for (int x = 0, xx = out.w; x < xx; x++) {
|
||||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(out_row_ptr, x,
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
|
||||||
COLOR_RGB565_TO_GRAYSCALE(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x)));
|
switch (channel) {
|
||||||
|
case 0: {
|
||||||
|
pixel = COLOR_RGB565_TO_R8(pixel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
pixel = COLOR_RGB565_TO_G8(pixel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
pixel = COLOR_RGB565_TO_B8(pixel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
pixel = COLOR_RGB565_TO_GRAYSCALE(pixel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(out_row_ptr, x, pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -879,6 +919,7 @@ static mp_obj_t py_image_to_rgb565(uint n_args, const mp_obj_t *args, mp_map_t *
|
|||||||
{
|
{
|
||||||
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
||||||
|
int channel = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
|
||||||
|
|
||||||
image_t out;
|
image_t out;
|
||||||
out.w = arg_img->w;
|
out.w = arg_img->w;
|
||||||
@ -888,7 +929,7 @@ static mp_obj_t py_image_to_rgb565(uint n_args, const mp_obj_t *args, mp_map_t *
|
|||||||
|
|
||||||
switch(arg_img->bpp) {
|
switch(arg_img->bpp) {
|
||||||
case IMAGE_BPP_BINARY: {
|
case IMAGE_BPP_BINARY: {
|
||||||
PY_ASSERT_TRUE_MSG((out.w == 1) || copy,
|
PY_ASSERT_TRUE_MSG((out.w <= (sizeof(uint32_t)/sizeof(uint16_t))) || copy,
|
||||||
"Can't convert to grayscale in place!");
|
"Can't convert to grayscale in place!");
|
||||||
for (int y = 0, yy = out.h; y < yy; y++) {
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
|
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
|
||||||
@ -914,7 +955,31 @@ static mp_obj_t py_image_to_rgb565(uint n_args, const mp_obj_t *args, mp_map_t *
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IMAGE_BPP_RGB565: {
|
case IMAGE_BPP_RGB565: {
|
||||||
if (copy) memcpy(out.data, arg_img->data, image_size(&out));
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
|
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
|
||||||
|
uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
|
||||||
|
for (int x = 0, xx = out.w; x < xx; x++) {
|
||||||
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
|
||||||
|
switch (channel) {
|
||||||
|
case 0: {
|
||||||
|
pixel = COLOR_R5_G6_B5_TO_RGB565(COLOR_RGB565_TO_R5(pixel), 0, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
pixel = COLOR_R5_G6_B5_TO_RGB565(0, COLOR_RGB565_TO_G6(pixel), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
pixel = COLOR_R5_G6_B5_TO_RGB565(0, 0, COLOR_RGB565_TO_B5(pixel));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x, pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -936,6 +1001,7 @@ static mp_obj_t py_image_to_rainbow(uint n_args, const mp_obj_t *args, mp_map_t
|
|||||||
{
|
{
|
||||||
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
||||||
|
int channel = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
|
||||||
|
|
||||||
image_t out;
|
image_t out;
|
||||||
out.w = arg_img->w;
|
out.w = arg_img->w;
|
||||||
@ -945,7 +1011,7 @@ static mp_obj_t py_image_to_rainbow(uint n_args, const mp_obj_t *args, mp_map_t
|
|||||||
|
|
||||||
switch(arg_img->bpp) {
|
switch(arg_img->bpp) {
|
||||||
case IMAGE_BPP_BINARY: {
|
case IMAGE_BPP_BINARY: {
|
||||||
PY_ASSERT_TRUE_MSG((out.w == 1) || copy,
|
PY_ASSERT_TRUE_MSG((out.w <= (sizeof(uint32_t)/sizeof(uint16_t))) || copy,
|
||||||
"Can't convert to rainbow in place!");
|
"Can't convert to rainbow in place!");
|
||||||
for (int y = 0, yy = out.h; y < yy; y++) {
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
|
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
|
||||||
@ -975,8 +1041,26 @@ static mp_obj_t py_image_to_rainbow(uint n_args, const mp_obj_t *args, mp_map_t
|
|||||||
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
|
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
|
||||||
uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
|
uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
|
||||||
for (int x = 0, xx = out.w; x < xx; x++) {
|
for (int x = 0, xx = out.w; x < xx; x++) {
|
||||||
IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
|
||||||
rainbow_table[COLOR_RGB565_TO_GRAYSCALE(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x))]);
|
switch (channel) {
|
||||||
|
case 0: {
|
||||||
|
pixel = rainbow_table[COLOR_RGB565_TO_R8(pixel)];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
pixel = rainbow_table[COLOR_RGB565_TO_G8(pixel)];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
pixel = rainbow_table[COLOR_RGB565_TO_B8(pixel)];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
pixel = rainbow_table[COLOR_RGB565_TO_GRAYSCALE(pixel)];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x, pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1030,7 +1114,7 @@ static mp_obj_t py_image_compress_for_ide(uint n_args, const mp_obj_t *args, mp_
|
|||||||
uint8_t *buffer = fb_alloc_all(&size);
|
uint8_t *buffer = fb_alloc_all(&size);
|
||||||
image_t out = { .w=arg_img->w, .h=arg_img->h, .bpp=size, .data=buffer };
|
image_t out = { .w=arg_img->w, .h=arg_img->h, .bpp=size, .data=buffer };
|
||||||
PY_ASSERT_FALSE_MSG(jpeg_compress(arg_img, &out, arg_q, false), "Out of Memory!");
|
PY_ASSERT_FALSE_MSG(jpeg_compress(arg_img, &out, arg_q, false), "Out of Memory!");
|
||||||
PY_ASSERT_TRUE_MSG(out.bpp <= image_size(arg_img), "Can't compress in place!");
|
PY_ASSERT_TRUE_MSG(((((out.bpp * 8) + 5) / 6) + 2) <= image_size(arg_img), "Can't compress in place!");
|
||||||
uint8_t *ptr = arg_img->data;
|
uint8_t *ptr = arg_img->data;
|
||||||
|
|
||||||
*ptr++ = 0xFE;
|
*ptr++ = 0xFE;
|
||||||
@ -1152,84 +1236,146 @@ static mp_obj_t py_image_compressed_for_ide(uint n_args, const mp_obj_t *args, m
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_compressed_for_ide_obj, 1, py_image_compressed_for_ide);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_compressed_for_ide_obj, 1, py_image_compressed_for_ide);
|
||||||
|
|
||||||
static mp_obj_t py_image_copy(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
static mp_obj_t py_image_copy_int(uint n_args, const mp_obj_t *args, mp_map_t *kw_args, bool mode)
|
||||||
{
|
{
|
||||||
image_t *arg_img = py_image_cobj(args[0]);
|
// mode == false -> copy behavior
|
||||||
|
// mode == true -> crop/scale behavior
|
||||||
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
|
|
||||||
rectangle_t roi;
|
rectangle_t roi;
|
||||||
py_helper_keyword_rectangle_roi(arg_img, n_args, args, 1, kw_args, &roi);
|
py_helper_keyword_rectangle_roi(arg_img, n_args, args, 1, kw_args, &roi);
|
||||||
|
|
||||||
bool copy_to_fb = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy_to_fb), false);
|
float arg_x_scale =
|
||||||
if (copy_to_fb) fb_update_jpeg_buffer();
|
py_helper_keyword_float(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_x_scale), 1.0f);
|
||||||
|
PY_ASSERT_TRUE_MSG((0.0f <= arg_x_scale), "Error: 0.0 <= x_scale!");
|
||||||
|
|
||||||
|
float arg_y_scale =
|
||||||
|
py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_y_scale), 1.0f);
|
||||||
|
PY_ASSERT_TRUE_MSG((0.0f <= arg_y_scale), "Error: 0.0 <= y_scale!");
|
||||||
|
|
||||||
|
mp_obj_t copy_to_fb_obj = py_helper_keyword_object(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(mode ? MP_QSTR_copy : MP_QSTR_copy_to_fb));
|
||||||
|
bool copy_to_fb = false;
|
||||||
|
image_t *arg_other = mode ? arg_img : NULL;
|
||||||
|
|
||||||
|
if (copy_to_fb_obj) {
|
||||||
|
if (mp_obj_is_integer(copy_to_fb_obj)) {
|
||||||
|
if (!mode) {
|
||||||
|
copy_to_fb = mp_obj_get_int(copy_to_fb_obj);
|
||||||
|
} else if (mp_obj_get_int(copy_to_fb_obj)) {
|
||||||
|
arg_other = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
arg_other = py_helper_arg_to_image_mutable(copy_to_fb_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy_to_fb) {
|
||||||
|
fb_update_jpeg_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
image_t image;
|
image_t image;
|
||||||
image.w = roi.w;
|
image.w = fast_roundf(roi.w * arg_x_scale);
|
||||||
image.h = roi.h;
|
PY_ASSERT_TRUE_MSG(image.w >= 1, "Output image width is 0!");
|
||||||
|
image.h = fast_roundf(roi.h * arg_y_scale);
|
||||||
|
PY_ASSERT_TRUE_MSG(image.h >= 1, "Output image height is 0!");
|
||||||
image.bpp = arg_img->bpp;
|
image.bpp = arg_img->bpp;
|
||||||
image.data = NULL;
|
image.data = NULL;
|
||||||
|
|
||||||
if (copy_to_fb) {
|
if (copy_to_fb) {
|
||||||
PY_ASSERT_TRUE_MSG(arg_img->data != MAIN_FB()->pixels, "Cannot copy to fb!");
|
MAIN_FB()->w = 0;
|
||||||
PY_ASSERT_TRUE_MSG((image_size(&image) <= OMV_RAW_BUF_SIZE), "FB Overflow!");
|
MAIN_FB()->h = 0;
|
||||||
|
MAIN_FB()->bpp = 0;
|
||||||
|
PY_ASSERT_TRUE_MSG((image_size(&image) <= fb_avail()), "The new image won't fit in the main frame buffer!");
|
||||||
MAIN_FB()->w = image.w;
|
MAIN_FB()->w = image.w;
|
||||||
MAIN_FB()->h = image.h;
|
MAIN_FB()->h = image.h;
|
||||||
MAIN_FB()->bpp = image.bpp;
|
MAIN_FB()->bpp = image.bpp;
|
||||||
image.data = MAIN_FB()->pixels;
|
image.data = MAIN_FB()->pixels;
|
||||||
|
} else if (arg_other) {
|
||||||
|
PY_ASSERT_TRUE_MSG((image_size(&image) <= image_size(arg_other)), "The new image won't fit in the target frame buffer!");
|
||||||
|
image.data = arg_other->data;
|
||||||
} else {
|
} else {
|
||||||
image.data = xalloc(image_size(&image));
|
image.data = xalloc(image_size(&image));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool in_place = arg_img->data == image.data;
|
||||||
|
image_t temp;
|
||||||
|
|
||||||
|
if (in_place) {
|
||||||
|
memcpy(&temp, arg_img, sizeof(image_t));
|
||||||
|
fb_alloc_mark();
|
||||||
|
temp.data = fb_alloc(image_size(&temp));
|
||||||
|
memcpy(temp.data, arg_img->data, image_size(&temp));
|
||||||
|
arg_img = &temp;
|
||||||
|
if (copy_to_fb) PY_ASSERT_TRUE_MSG((image_size(&image) <= fb_avail()), "The new image won't fit in the main frame buffer!");
|
||||||
|
}
|
||||||
|
|
||||||
|
float over_xscale = IM_DIV(1.0, arg_x_scale), over_yscale = IM_DIV(1.0f, arg_y_scale);
|
||||||
|
|
||||||
switch(arg_img->bpp) {
|
switch(arg_img->bpp) {
|
||||||
case IMAGE_BPP_BINARY: {
|
case IMAGE_BPP_BINARY: {
|
||||||
for (int y = roi.y, yy = roi.y + roi.h; y < yy; y++) {
|
for (int y = 0, yy = image.h; y < yy; y++) {
|
||||||
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
|
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, fast_roundf(y * over_yscale) + roi.y);
|
||||||
uint32_t *row_ptr_2 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&image, y - roi.y);
|
uint32_t *row_ptr_2 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&image, y);
|
||||||
for (int x = roi.x, xx = roi.x + roi.w; x < xx; x++) {
|
for (int x = 0, xx = image.w; x < xx; x++) {
|
||||||
IMAGE_PUT_BINARY_PIXEL_FAST(row_ptr_2, x - roi.x, IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x));
|
IMAGE_PUT_BINARY_PIXEL_FAST(row_ptr_2, x,
|
||||||
|
IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, fast_roundf(x * over_xscale) + roi.x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IMAGE_BPP_GRAYSCALE: {
|
case IMAGE_BPP_GRAYSCALE: {
|
||||||
for (int y = roi.y, yy = roi.y + roi.h; y < yy; y++) {
|
for (int y = 0, yy = image.h; y < yy; y++) {
|
||||||
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, y);
|
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, fast_roundf(y * over_yscale) + roi.y);
|
||||||
uint8_t *row_ptr_2 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&image, y - roi.y);
|
uint8_t *row_ptr_2 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&image, y);
|
||||||
for (int x = roi.x, xx = roi.x + roi.w; x < xx; x++) {
|
for (int x = 0, xx = image.w; x < xx; x++) {
|
||||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_ptr_2, x - roi.x, IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x));
|
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_ptr_2, x,
|
||||||
|
IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, fast_roundf(x * over_xscale) + roi.x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IMAGE_BPP_RGB565: {
|
case IMAGE_BPP_RGB565: {
|
||||||
for (int y = roi.y, yy = roi.y + roi.h; y < yy; y++) {
|
for (int y = 0, yy = image.h; y < yy; y++) {
|
||||||
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
|
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, fast_roundf(y * over_yscale) + roi.y);
|
||||||
uint16_t *row_ptr_2 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&image, y - roi.y);
|
uint16_t *row_ptr_2 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&image, y);
|
||||||
for (int x = roi.x, xx = roi.x + roi.w; x < xx; x++) {
|
for (int x = 0, xx = image.w; x < xx; x++) {
|
||||||
IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr_2, x - roi.x, IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x));
|
IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr_2, x,
|
||||||
|
IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, fast_roundf(x * over_xscale) + roi.x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IMAGE_BPP_BAYER: { // Correct!
|
default: {
|
||||||
for (int y = roi.y, yy = roi.y + roi.h; y < yy; y++) {
|
|
||||||
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, y);
|
|
||||||
uint8_t *row_ptr_2 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&image, y - roi.y);
|
|
||||||
for (int x = roi.x, xx = roi.x + roi.w; x < xx; x++) {
|
|
||||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_ptr_2, x - roi.x, IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: { // JPEG
|
|
||||||
memcpy(image.data, arg_img->data, image_size(&image));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_place) {
|
||||||
|
fb_free();
|
||||||
|
fb_alloc_free_till_mark();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MAIN_FB()->pixels == image.data) {
|
||||||
|
MAIN_FB()->w = image.w;
|
||||||
|
MAIN_FB()->h = image.h;
|
||||||
|
MAIN_FB()->bpp = image.bpp;
|
||||||
|
}
|
||||||
|
|
||||||
return py_image_from_struct(&image);
|
return py_image_from_struct(&image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mp_obj_t py_image_copy(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
|
{
|
||||||
|
return py_image_copy_int(n_args, args, kw_args, false);
|
||||||
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_copy_obj, 1, py_image_copy);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_copy_obj, 1, py_image_copy);
|
||||||
|
|
||||||
|
static mp_obj_t py_image_crop(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
|
{
|
||||||
|
return py_image_copy_int(n_args, args, kw_args, true);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_crop_obj, 1, py_image_crop);
|
||||||
|
|
||||||
static mp_obj_t py_image_save(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
static mp_obj_t py_image_save(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
{
|
{
|
||||||
image_t *arg_img = py_image_cobj(args[0]);
|
image_t *arg_img = py_image_cobj(args[0]);
|
||||||
@ -5865,6 +6011,8 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
|||||||
{MP_ROM_QSTR(MP_QSTR_compressed), MP_ROM_PTR(&py_image_compressed_obj)},
|
{MP_ROM_QSTR(MP_QSTR_compressed), MP_ROM_PTR(&py_image_compressed_obj)},
|
||||||
{MP_ROM_QSTR(MP_QSTR_compressed_for_ide), MP_ROM_PTR(&py_image_compressed_for_ide_obj)},
|
{MP_ROM_QSTR(MP_QSTR_compressed_for_ide), MP_ROM_PTR(&py_image_compressed_for_ide_obj)},
|
||||||
{MP_ROM_QSTR(MP_QSTR_copy), MP_ROM_PTR(&py_image_copy_obj)},
|
{MP_ROM_QSTR(MP_QSTR_copy), MP_ROM_PTR(&py_image_copy_obj)},
|
||||||
|
{MP_ROM_QSTR(MP_QSTR_crop), MP_ROM_PTR(&py_image_crop_obj)},
|
||||||
|
{MP_ROM_QSTR(MP_QSTR_scale), MP_ROM_PTR(&py_image_crop_obj)},
|
||||||
{MP_ROM_QSTR(MP_QSTR_save), MP_ROM_PTR(&py_image_save_obj)},
|
{MP_ROM_QSTR(MP_QSTR_save), MP_ROM_PTR(&py_image_save_obj)},
|
||||||
/* Drawing Methods */
|
/* Drawing Methods */
|
||||||
{MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&py_image_clear_obj)},
|
{MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&py_image_clear_obj)},
|
||||||
|
|||||||
@ -19,7 +19,6 @@ Q(board_id)
|
|||||||
|
|
||||||
// Image module
|
// Image module
|
||||||
Q(image)
|
Q(image)
|
||||||
Q(Image)
|
|
||||||
Q(binary_to_grayscale)
|
Q(binary_to_grayscale)
|
||||||
Q(binary_to_rgb)
|
Q(binary_to_rgb)
|
||||||
Q(binary_to_lab)
|
Q(binary_to_lab)
|
||||||
@ -51,31 +50,24 @@ Q(CORNER_AGAST)
|
|||||||
Q(load_descriptor)
|
Q(load_descriptor)
|
||||||
Q(save_descriptor)
|
Q(save_descriptor)
|
||||||
Q(match_descriptor)
|
Q(match_descriptor)
|
||||||
|
|
||||||
// Image class
|
// Image class
|
||||||
Q(copy)
|
Q(Image)
|
||||||
Q(copy_to_fb)
|
|
||||||
Q(save)
|
Q(save)
|
||||||
Q(width)
|
Q(width)
|
||||||
Q(height)
|
Q(height)
|
||||||
Q(format)
|
Q(format)
|
||||||
Q(size)
|
Q(size)
|
||||||
Q(midpoint_pool)
|
|
||||||
Q(midpoint_pooled)
|
|
||||||
Q(mean_pool)
|
|
||||||
Q(mean_pooled)
|
|
||||||
Q(find_template)
|
Q(find_template)
|
||||||
Q(kp_desc)
|
Q(kp_desc)
|
||||||
Q(lbp_desc)
|
Q(lbp_desc)
|
||||||
Q(Cascade)
|
Q(Cascade)
|
||||||
|
Q(cmp_lbp)
|
||||||
Q(find_features)
|
Q(find_features)
|
||||||
Q(find_keypoints)
|
Q(find_keypoints)
|
||||||
Q(find_lbp)
|
Q(find_lbp)
|
||||||
Q(find_eye)
|
Q(find_eye)
|
||||||
Q(find_edges)
|
Q(find_edges)
|
||||||
Q(find_hog)
|
Q(find_hog)
|
||||||
Q(cmp_lbp)
|
|
||||||
Q(roi)
|
|
||||||
Q(normalized)
|
Q(normalized)
|
||||||
Q(filter_outliers)
|
Q(filter_outliers)
|
||||||
Q(scale_factor)
|
Q(scale_factor)
|
||||||
@ -365,21 +357,39 @@ Q(rgbtuple)
|
|||||||
Q(set_pixel)
|
Q(set_pixel)
|
||||||
Q(color)
|
Q(color)
|
||||||
|
|
||||||
|
// Mean Pool
|
||||||
|
Q(mean_pool)
|
||||||
|
|
||||||
|
// Mean Pooled
|
||||||
|
Q(mean_pooled)
|
||||||
|
|
||||||
|
// Midpoint Pool
|
||||||
|
Q(midpoint_pool)
|
||||||
|
Q(bias)
|
||||||
|
|
||||||
|
// Midpoint Pooled
|
||||||
|
Q(midpoint_pooled)
|
||||||
|
// duplicate Q(bias)
|
||||||
|
|
||||||
// To Bitmap
|
// To Bitmap
|
||||||
Q(to_bitmap)
|
Q(to_bitmap)
|
||||||
// duplicate Q(copy)
|
Q(copy)
|
||||||
|
Q(rgb_channel)
|
||||||
|
|
||||||
// To Grayscale
|
// To Grayscale
|
||||||
Q(to_grayscale)
|
Q(to_grayscale)
|
||||||
// duplicate Q(copy)
|
// duplicate Q(copy)
|
||||||
|
// duplicate Q(rgb_channel)
|
||||||
|
|
||||||
// To RGB565
|
// To RGB565
|
||||||
Q(to_rgb565)
|
Q(to_rgb565)
|
||||||
// duplicate Q(copy)
|
// duplicate Q(copy)
|
||||||
|
// duplicate Q(rgb_channel)
|
||||||
|
|
||||||
// To Rainbow
|
// To Rainbow
|
||||||
Q(to_rainbow)
|
Q(to_rainbow)
|
||||||
// duplicate Q(copy)
|
// duplicate Q(copy)
|
||||||
|
// duplicate Q(rgb_channel)
|
||||||
|
|
||||||
// Compress (in place)
|
// Compress (in place)
|
||||||
Q(compress)
|
Q(compress)
|
||||||
@ -397,6 +407,15 @@ Q(compressed)
|
|||||||
Q(compressed_for_ide)
|
Q(compressed_for_ide)
|
||||||
// duplicate Q(quality)
|
// duplicate Q(quality)
|
||||||
|
|
||||||
|
// Copy
|
||||||
|
// duplicate Q(copy)
|
||||||
|
Q(crop)
|
||||||
|
Q(scale)
|
||||||
|
Q(roi)
|
||||||
|
Q(x_scale)
|
||||||
|
Q(y_scale)
|
||||||
|
Q(copy_to_fb)
|
||||||
|
|
||||||
// Clear
|
// Clear
|
||||||
Q(clear)
|
Q(clear)
|
||||||
|
|
||||||
@ -427,7 +446,7 @@ Q(rotation)
|
|||||||
// Draw String
|
// Draw String
|
||||||
Q(draw_string)
|
Q(draw_string)
|
||||||
// duplicate Q(color)
|
// duplicate Q(color)
|
||||||
Q(scale)
|
// duplicate Q(scale)
|
||||||
Q(x_spacing)
|
Q(x_spacing)
|
||||||
Q(y_spacing)
|
Q(y_spacing)
|
||||||
Q(mono_space)
|
Q(mono_space)
|
||||||
@ -453,8 +472,8 @@ Q(draw_edges)
|
|||||||
|
|
||||||
// Draw Image
|
// Draw Image
|
||||||
Q(draw_image)
|
Q(draw_image)
|
||||||
Q(x_scale)
|
// duplicate Q(x_scale)
|
||||||
Q(y_scale)
|
// duplicate Q(y_scale)
|
||||||
Q(alpha)
|
Q(alpha)
|
||||||
Q(mask)
|
Q(mask)
|
||||||
|
|
||||||
@ -630,7 +649,7 @@ Q(mode)
|
|||||||
|
|
||||||
// Midpoint
|
// Midpoint
|
||||||
Q(midpoint)
|
Q(midpoint)
|
||||||
Q(bias)
|
// duplicate Q(bias)
|
||||||
// duplicate Q(threshold)
|
// duplicate Q(threshold)
|
||||||
// duplicate Q(offset)
|
// duplicate Q(offset)
|
||||||
// duplicate Q(invert)
|
// duplicate Q(invert)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user