mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Add transpose support to replace and aliases
Now you can rotate and image by 0, 90, 180, 270 degrees along with vertical flip and horizontal mirror. This method works in place or out of place.
This commit is contained in:
parent
563642a174
commit
dbe7bf0591
@ -1298,7 +1298,7 @@ void imlib_black_hat(image_t *img, int ksize, int threshold, image_t *mask);
|
||||
// Math Functions
|
||||
void imlib_gamma_corr(image_t *img, float gamma, float scale, float offset);
|
||||
void imlib_negate(image_t *img);
|
||||
void imlib_replace(image_t *img, const char *path, image_t *other, int scalar, bool hmirror, bool vflip, 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);
|
||||
void imlib_add(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_sub(image_t *img, const char *path, image_t *other, int scalar, bool reverse, image_t *mask);
|
||||
void imlib_mul(image_t *img, const char *path, image_t *other, int scalar, bool invert, image_t *mask);
|
||||
|
||||
@ -147,7 +147,7 @@ void imlib_negate(image_t *img)
|
||||
}
|
||||
|
||||
typedef struct imlib_replace_line_op_state {
|
||||
bool hmirror, vflip;
|
||||
bool hmirror, vflip, transpose;
|
||||
image_t *mask;
|
||||
} imlib_replace_line_op_state_t;
|
||||
|
||||
@ -155,44 +155,52 @@ static void imlib_replace_line_op(image_t *img, int line, void *other, void *dat
|
||||
{
|
||||
bool hmirror = ((imlib_replace_line_op_state_t *) data)->hmirror;
|
||||
bool vflip = ((imlib_replace_line_op_state_t *) data)->vflip;
|
||||
bool transpose = ((imlib_replace_line_op_state_t *) data)->transpose;
|
||||
image_t *mask = ((imlib_replace_line_op_state_t *) data)->mask;
|
||||
|
||||
image_t target;
|
||||
memcpy(&target, img, sizeof(image_t));
|
||||
|
||||
if (transpose) {
|
||||
int w = target.w;
|
||||
int h = target.h;
|
||||
target.w = h;
|
||||
target.h = w;
|
||||
}
|
||||
|
||||
switch(img->bpp) {
|
||||
case IMAGE_BPP_BINARY: {
|
||||
int v_line = vflip ? (img->h - line - 1) : line;
|
||||
uint32_t *data = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, v_line);
|
||||
for (int i = 0, j = img->w; i < j; i++) {
|
||||
int h_i = hmirror ? (img->w - i - 1) : i;
|
||||
|
||||
if ((!mask) || image_get_mask_pixel(mask, h_i, v_line)) {
|
||||
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(((uint32_t *) other), h_i);
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(data, i, pixel);
|
||||
IMAGE_PUT_BINARY_PIXEL(&target, transpose ? v_line : i, transpose ? i : v_line, pixel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IMAGE_BPP_GRAYSCALE: {
|
||||
int v_line = vflip ? (img->h - line - 1) : line;
|
||||
uint8_t *data = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, v_line);
|
||||
for (int i = 0, j = img->w; i < j; i++) {
|
||||
int h_i = hmirror ? (img->w - i - 1) : i;
|
||||
|
||||
if ((!mask) || image_get_mask_pixel(mask, h_i, v_line)) {
|
||||
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(((uint8_t *) other), h_i);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(data, i, pixel);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL(&target, transpose ? v_line : i, transpose ? i : v_line, pixel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IMAGE_BPP_RGB565: {
|
||||
int v_line = vflip ? (img->h - line - 1) : line;
|
||||
uint16_t *data = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, v_line);
|
||||
for (int i = 0, j = img->w; i < j; i++) {
|
||||
int h_i = hmirror ? (img->w - i - 1) : i;
|
||||
|
||||
if ((!mask) || image_get_mask_pixel(mask, h_i, v_line)) {
|
||||
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(((uint16_t *) other), h_i);
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(data, i, pixel);
|
||||
IMAGE_PUT_RGB565_PIXEL(&target, transpose ? v_line : i, transpose ? i : v_line, pixel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -203,13 +211,35 @@ 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, 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;
|
||||
image_t temp;
|
||||
|
||||
if (in_place) {
|
||||
memcpy(&temp, other, sizeof(image_t));
|
||||
temp.data = fb_alloc(image_size(&temp));
|
||||
memcpy(temp.data, other->data, image_size(&temp));
|
||||
other = &temp;
|
||||
}
|
||||
|
||||
imlib_replace_line_op_state_t state;
|
||||
state.hmirror = hmirror;
|
||||
state.vflip = vflip;
|
||||
state.mask = mask;
|
||||
state.transpose = transpose;
|
||||
imlib_image_operation(img, path, other, scalar, imlib_replace_line_op, &state);
|
||||
|
||||
if (in_place) {
|
||||
fb_free();
|
||||
}
|
||||
|
||||
if (transpose) {
|
||||
int w = img->w;
|
||||
int h = img->h;
|
||||
img->w = h;
|
||||
img->h = w;
|
||||
}
|
||||
}
|
||||
|
||||
static void imlib_add_line_op(image_t *img, int line, void *other, void *data, bool vflipped)
|
||||
|
||||
@ -1852,23 +1852,44 @@ STATIC mp_obj_t py_image_replace(uint n_args, const mp_obj_t *args, mp_map_t *kw
|
||||
py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hmirror), false);
|
||||
bool arg_vflip =
|
||||
py_helper_keyword_int(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_vflip), false);
|
||||
bool arg_transpose =
|
||||
py_helper_keyword_int(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_transpose), false);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image_mutable_mask(n_args, args, 4, kw_args);
|
||||
py_helper_keyword_to_image_mutable_mask(n_args, args, 5, kw_args);
|
||||
|
||||
if (arg_transpose) {
|
||||
size_t size0 = image_size(arg_img);
|
||||
int w = arg_img->w;
|
||||
int h = arg_img->h;
|
||||
arg_img->w = h;
|
||||
arg_img->h = w;
|
||||
size_t size1 = image_size(arg_img);
|
||||
arg_img->w = w;
|
||||
arg_img->h = h;
|
||||
PY_ASSERT_TRUE_MSG(size1 <= size0, "Unable to transpose the image because it would grow in size!");
|
||||
}
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_replace(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_hmirror, arg_vflip, arg_msk);
|
||||
imlib_replace(arg_img, mp_obj_str_get_str(args[1]), NULL, 0,
|
||||
arg_hmirror, arg_vflip, arg_transpose, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_replace(arg_img, NULL, py_helper_arg_to_image_mutable(args[1]), 0, arg_hmirror, arg_vflip, arg_msk);
|
||||
imlib_replace(arg_img, NULL, py_helper_arg_to_image_mutable(args[1]), 0,
|
||||
arg_hmirror, arg_vflip, arg_transpose, arg_msk);
|
||||
} else {
|
||||
imlib_replace(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_hmirror, arg_vflip, arg_msk);
|
||||
arg_hmirror, arg_vflip, arg_transpose, arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
if (MAIN_FB()->pixels == arg_img->data) {
|
||||
MAIN_FB()->w = arg_img->w;
|
||||
MAIN_FB()->h = arg_img->h;
|
||||
}
|
||||
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_replace_obj, 2, py_image_replace);
|
||||
@ -5363,7 +5384,9 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
||||
/* Math Methods */
|
||||
{MP_ROM_QSTR(MP_QSTR_gamma_corr), MP_ROM_PTR(&py_image_gamma_corr_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_negate), MP_ROM_PTR(&py_image_negate_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_assign), MP_ROM_PTR(&py_image_replace_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_replace), MP_ROM_PTR(&py_image_replace_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&py_image_replace_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_add), MP_ROM_PTR(&py_image_add_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&py_image_sub_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_mul), MP_ROM_PTR(&py_image_mul_obj)},
|
||||
@ -5376,7 +5399,9 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
||||
{MP_ROM_QSTR(MP_QSTR_top_hat), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_black_hat), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_negate), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_assign), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_replace), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_add), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_mul), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
|
||||
@ -527,10 +527,13 @@ Q(brightness)
|
||||
// Negate
|
||||
Q(negate)
|
||||
|
||||
// Replace
|
||||
// Assign/Replace/Set
|
||||
Q(assign)
|
||||
Q(replace)
|
||||
Q(set)
|
||||
Q(hmirror)
|
||||
Q(vflip)
|
||||
Q(transpose)
|
||||
// duplicate Q(mask)
|
||||
|
||||
// Add Op
|
||||
|
||||
Loading…
Reference in New Issue
Block a user