mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
imlib: Add support for AWB and CCM.
This commit is contained in:
parent
dfa1d09947
commit
0e0326ffab
@ -72,6 +72,7 @@ SRCS += $(addprefix imlib/, \
|
||||
imlib.c \
|
||||
integral.c \
|
||||
integral_mw.c \
|
||||
isp.c \
|
||||
jpegd.c \
|
||||
jpeg.c \
|
||||
lodepng.c \
|
||||
|
||||
@ -30,6 +30,9 @@
|
||||
// Enable midpoint pooling
|
||||
//#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
//#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
//#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -30,6 +30,9 @@
|
||||
// Enable midpoint pooling
|
||||
//#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
//#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
//#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
// Enable midpoint pooling
|
||||
#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
// Enable midpoint pooling
|
||||
#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
// Enable midpoint pooling
|
||||
#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
// Enable midpoint pooling
|
||||
#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
// Enable midpoint pooling
|
||||
#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
// Enable midpoint pooling
|
||||
#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
// Enable midpoint pooling
|
||||
#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -30,6 +30,9 @@
|
||||
// Enable midpoint pooling
|
||||
//#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
//#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
//#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
// Enable midpoint pooling
|
||||
#define IMLIB_ENABLE_MIDPOINT_POOLING
|
||||
|
||||
// Enable ISP ops
|
||||
#define IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
// Enable binary ops
|
||||
#define IMLIB_ENABLE_BINARY_OPS
|
||||
|
||||
|
||||
@ -1287,6 +1287,10 @@ void imlib_draw_image(image_t *dst_img, image_t *src_img, int dst_x_start, int d
|
||||
void imlib_flood_fill(image_t *img, int x, int y,
|
||||
float seed_threshold, float floating_threshold,
|
||||
int c, bool invert, bool clear_background, image_t *mask);
|
||||
// ISP Functions
|
||||
void imlib_awb(image_t *img, bool max);
|
||||
void imlib_ccm(image_t *img, float *ccm, bool offset);
|
||||
void imlib_gamma(image_t *img, float gamma, float scale, float offset);
|
||||
// Binary Functions
|
||||
void imlib_binary(image_t *out, image_t *img, list_t *thresholds, bool invert, bool zero, image_t *mask);
|
||||
void imlib_invert(image_t *img);
|
||||
@ -1303,7 +1307,6 @@ void imlib_close(image_t *img, int ksize, int threshold, image_t *mask);
|
||||
void imlib_top_hat(image_t *img, int ksize, int threshold, image_t *mask);
|
||||
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, bool transpose, image_t *mask);
|
||||
void imlib_add(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
|
||||
1151
src/omv/imlib/isp.c
Normal file
1151
src/omv/imlib/isp.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,102 +11,6 @@
|
||||
#include "imlib.h"
|
||||
|
||||
#ifdef IMLIB_ENABLE_MATH_OPS
|
||||
void imlib_gamma_corr(image_t *img, float gamma, float contrast, float brightness)
|
||||
{
|
||||
gamma = IM_DIV(1.0, gamma);
|
||||
switch (img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
float pScale = COLOR_BINARY_MAX - COLOR_BINARY_MIN;
|
||||
float pDiv = 1 / pScale;
|
||||
int *p_lut = fb_alloc((COLOR_BINARY_MAX - COLOR_BINARY_MIN + 1) * sizeof(int), FB_ALLOC_NO_HINT);
|
||||
|
||||
for (int i = COLOR_BINARY_MIN; i <= COLOR_BINARY_MAX; i++) {
|
||||
int p = ((fast_powf(i * pDiv, gamma) * contrast) + brightness) * pScale;
|
||||
p_lut[i] = IM_MIN(IM_MAX(p , COLOR_BINARY_MIN), COLOR_BINARY_MAX);
|
||||
}
|
||||
|
||||
for (int y = 0, yy = img->h; y < yy; y++) {
|
||||
uint32_t *data = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y);
|
||||
for (int x = 0, xx = img->w; x < xx; x++) {
|
||||
int dataPixel = IMAGE_GET_BINARY_PIXEL_FAST(data, x);
|
||||
int p = p_lut[dataPixel];
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(data, x, p);
|
||||
}
|
||||
}
|
||||
|
||||
fb_free();
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
float pScale = COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN;
|
||||
float pDiv = 1 / pScale;
|
||||
int *p_lut = fb_alloc((COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN + 1) * sizeof(int), FB_ALLOC_NO_HINT);
|
||||
|
||||
for (int i = COLOR_GRAYSCALE_MIN; i <= COLOR_GRAYSCALE_MAX; i++) {
|
||||
int p = ((fast_powf(i * pDiv, gamma) * contrast) + brightness) * pScale;
|
||||
p_lut[i] = IM_MIN(IM_MAX(p , COLOR_GRAYSCALE_MIN), COLOR_GRAYSCALE_MAX);
|
||||
}
|
||||
|
||||
for (int y = 0, yy = img->h; y < yy; y++) {
|
||||
uint8_t *data = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y);
|
||||
for (int x = 0, xx = img->w; x < xx; x++) {
|
||||
int dataPixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(data, x);
|
||||
int p = p_lut[dataPixel];
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(data, x, p);
|
||||
}
|
||||
}
|
||||
|
||||
fb_free();
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
float rScale = COLOR_R5_MAX - COLOR_R5_MIN;
|
||||
float gScale = COLOR_G6_MAX - COLOR_G6_MIN;
|
||||
float bScale = COLOR_B5_MAX - COLOR_B5_MIN;
|
||||
float rDiv = 1 / rScale;
|
||||
float gDiv = 1 / gScale;
|
||||
float bDiv = 1 / bScale;
|
||||
int *r_lut = fb_alloc((COLOR_R5_MAX - COLOR_R5_MIN + 1) * sizeof(int), FB_ALLOC_NO_HINT);
|
||||
int *g_lut = fb_alloc((COLOR_G6_MAX - COLOR_G6_MIN + 1) * sizeof(int), FB_ALLOC_NO_HINT);
|
||||
int *b_lut = fb_alloc((COLOR_B5_MAX - COLOR_B5_MIN + 1) * sizeof(int), FB_ALLOC_NO_HINT);
|
||||
|
||||
for (int i = COLOR_R5_MIN; i <= COLOR_R5_MAX; i++) {
|
||||
int r = ((fast_powf(i * rDiv, gamma) * contrast) + brightness) * rScale;
|
||||
r_lut[i] = IM_MIN(IM_MAX(r , COLOR_R5_MIN), COLOR_R5_MAX);
|
||||
}
|
||||
|
||||
for (int i = COLOR_G6_MIN; i <= COLOR_G6_MAX; i++) {
|
||||
int g = ((fast_powf(i * gDiv, gamma) * contrast) + brightness) * gScale;
|
||||
g_lut[i] = IM_MIN(IM_MAX(g , COLOR_G6_MIN), COLOR_G6_MAX);
|
||||
}
|
||||
|
||||
for (int i = COLOR_B5_MIN; i <= COLOR_B5_MAX; i++) {
|
||||
int b = ((fast_powf(i * bDiv, gamma) * contrast) + brightness) * bScale;
|
||||
b_lut[i] = IM_MIN(IM_MAX(b , COLOR_B5_MIN), COLOR_B5_MAX);
|
||||
}
|
||||
|
||||
for (int y = 0, yy = img->h; y < yy; y++) {
|
||||
uint16_t *data = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y);
|
||||
for (int x = 0, xx = img->w; x < xx; x++) {
|
||||
int dataPixel = IMAGE_GET_RGB565_PIXEL_FAST(data, x);
|
||||
int r = r_lut[COLOR_RGB565_TO_R5(dataPixel)];
|
||||
int g = g_lut[COLOR_RGB565_TO_G6(dataPixel)];
|
||||
int b = b_lut[COLOR_RGB565_TO_B5(dataPixel)];
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(data, x, COLOR_R5_G6_B5_TO_RGB565(r, g, b));
|
||||
}
|
||||
}
|
||||
|
||||
fb_free();
|
||||
fb_free();
|
||||
fb_free();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_negate(image_t *img)
|
||||
{
|
||||
switch (img->pixfmt) {
|
||||
|
||||
@ -1808,6 +1808,67 @@ STATIC mp_obj_t py_image_flood_fill(uint n_args, const mp_obj_t *args, mp_map_t
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_flood_fill_obj, 2, py_image_flood_fill);
|
||||
#endif // IMLIB_ENABLE_FLOOD_FILL
|
||||
|
||||
|
||||
#ifdef IMLIB_ENABLE_ISP_OPS
|
||||
//////////////
|
||||
// ISP Methods
|
||||
//////////////
|
||||
|
||||
STATIC mp_obj_t py_awb(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
{
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image_not_compressed(args[0]);
|
||||
bool arg_max =
|
||||
py_helper_keyword_float(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_max), false);
|
||||
|
||||
imlib_awb(arg_img, arg_max);
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_awb_obj, 1, py_awb);
|
||||
|
||||
STATIC mp_obj_t py_ccm(mp_obj_t img_obj, mp_obj_t ccm_obj)
|
||||
{
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image_mutable(img_obj);
|
||||
|
||||
size_t len;
|
||||
mp_obj_t *items;
|
||||
mp_obj_get_array(ccm_obj, &len, &items);
|
||||
|
||||
if ((len != 9) && (len != 12)) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Expected a 3x3 or 4x3 matrix!"));
|
||||
}
|
||||
|
||||
float ccm[12] = {};
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ccm[i] = mp_obj_get_float(items[i]);
|
||||
}
|
||||
|
||||
imlib_ccm(arg_img, ccm, len == 12);
|
||||
return img_obj;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_ccm_obj, py_ccm);
|
||||
|
||||
STATIC mp_obj_t py_image_gamma(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]);
|
||||
float arg_gamma =
|
||||
py_helper_keyword_float(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gamma), 1.0f);
|
||||
float arg_contrast =
|
||||
py_helper_keyword_float(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_contrast), 1.0f);
|
||||
float arg_brightness =
|
||||
py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_brightness), 0.0f);
|
||||
|
||||
fb_alloc_mark();
|
||||
imlib_gamma(arg_img, arg_gamma, arg_contrast, arg_brightness);
|
||||
fb_alloc_free_till_mark();
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_gamma_obj, 1, py_image_gamma);
|
||||
|
||||
#endif // IMLIB_ENABLE_ISP_OPS
|
||||
|
||||
#ifdef IMLIB_ENABLE_BINARY_OPS
|
||||
/////////////////
|
||||
// Binary Methods
|
||||
@ -2100,24 +2161,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_close_obj, 2, py_image_close);
|
||||
// Math Methods
|
||||
///////////////
|
||||
|
||||
STATIC mp_obj_t py_image_gamma_corr(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]);
|
||||
float arg_gamma =
|
||||
py_helper_keyword_float(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gamma), 1.0f);
|
||||
float arg_contrast =
|
||||
py_helper_keyword_float(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_contrast), 1.0f);
|
||||
float arg_brightness =
|
||||
py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_brightness), 0.0f);
|
||||
|
||||
fb_alloc_mark();
|
||||
imlib_gamma_corr(arg_img, arg_gamma, arg_contrast, arg_brightness);
|
||||
fb_alloc_free_till_mark();
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_gamma_corr_obj, 1, py_image_gamma_corr);
|
||||
|
||||
STATIC mp_obj_t py_image_negate(mp_obj_t img_obj)
|
||||
{
|
||||
imlib_negate(py_helper_arg_to_image_mutable(img_obj));
|
||||
@ -6093,6 +6136,18 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
||||
{MP_ROM_QSTR(MP_QSTR_mask_rectangle), MP_ROM_PTR(&py_image_mask_rectangle_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_mask_circle), MP_ROM_PTR(&py_image_mask_circle_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_mask_ellipse), MP_ROM_PTR(&py_image_mask_ellipse_obj)},
|
||||
/* ISP Methods */
|
||||
#ifdef IMLIB_ENABLE_ISP_OPS
|
||||
{MP_ROM_QSTR(MP_QSTR_awb), MP_ROM_PTR(&py_awb_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_ccm), MP_ROM_PTR(&py_ccm_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_gamma), MP_ROM_PTR(&py_image_gamma_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_gamma_corr), MP_ROM_PTR(&py_image_gamma_obj)},
|
||||
#else
|
||||
{MP_ROM_QSTR(MP_QSTR_awb), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_ccm), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_gamma), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_gamma_corr), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
#endif // IMLIB_ENABLE_ISP_OPS
|
||||
/* Binary Methods */
|
||||
#ifdef IMLIB_ENABLE_BINARY_OPS
|
||||
{MP_ROM_QSTR(MP_QSTR_binary), MP_ROM_PTR(&py_image_binary_obj)},
|
||||
@ -6135,7 +6190,6 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
||||
#endif
|
||||
#ifdef IMLIB_ENABLE_MATH_OPS
|
||||
/* 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)},
|
||||
|
||||
@ -150,6 +150,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/imlib/, \
|
||||
imlib.o \
|
||||
integral.o \
|
||||
integral_mw.o \
|
||||
isp.o \
|
||||
jpegd.o \
|
||||
jpeg.o \
|
||||
lodepng.o \
|
||||
|
||||
@ -143,6 +143,7 @@ target_sources(${MICROPY_TARGET} PRIVATE
|
||||
${TOP_DIR}/${OMV_DIR}/imlib/imlib.c
|
||||
${TOP_DIR}/${OMV_DIR}/imlib/integral.c
|
||||
${TOP_DIR}/${OMV_DIR}/imlib/integral_mw.c
|
||||
${TOP_DIR}/${OMV_DIR}/imlib/isp.c
|
||||
${TOP_DIR}/${OMV_DIR}/imlib/jpegd.c
|
||||
${TOP_DIR}/${OMV_DIR}/imlib/jpeg.c
|
||||
${TOP_DIR}/${OMV_DIR}/imlib/lodepng.c
|
||||
|
||||
@ -195,6 +195,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/imlib/, \
|
||||
imlib.o \
|
||||
integral.o \
|
||||
integral_mw.o \
|
||||
isp.o \
|
||||
jpegd.o \
|
||||
jpeg.o \
|
||||
lodepng.o \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user