mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Add image conversion methods.
Requested by customers to make a grayscale image and rainbow image.
This commit is contained in:
parent
5881e5ef4f
commit
93b81fcffc
@ -740,6 +740,243 @@ static mp_obj_t py_image_midpoint_pooled(uint n_args, const mp_obj_t *args, mp_m
|
|||||||
}
|
}
|
||||||
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);
|
||||||
|
|
||||||
|
static mp_obj_t py_image_to_bitmap(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
|
{
|
||||||
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
|
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
||||||
|
|
||||||
|
image_t out;
|
||||||
|
out.w = arg_img->w;
|
||||||
|
out.h = arg_img->h;
|
||||||
|
out.bpp = IMAGE_BPP_BINARY;
|
||||||
|
out.data = copy ? xalloc(image_size(&out)) : arg_img->data;
|
||||||
|
|
||||||
|
switch(arg_img->bpp) {
|
||||||
|
case IMAGE_BPP_BINARY: {
|
||||||
|
if (copy) memcpy(out.data, arg_img->data, image_size(&out));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_GRAYSCALE: {
|
||||||
|
PY_ASSERT_TRUE_MSG((out.w >= (sizeof(uint32_t)/sizeof(uint8_t))) || copy,
|
||||||
|
"Can't convert to bitmap in place!");
|
||||||
|
fb_alloc_mark();
|
||||||
|
uint32_t *out_lin_ptr = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
||||||
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
|
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, y);
|
||||||
|
for (int x = 0, xx = out.w; x < xx; x++) {
|
||||||
|
IMAGE_PUT_BINARY_PIXEL_FAST(out_lin_ptr, x,
|
||||||
|
COLOR_GRAYSCALE_TO_BINARY(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)));
|
||||||
|
}
|
||||||
|
memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&out, y),
|
||||||
|
out_lin_ptr, IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
||||||
|
}
|
||||||
|
fb_free();
|
||||||
|
fb_alloc_free_till_mark();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_RGB565: {
|
||||||
|
PY_ASSERT_TRUE_MSG((out.w >= (sizeof(uint32_t)/sizeof(uint16_t))) || copy,
|
||||||
|
"Can't convert to bitmap in place!");
|
||||||
|
fb_alloc_mark();
|
||||||
|
uint32_t *out_lin_ptr = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
||||||
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
|
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
|
||||||
|
for (int x = 0, xx = out.w; x < xx; x++) {
|
||||||
|
IMAGE_PUT_BINARY_PIXEL_FAST(out_lin_ptr, x,
|
||||||
|
COLOR_RGB565_TO_BINARY(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x)));
|
||||||
|
}
|
||||||
|
memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&out, y),
|
||||||
|
out_lin_ptr, IMAGE_BINARY_LINE_LEN_BYTES(&out));
|
||||||
|
}
|
||||||
|
fb_free();
|
||||||
|
fb_alloc_free_till_mark();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!copy) && (MAIN_FB()->pixels == out.data)) {
|
||||||
|
MAIN_FB()->bpp = out.bpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return py_image_from_struct(&out);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_bitmap_obj, 1, py_image_to_bitmap);
|
||||||
|
|
||||||
|
static mp_obj_t py_image_to_grayscale(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
|
{
|
||||||
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
|
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
||||||
|
|
||||||
|
image_t out;
|
||||||
|
out.w = arg_img->w;
|
||||||
|
out.h = arg_img->h;
|
||||||
|
out.bpp = IMAGE_BPP_GRAYSCALE;
|
||||||
|
out.data = copy ? xalloc(image_size(&out)) : arg_img->data;
|
||||||
|
|
||||||
|
switch(arg_img->bpp) {
|
||||||
|
case IMAGE_BPP_BINARY: {
|
||||||
|
PY_ASSERT_TRUE_MSG((out.w == 1) || copy,
|
||||||
|
"Can't convert to grayscale in place!");
|
||||||
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
|
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
|
||||||
|
uint8_t *out_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&out, y);
|
||||||
|
for (int x = 0, xx = out.w; x < xx; x++) {
|
||||||
|
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(out_row_ptr, x,
|
||||||
|
COLOR_BINARY_TO_GRAYSCALE(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_GRAYSCALE: {
|
||||||
|
if (copy) memcpy(out.data, arg_img->data, image_size(&out));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_RGB565: {
|
||||||
|
for (int y = 0, yy = out.h; y < yy; 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);
|
||||||
|
for (int x = 0, xx = out.w; x < xx; x++) {
|
||||||
|
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(out_row_ptr, x,
|
||||||
|
COLOR_RGB565_TO_GRAYSCALE(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!copy) && (MAIN_FB()->pixels == out.data)) {
|
||||||
|
MAIN_FB()->bpp = out.bpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return py_image_from_struct(&out);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_grayscale_obj, 1, py_image_to_grayscale);
|
||||||
|
|
||||||
|
static mp_obj_t py_image_to_rgb565(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
|
{
|
||||||
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
|
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
||||||
|
|
||||||
|
image_t out;
|
||||||
|
out.w = arg_img->w;
|
||||||
|
out.h = arg_img->h;
|
||||||
|
out.bpp = IMAGE_BPP_RGB565;
|
||||||
|
out.data = copy ? xalloc(image_size(&out)) : arg_img->data;
|
||||||
|
|
||||||
|
switch(arg_img->bpp) {
|
||||||
|
case IMAGE_BPP_BINARY: {
|
||||||
|
PY_ASSERT_TRUE_MSG((out.w == 1) || copy,
|
||||||
|
"Can't convert to grayscale in place!");
|
||||||
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
|
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_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++) {
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
|
||||||
|
imlib_yuv_to_rgb(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) * COLOR_GRAYSCALE_MAX, 0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_GRAYSCALE: {
|
||||||
|
PY_ASSERT_TRUE_MSG(copy,
|
||||||
|
"Can't convert to rgb565 in place!");
|
||||||
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
|
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_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++) {
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
|
||||||
|
imlib_yuv_to_rgb(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), 0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_RGB565: {
|
||||||
|
if (copy) memcpy(out.data, arg_img->data, image_size(&out));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!copy) && (MAIN_FB()->pixels == out.data)) {
|
||||||
|
MAIN_FB()->bpp = out.bpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return py_image_from_struct(&out);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_rgb565_obj, 1, py_image_to_rgb565);
|
||||||
|
|
||||||
|
extern const uint16_t rainbow_table[256];
|
||||||
|
|
||||||
|
static mp_obj_t py_image_to_rainbow(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
|
{
|
||||||
|
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||||
|
bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
|
||||||
|
|
||||||
|
image_t out;
|
||||||
|
out.w = arg_img->w;
|
||||||
|
out.h = arg_img->h;
|
||||||
|
out.bpp = IMAGE_BPP_RGB565;
|
||||||
|
out.data = copy ? xalloc(image_size(&out)) : arg_img->data;
|
||||||
|
|
||||||
|
switch(arg_img->bpp) {
|
||||||
|
case IMAGE_BPP_BINARY: {
|
||||||
|
PY_ASSERT_TRUE_MSG((out.w == 1) || copy,
|
||||||
|
"Can't convert to rainbow in place!");
|
||||||
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
|
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_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++) {
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
|
||||||
|
rainbow_table[IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) * COLOR_GRAYSCALE_MAX]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_GRAYSCALE: {
|
||||||
|
PY_ASSERT_TRUE_MSG(copy,
|
||||||
|
"Can't convert to rainbow in place!");
|
||||||
|
for (int y = 0, yy = out.h; y < yy; y++) {
|
||||||
|
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_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++) {
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
|
||||||
|
rainbow_table[IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_RGB565: {
|
||||||
|
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++) {
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
|
||||||
|
rainbow_table[COLOR_RGB565_TO_GRAYSCALE(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x))]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!copy) && (MAIN_FB()->pixels == out.data)) {
|
||||||
|
MAIN_FB()->bpp = out.bpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return py_image_from_struct(&out);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_rainbow_obj, 1, py_image_to_rainbow);
|
||||||
|
|
||||||
static mp_obj_t py_image_compress(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
static mp_obj_t py_image_compress(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
{
|
{
|
||||||
image_t *arg_img = py_helper_arg_to_image_mutable_bayer(args[0]);
|
image_t *arg_img = py_helper_arg_to_image_mutable_bayer(args[0]);
|
||||||
@ -4977,6 +5214,10 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
|||||||
{MP_ROM_QSTR(MP_QSTR_mean_pooled), MP_ROM_PTR(&py_image_mean_pooled_obj)},
|
{MP_ROM_QSTR(MP_QSTR_mean_pooled), MP_ROM_PTR(&py_image_mean_pooled_obj)},
|
||||||
{MP_ROM_QSTR(MP_QSTR_midpoint_pool), MP_ROM_PTR(&py_image_midpoint_pool_obj)},
|
{MP_ROM_QSTR(MP_QSTR_midpoint_pool), MP_ROM_PTR(&py_image_midpoint_pool_obj)},
|
||||||
{MP_ROM_QSTR(MP_QSTR_midpoint_pooled), MP_ROM_PTR(&py_image_midpoint_pooled_obj)},
|
{MP_ROM_QSTR(MP_QSTR_midpoint_pooled), MP_ROM_PTR(&py_image_midpoint_pooled_obj)},
|
||||||
|
{MP_ROM_QSTR(MP_QSTR_to_bitmap), MP_ROM_PTR(&py_image_to_bitmap_obj)},
|
||||||
|
{MP_ROM_QSTR(MP_QSTR_to_grayscale), MP_ROM_PTR(&py_image_to_grayscale_obj)},
|
||||||
|
{MP_ROM_QSTR(MP_QSTR_to_rgb565), MP_ROM_PTR(&py_image_to_rgb565_obj)},
|
||||||
|
{MP_ROM_QSTR(MP_QSTR_to_rainbow), MP_ROM_PTR(&py_image_to_rainbow_obj)},
|
||||||
{MP_ROM_QSTR(MP_QSTR_compress), MP_ROM_PTR(&py_image_compress_obj)},
|
{MP_ROM_QSTR(MP_QSTR_compress), MP_ROM_PTR(&py_image_compress_obj)},
|
||||||
{MP_ROM_QSTR(MP_QSTR_compress_for_ide), MP_ROM_PTR(&py_image_compress_for_ide_obj)},
|
{MP_ROM_QSTR(MP_QSTR_compress_for_ide), MP_ROM_PTR(&py_image_compress_for_ide_obj)},
|
||||||
{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)},
|
||||||
|
|||||||
@ -40,10 +40,6 @@ Q(match_descriptor)
|
|||||||
Q(copy)
|
Q(copy)
|
||||||
Q(copy_to_fb)
|
Q(copy_to_fb)
|
||||||
Q(save)
|
Q(save)
|
||||||
Q(compress)
|
|
||||||
Q(compress_for_ide)
|
|
||||||
Q(compressed)
|
|
||||||
Q(compressed_for_ide)
|
|
||||||
Q(width)
|
Q(width)
|
||||||
Q(height)
|
Q(height)
|
||||||
Q(format)
|
Q(format)
|
||||||
@ -63,7 +59,6 @@ Q(find_eye)
|
|||||||
Q(find_edges)
|
Q(find_edges)
|
||||||
Q(find_hog)
|
Q(find_hog)
|
||||||
Q(cmp_lbp)
|
Q(cmp_lbp)
|
||||||
Q(quality)
|
|
||||||
Q(roi)
|
Q(roi)
|
||||||
Q(normalized)
|
Q(normalized)
|
||||||
Q(filter_outliers)
|
Q(filter_outliers)
|
||||||
@ -325,6 +320,38 @@ Q(rgbtuple)
|
|||||||
Q(set_pixel)
|
Q(set_pixel)
|
||||||
Q(color)
|
Q(color)
|
||||||
|
|
||||||
|
// To Bitmap
|
||||||
|
Q(to_bitmap)
|
||||||
|
// duplicate Q(copy)
|
||||||
|
|
||||||
|
// To Grayscale
|
||||||
|
Q(to_grayscale)
|
||||||
|
// duplicate Q(copy)
|
||||||
|
|
||||||
|
// To RGB565
|
||||||
|
Q(to_rgb565)
|
||||||
|
// duplicate Q(copy)
|
||||||
|
|
||||||
|
// To Rainbow
|
||||||
|
Q(to_rainbow)
|
||||||
|
// duplicate Q(copy)
|
||||||
|
|
||||||
|
// Compress (in place)
|
||||||
|
Q(compress)
|
||||||
|
Q(quality)
|
||||||
|
|
||||||
|
// Compress for IDE (in place)
|
||||||
|
Q(compress_for_ide)
|
||||||
|
// duplicate Q(quality)
|
||||||
|
|
||||||
|
// Compressed (out of place)
|
||||||
|
Q(compressed)
|
||||||
|
// duplicate Q(quality)
|
||||||
|
|
||||||
|
// Compressed for IDE (out of place)
|
||||||
|
Q(compressed_for_ide)
|
||||||
|
// duplicate Q(quality)
|
||||||
|
|
||||||
// Clear
|
// Clear
|
||||||
Q(clear)
|
Q(clear)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user