mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
modules/py_fir: Refactor arg parsing.
This commit is contained in:
parent
4773126560
commit
08bf62a32f
@ -82,7 +82,7 @@ static omv_i2c_t fir_bus = {};
|
||||
static void *fir_mlx_data = NULL;
|
||||
#endif
|
||||
|
||||
static enum {
|
||||
typedef enum fir_sensor_type {
|
||||
FIR_NONE,
|
||||
#if (OMV_ENABLE_FIR_MLX90621 == 1)
|
||||
FIR_MLX90621,
|
||||
@ -99,14 +99,14 @@ static enum {
|
||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||
FIR_LEPTON
|
||||
#endif
|
||||
}
|
||||
fir_sensor = FIR_NONE;
|
||||
} fir_sensor_type_t;
|
||||
|
||||
static int fir_width = 0;
|
||||
static int fir_height = 0;
|
||||
static int fir_ir_fresh_rate = 0;
|
||||
static int fir_adc_resolution = 0;
|
||||
static bool fir_transposed = false;
|
||||
static fir_sensor_type_t fir_sensor = FIR_NONE;
|
||||
|
||||
// img->w == data_w && img->h == data_h && img->pixfmt == PIXFORMAT_GRAYSCALE
|
||||
static void fir_fill_image_float_obj(image_t *img, mp_obj_t *data, float min, float max) {
|
||||
@ -194,14 +194,20 @@ static void fir_MLX90641_get_frame(float *Ta, float *To) {
|
||||
static void fir_AMG8833_get_frame(float *Ta, float *To) {
|
||||
int16_t temp;
|
||||
int error = 0;
|
||||
error |= omv_i2c_write_bytes(&fir_bus, AMG8833_ADDR, (uint8_t [1]) {AMG8833_THERMISTOR_REGISTER}, 1, OMV_I2C_XFER_NO_STOP);
|
||||
error |= omv_i2c_write_bytes(&fir_bus,
|
||||
AMG8833_ADDR,
|
||||
(uint8_t [1]) {AMG8833_THERMISTOR_REGISTER},
|
||||
1, OMV_I2C_XFER_NO_STOP);
|
||||
error |= omv_i2c_read_bytes(&fir_bus, AMG8833_ADDR, (uint8_t *) &temp, sizeof(temp), OMV_I2C_XFER_NO_FLAGS);
|
||||
PY_ASSERT_TRUE_MSG((error == 0), "Failed to read the AMG8833 sensor data!");
|
||||
|
||||
*Ta = AMG8833_12_TO_16(temp) * 0.0625f;
|
||||
|
||||
int16_t *data = fb_alloc(AMG8833_WIDTH * AMG8833_HEIGHT * sizeof(int16_t), FB_ALLOC_NO_HINT);
|
||||
error |= omv_i2c_write_bytes(&fir_bus, AMG8833_ADDR, (uint8_t [1]) {AMG8833_TEMPERATURE_REGISTER}, 1, OMV_I2C_XFER_NO_STOP);
|
||||
error |= omv_i2c_write_bytes(&fir_bus,
|
||||
AMG8833_ADDR,
|
||||
(uint8_t [1]) {AMG8833_TEMPERATURE_REGISTER},
|
||||
1, OMV_I2C_XFER_NO_STOP);
|
||||
error |= omv_i2c_read_bytes(&fir_bus,
|
||||
AMG8833_ADDR,
|
||||
(uint8_t *) data,
|
||||
@ -217,22 +223,21 @@ static void fir_AMG8833_get_frame(float *Ta, float *To) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static mp_obj_t fir_get_ir(int w, int h, float Ta, float *To, bool mirror, bool flip, bool dst_transpose, bool src_transpose) {
|
||||
static mp_obj_t fir_get_ir(int w, int h, float Ta, float *To, bool mirror,
|
||||
bool flip, bool dst_transpose, bool src_transpose) {
|
||||
mp_obj_list_t *list = (mp_obj_list_t *) mp_obj_new_list(w * h, NULL);
|
||||
float min = FLT_MAX;
|
||||
float max = -FLT_MAX;
|
||||
int w_1 = w - 1;
|
||||
int h_1 = h - 1;
|
||||
|
||||
if (!src_transpose) {
|
||||
for (int y = 0; y < h; y++) {
|
||||
int y_dst = flip ? (h_1 - y) : y;
|
||||
int y_dst = flip ? (h - y - 1) : y;
|
||||
float *raw_row = To + (y * w);
|
||||
mp_obj_t *list_row = list->items + (y_dst * w);
|
||||
mp_obj_t *t_list_row = list->items + y_dst;
|
||||
|
||||
for (int x = 0; x < w; x++) {
|
||||
int x_dst = mirror ? (w_1 - x) : x;
|
||||
int x_dst = mirror ? (w - x - 1) : x;
|
||||
float raw = raw_row[x];
|
||||
|
||||
if (raw < min) {
|
||||
@ -254,13 +259,13 @@ static mp_obj_t fir_get_ir(int w, int h, float Ta, float *To, bool mirror, bool
|
||||
}
|
||||
} else {
|
||||
for (int x = 0; x < w; x++) {
|
||||
int x_dst = mirror ? (w_1 - x) : x;
|
||||
int x_dst = mirror ? (w - x - 1) : x;
|
||||
float *raw_row = To + (x * h);
|
||||
mp_obj_t *t_list_row = list->items + (x_dst * h);
|
||||
mp_obj_t *list_row = list->items + x_dst;
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
int y_dst = flip ? (h_1 - y) : y;
|
||||
int y_dst = flip ? (h - y - 1) : y;
|
||||
float raw = raw_row[y];
|
||||
|
||||
if (raw < min) {
|
||||
@ -318,10 +323,21 @@ static mp_obj_t py_fir_deinit() {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_deinit_obj, py_fir_deinit);
|
||||
|
||||
mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
mp_obj_t py_fir_init(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_type, ARG_refresh, ARG_resolution };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_type, MP_ARG_INT, {.u_int = -1 } },
|
||||
{ MP_QSTR_refresh, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1 } },
|
||||
{ MP_QSTR_resolution, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1 } },
|
||||
};
|
||||
|
||||
// Parse args.
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
py_fir_deinit();
|
||||
bool first_init = true;
|
||||
int type = py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_type), -1);
|
||||
int type = args[ARG_type].u_int;
|
||||
if (type == -1) {
|
||||
FIR_SCAN_RETRY:
|
||||
omv_i2c_init(&fir_bus, FIR_I2C_ID, OMV_I2C_SPEED_STANDARD);
|
||||
@ -379,14 +395,11 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
// Initialize the detected sensor.
|
||||
first_init = true;
|
||||
switch (type) {
|
||||
case FIR_NONE: {
|
||||
return mp_const_none;
|
||||
}
|
||||
#if (OMV_ENABLE_FIR_MLX90621 == 1)
|
||||
case FIR_MLX90621: {
|
||||
// parse refresh rate and ADC resolution
|
||||
int ir_fresh_rate = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_refresh), 64);
|
||||
int adc_resolution = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_resolution), 18);
|
||||
// Set refresh rate and ADC resolution
|
||||
uint32_t ir_fresh_rate = args[ARG_refresh].u_int != -1 ? args[ARG_refresh].u_int : 64;
|
||||
uint32_t adc_resolution = args[ARG_resolution].u_int != -1 ? args[ARG_resolution].u_int : 18;
|
||||
|
||||
// sanitize values
|
||||
ir_fresh_rate = 14 - __CLZ(__RBIT((ir_fresh_rate > 512) ? 512 : ((ir_fresh_rate < 1) ? 1 : ir_fresh_rate)));
|
||||
@ -431,9 +444,9 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90640 == 1)
|
||||
case FIR_MLX90640: {
|
||||
// parse refresh rate and ADC resolution
|
||||
int ir_fresh_rate = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_refresh), 32);
|
||||
int adc_resolution = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_resolution), 19);
|
||||
// Set refresh rate and ADC resolution
|
||||
uint32_t ir_fresh_rate = args[ARG_refresh].u_int != -1 ? args[ARG_refresh].u_int : 32;
|
||||
uint32_t adc_resolution = args[ARG_resolution].u_int != -1 ? args[ARG_resolution].u_int : 19;
|
||||
|
||||
// sanitize values
|
||||
ir_fresh_rate = __CLZ(__RBIT((ir_fresh_rate > 64) ? 64 : ((ir_fresh_rate < 1) ? 1 : ir_fresh_rate))) + 1;
|
||||
@ -477,9 +490,9 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90641 == 1)
|
||||
case FIR_MLX90641: {
|
||||
// parse refresh rate and ADC resolution
|
||||
int ir_fresh_rate = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_refresh), 32);
|
||||
int adc_resolution = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_resolution), 19);
|
||||
// Set refresh rate and ADC resolution
|
||||
uint32_t ir_fresh_rate = args[ARG_refresh].u_int != -1 ? args[ARG_refresh].u_int : 32;
|
||||
uint32_t adc_resolution = args[ARG_resolution].u_int != -1 ? args[ARG_resolution].u_int : 19;
|
||||
|
||||
// sanitize values
|
||||
ir_fresh_rate = __CLZ(__RBIT((ir_fresh_rate > 64) ? 64 : ((ir_fresh_rate < 1) ? 1 : ir_fresh_rate))) + 1;
|
||||
@ -579,26 +592,26 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_init_obj, 0, py_fir_init);
|
||||
|
||||
static mp_obj_t py_fir_type() {
|
||||
if (fir_sensor == FIR_NONE) {
|
||||
return mp_const_none;
|
||||
if (fir_sensor != FIR_NONE) {
|
||||
return mp_obj_new_int(fir_sensor);
|
||||
}
|
||||
return mp_obj_new_int(fir_sensor);
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_type_obj, py_fir_type);
|
||||
|
||||
static mp_obj_t py_fir_width() {
|
||||
if (fir_sensor == FIR_NONE) {
|
||||
return mp_const_none;
|
||||
if (fir_sensor != FIR_NONE) {
|
||||
return mp_obj_new_int(fir_width);
|
||||
}
|
||||
return mp_obj_new_int(fir_width);
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_width_obj, py_fir_width);
|
||||
|
||||
static mp_obj_t py_fir_height() {
|
||||
if (fir_sensor == FIR_NONE) {
|
||||
return mp_const_none;
|
||||
if (fir_sensor != FIR_NONE) {
|
||||
return mp_obj_new_int(fir_height);
|
||||
}
|
||||
return mp_obj_new_int(fir_height);
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_height_obj, py_fir_height);
|
||||
|
||||
@ -610,19 +623,16 @@ static mp_obj_t py_fir_refresh() {
|
||||
const int mlx_90640_1_refresh_rates[8] = {0, 1, 2, 4, 8, 16, 32, 64};
|
||||
#endif
|
||||
switch (fir_sensor) {
|
||||
case FIR_NONE:
|
||||
return mp_const_none;
|
||||
#if (OMV_ENABLE_FIR_MLX90621 == 1)
|
||||
case FIR_MLX90621:
|
||||
return mp_obj_new_int(mlx_90621_refresh_rates[fir_ir_fresh_rate]);
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90640 == 1) || (OMV_ENABLE_FIR_MLX90640 == 1)
|
||||
#if (OMV_ENABLE_FIR_MLX90640 == 1)
|
||||
case FIR_MLX90640:
|
||||
return mp_obj_new_int(mlx_90640_1_refresh_rates[fir_ir_fresh_rate]);
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90641 == 1)
|
||||
case FIR_MLX90641:
|
||||
#endif
|
||||
return mp_obj_new_int(mlx_90640_1_refresh_rates[fir_ir_fresh_rate]);
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_AMG8833 == 1)
|
||||
@ -634,26 +644,23 @@ static mp_obj_t py_fir_refresh() {
|
||||
return mp_obj_new_int(fir_ir_fresh_rate);
|
||||
#endif
|
||||
default:
|
||||
return mp_const_none;
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_refresh_obj, py_fir_refresh);
|
||||
|
||||
static mp_obj_t py_fir_resolution() {
|
||||
switch (fir_sensor) {
|
||||
case FIR_NONE:
|
||||
return mp_const_none;
|
||||
#if (OMV_ENABLE_FIR_MLX90621 == 1)
|
||||
case FIR_MLX90621:
|
||||
return mp_obj_new_int(fir_adc_resolution + 15);
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90640 == 1) || (OMV_ENABLE_FIR_MLX90640 == 1)
|
||||
#if (OMV_ENABLE_FIR_MLX90640 == 1)
|
||||
case FIR_MLX90640:
|
||||
return mp_obj_new_int(fir_adc_resolution + 16);
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90641 == 1)
|
||||
case FIR_MLX90641:
|
||||
#endif
|
||||
return mp_obj_new_int(fir_adc_resolution + 16);
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_AMG8833 == 1)
|
||||
@ -665,7 +672,7 @@ static mp_obj_t py_fir_resolution() {
|
||||
return mp_obj_new_int(fir_adc_resolution);
|
||||
#endif
|
||||
default:
|
||||
return mp_const_none;
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_resolution_obj, py_fir_resolution);
|
||||
@ -674,9 +681,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_resolution_obj, py_fir_resolution);
|
||||
static mp_obj_t py_fir_radiometric() {
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
return fir_lepton_get_radiometry();
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
|
||||
return mp_const_true;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_radiometric_obj, py_fir_radiometric);
|
||||
|
||||
@ -684,8 +691,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_radiometric_obj, py_fir_radiometric);
|
||||
static mp_obj_t py_fir_register_vsync_cb(mp_obj_t cb) {
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
fir_lepton_register_vsync_cb(cb);
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_fir_register_vsync_cb_obj, py_fir_register_vsync_cb);
|
||||
@ -694,8 +702,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_fir_register_vsync_cb_obj, py_fir_register_v
|
||||
static mp_obj_t py_fir_register_frame_cb(mp_obj_t cb) {
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
fir_lepton_register_frame_cb(cb);
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_fir_register_frame_cb_obj, py_fir_register_frame_cb);
|
||||
@ -703,17 +712,27 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_fir_register_frame_cb_obj, py_fir_register_f
|
||||
static mp_obj_t py_fir_get_frame_available() {
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
return fir_lepton_get_frame_available();
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
|
||||
return mp_const_true;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_get_frame_available_obj, py_fir_get_frame_available);
|
||||
|
||||
static mp_obj_t py_fir_trigger_ffc(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
fir_lepton_trigger_ffc(n_args, args, kw_args);
|
||||
}
|
||||
static mp_obj_t py_fir_trigger_ffc(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_timeout };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_timeout, MP_ARG_INT, {.u_int = -1 } },
|
||||
};
|
||||
|
||||
// Parse args.
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
fir_lepton_trigger_ffc(args[ARG_timeout].u_int);
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_trigger_ffc_obj, 0, py_fir_trigger_ffc);
|
||||
@ -721,9 +740,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_trigger_ffc_obj, 0, py_fir_trigger_ffc)
|
||||
|
||||
mp_obj_t py_fir_read_ta() {
|
||||
switch (fir_sensor) {
|
||||
case FIR_NONE: {
|
||||
return mp_const_none;
|
||||
}
|
||||
#if (OMV_ENABLE_FIR_MLX90621 == 1)
|
||||
case FIR_MLX90621: {
|
||||
fb_alloc_mark();
|
||||
@ -776,31 +792,38 @@ mp_obj_t py_fir_read_ta() {
|
||||
return fir_lepton_read_ta();
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_read_ta_obj, py_fir_read_ta);
|
||||
|
||||
mp_obj_t py_fir_read_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
bool arg_hmirror = py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hmirror), false);
|
||||
bool arg_vflip = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_vflip), false);
|
||||
fir_transposed = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_transpose), false);
|
||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||
int arg_timeout = py_helper_keyword_int(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_timeout), -1);
|
||||
#endif
|
||||
mp_obj_t py_fir_read_ir(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_hmirror, ARG_vflip, ARG_transpose, ARG_timeout };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_hmirror, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false } },
|
||||
{ MP_QSTR_vflip, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false } },
|
||||
{ MP_QSTR_transpose, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false } },
|
||||
{ MP_QSTR_timeout, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1 } },
|
||||
};
|
||||
|
||||
// Parse args.
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
fir_transposed = args[ARG_transpose].u_bool;
|
||||
|
||||
switch (fir_sensor) {
|
||||
case FIR_NONE: {
|
||||
return mp_const_none;
|
||||
}
|
||||
#if (OMV_ENABLE_FIR_MLX90621 == 1)
|
||||
case FIR_MLX90621: {
|
||||
fb_alloc_mark();
|
||||
float Ta, *To = fb_alloc(MLX90621_WIDTH * MLX90621_HEIGHT * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
fir_MLX90621_get_frame(&Ta, To);
|
||||
mp_obj_t result = fir_get_ir(MLX90621_WIDTH, MLX90621_HEIGHT, Ta, To,
|
||||
arg_hmirror ^ true, arg_vflip, fir_transposed, true);
|
||||
mp_obj_t result = fir_get_ir(MLX90621_WIDTH, MLX90621_HEIGHT, Ta, To, !args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, true);
|
||||
fb_alloc_free_till_mark();
|
||||
return result;
|
||||
}
|
||||
@ -810,8 +833,8 @@ mp_obj_t py_fir_read_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
fb_alloc_mark();
|
||||
float Ta, *To = fb_alloc(MLX90640_WIDTH * MLX90640_HEIGHT * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
fir_MLX90640_get_frame(&Ta, To);
|
||||
mp_obj_t result = fir_get_ir(MLX90640_WIDTH, MLX90640_HEIGHT, Ta, To,
|
||||
arg_hmirror ^ true, arg_vflip, fir_transposed, false);
|
||||
mp_obj_t result = fir_get_ir(MLX90640_WIDTH, MLX90640_HEIGHT, Ta, To, !args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, false);
|
||||
fb_alloc_free_till_mark();
|
||||
return result;
|
||||
}
|
||||
@ -821,8 +844,8 @@ mp_obj_t py_fir_read_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
fb_alloc_mark();
|
||||
float Ta, *To = fb_alloc(MLX90641_WIDTH * MLX90641_HEIGHT * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
fir_MLX90641_get_frame(&Ta, To);
|
||||
mp_obj_t result = fir_get_ir(MLX90641_WIDTH, MLX90641_HEIGHT, Ta, To,
|
||||
arg_hmirror ^ true, arg_vflip, fir_transposed, false);
|
||||
mp_obj_t result = fir_get_ir(MLX90641_WIDTH, MLX90641_HEIGHT, Ta, To, !args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, false);
|
||||
fb_alloc_free_till_mark();
|
||||
return result;
|
||||
}
|
||||
@ -832,313 +855,175 @@ mp_obj_t py_fir_read_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
fb_alloc_mark();
|
||||
float Ta, *To = fb_alloc(AMG8833_WIDTH * AMG8833_HEIGHT * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
fir_AMG8833_get_frame(&Ta, To);
|
||||
mp_obj_t result = fir_get_ir(AMG8833_WIDTH, AMG8833_HEIGHT, Ta, To,
|
||||
arg_hmirror ^ true, arg_vflip, fir_transposed, true);
|
||||
mp_obj_t result = fir_get_ir(AMG8833_WIDTH, AMG8833_HEIGHT, Ta, To, !args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, true);
|
||||
fb_alloc_free_till_mark();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||
case FIR_LEPTON: {
|
||||
return fir_lepton_read_ir(fir_width, fir_height, arg_hmirror, arg_vflip, fir_transposed, arg_timeout);
|
||||
return fir_lepton_read_ir(fir_width, fir_height, args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, args[ARG_timeout].u_int);
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_read_ir_obj, 0, py_fir_read_ir);
|
||||
|
||||
mp_obj_t py_fir_draw_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *dst_img = py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
mp_obj_t py_fir_draw_ir(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum {
|
||||
ARG_x, ARG_y, ARG_x_scale, ARG_y_scale, ARG_roi, ARG_channel, ARG_alpha,
|
||||
ARG_color_palette, ARG_alpha_palette, ARG_hint, ARG_scale
|
||||
};
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0 } },
|
||||
{ MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0 } },
|
||||
{ MP_QSTR_x_scale, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_y_scale, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_roi, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_rgb_channel, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1 } },
|
||||
{ MP_QSTR_alpha, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 256 } },
|
||||
{ MP_QSTR_color_palette, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_INT(COLOR_PALETTE_RAINBOW)} },
|
||||
{ MP_QSTR_alpha_palette, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_hint, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0 } },
|
||||
{ MP_QSTR_scale, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
};
|
||||
|
||||
image_t src_img;
|
||||
src_img.pixfmt = PIXFORMAT_GRAYSCALE;
|
||||
// Parse args.
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
size_t len;
|
||||
mp_obj_t *items, *arg_to;
|
||||
mp_obj_get_array(args[1], &len, &items);
|
||||
|
||||
if (len == 3) {
|
||||
src_img.w = mp_obj_get_int(items[0]);
|
||||
src_img.h = mp_obj_get_int(items[1]);
|
||||
mp_obj_get_array_fixed_n(items[2], src_img.w * src_img.h, &arg_to);
|
||||
} else if (fir_sensor != FIR_NONE) {
|
||||
src_img.w = fir_transposed ? fir_height : fir_width;
|
||||
src_img.h = fir_transposed ? fir_width : fir_height;
|
||||
// Handle if the user passed an array of the array.
|
||||
if (len == 1) {
|
||||
mp_obj_get_array_fixed_n(*items, src_img.w * src_img.h, &arg_to);
|
||||
} else {
|
||||
mp_obj_get_array_fixed_n(args[1], src_img.w * src_img.h, &arg_to);
|
||||
}
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_TypeError, MP_ERROR_TEXT("Invalid IR array!"));
|
||||
// Sanity checks
|
||||
if (fir_sensor == FIR_NONE) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
|
||||
int arg_x_off = 0;
|
||||
int arg_y_off = 0;
|
||||
uint offset = 2;
|
||||
if (n_args > 2) {
|
||||
if (MP_OBJ_IS_TYPE(args[2], &mp_type_tuple) || MP_OBJ_IS_TYPE(args[2], &mp_type_list)) {
|
||||
mp_obj_t *arg_vec;
|
||||
mp_obj_get_array_fixed_n(args[2], 2, &arg_vec);
|
||||
arg_x_off = mp_obj_get_int(arg_vec[0]);
|
||||
arg_y_off = mp_obj_get_int(arg_vec[1]);
|
||||
offset = 3;
|
||||
} else if (n_args > 3) {
|
||||
arg_x_off = mp_obj_get_int(args[2]);
|
||||
arg_y_off = mp_obj_get_int(args[3]);
|
||||
offset = 4;
|
||||
} else if (n_args > 2) {
|
||||
mp_raise_msg(&mp_type_TypeError, MP_ERROR_TEXT("Expected x and y offset!"));
|
||||
}
|
||||
if (args[ARG_channel].u_int < -1 || args[ARG_channel].u_int > 2) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("RGB channel can be 0, 1, or 2"));
|
||||
}
|
||||
|
||||
float arg_x_scale = 1.f;
|
||||
bool got_x_scale = py_helper_keyword_float_maybe(n_args, args,
|
||||
offset + 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_x_scale), &arg_x_scale);
|
||||
|
||||
float arg_y_scale = 1.f;
|
||||
bool got_y_scale = py_helper_keyword_float_maybe(n_args, args,
|
||||
offset + 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_y_scale), &arg_y_scale);
|
||||
|
||||
rectangle_t arg_roi;
|
||||
py_helper_keyword_rectangle_roi(&src_img, n_args, args, offset + 2, kw_args, &arg_roi);
|
||||
|
||||
float tmp_x_scale = dst_img->w / ((float) arg_roi.w);
|
||||
float tmp_y_scale = dst_img->h / ((float) arg_roi.h);
|
||||
float tmp_scale = IM_MIN(tmp_x_scale, tmp_y_scale);
|
||||
|
||||
if (n_args == 2) {
|
||||
arg_x_off = fast_floorf((dst_img->w - (arg_roi.w * tmp_scale)) / 2.f);
|
||||
arg_y_off = fast_floorf((dst_img->h - (arg_roi.h * tmp_scale)) / 2.f);
|
||||
if (args[ARG_alpha].u_int < 0 || args[ARG_alpha].u_int > 256) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Alpha ranges between 0 and 256"));
|
||||
}
|
||||
|
||||
if (!got_x_scale) {
|
||||
arg_x_scale = tmp_scale;
|
||||
}
|
||||
image_t src_img = {
|
||||
.w = fir_transposed ? fir_height : fir_width,
|
||||
.h = fir_transposed ? fir_width : fir_height,
|
||||
.pixfmt = PIXFORMAT_GRAYSCALE,
|
||||
//.data is allocated later.
|
||||
};
|
||||
|
||||
if (!got_y_scale) {
|
||||
arg_y_scale = tmp_scale;
|
||||
}
|
||||
image_t *dst_img = py_helper_arg_to_image(pos_args[0], ARG_IMAGE_MUTABLE);
|
||||
|
||||
int arg_rgb_channel = py_helper_keyword_int(n_args, args, offset + 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
|
||||
if ((arg_rgb_channel < -1) || (2 < arg_rgb_channel)) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("-1 <= rgb_channel <= 2!"));
|
||||
}
|
||||
mp_obj_t *ir_array;
|
||||
mp_obj_get_array_fixed_n(pos_args[1], src_img.w * src_img.h, &ir_array);
|
||||
|
||||
int arg_alpha = py_helper_keyword_int(n_args, args, offset + 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_alpha), 128);
|
||||
if ((arg_alpha < 0) || (256 < arg_alpha)) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("0 <= alpha <= 256!"));
|
||||
}
|
||||
rectangle_t roi = py_helper_arg_to_roi(args[ARG_roi].u_obj, &src_img);
|
||||
|
||||
const uint16_t *color_palette = py_helper_keyword_color_palette(n_args, args, offset + 5, kw_args, rainbow_table);
|
||||
const uint8_t *alpha_palette = py_helper_keyword_alpha_palette(n_args, args, offset + 6, kw_args, NULL);
|
||||
float x_scale = 1.0f;
|
||||
float y_scale = 1.0f;
|
||||
py_helper_arg_to_scale(args[ARG_x_scale].u_obj, args[ARG_y_scale].u_obj, &x_scale, &y_scale, &roi);
|
||||
|
||||
image_hint_t hint = py_helper_keyword_int(n_args, args, offset + 7, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hint), 0);
|
||||
float min = FLT_MAX;
|
||||
float max = -FLT_MAX;
|
||||
py_helper_arg_to_minmax(args[ARG_scale].u_obj, &min, &max, ir_array, src_img.w * src_img.h);
|
||||
|
||||
float arg_x_size;
|
||||
bool got_x_size = py_helper_keyword_float_maybe(n_args,
|
||||
args,
|
||||
offset + 8,
|
||||
kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_x_size),
|
||||
&arg_x_size);
|
||||
|
||||
float arg_y_size;
|
||||
bool got_y_size = py_helper_keyword_float_maybe(n_args,
|
||||
args,
|
||||
offset + 9,
|
||||
kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_y_size),
|
||||
&arg_y_size);
|
||||
|
||||
if (got_x_scale && got_x_size) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Choose either x_scale or x_size not both!"));
|
||||
}
|
||||
|
||||
if (got_y_scale && got_y_size) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Choose either y_scale or y_size not both!"));
|
||||
}
|
||||
|
||||
if (got_x_size) {
|
||||
arg_x_scale = arg_x_size / arg_roi.w;
|
||||
}
|
||||
|
||||
if (got_y_size) {
|
||||
arg_y_scale = arg_y_size / arg_roi.h;
|
||||
}
|
||||
|
||||
if ((!got_x_scale) && (!got_x_size) && got_y_size) {
|
||||
arg_x_scale = arg_y_scale;
|
||||
}
|
||||
|
||||
if ((!got_y_scale) && (!got_y_size) && got_x_size) {
|
||||
arg_y_scale = arg_x_scale;
|
||||
}
|
||||
|
||||
mp_obj_t scale_obj = py_helper_keyword_object(n_args, args, offset + 10, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_scale), NULL);
|
||||
float min = FLT_MAX, max = -FLT_MAX;
|
||||
|
||||
if (scale_obj) {
|
||||
mp_obj_t *arg_scale;
|
||||
mp_obj_get_array_fixed_n(scale_obj, 2, &arg_scale);
|
||||
min = mp_obj_get_float(arg_scale[0]);
|
||||
max = mp_obj_get_float(arg_scale[1]);
|
||||
} else {
|
||||
for (int i = 0, ii = src_img.w * src_img.h; i < ii; i++) {
|
||||
float temp = mp_obj_get_float(arg_to[i]);
|
||||
if (temp < min) {
|
||||
min = temp;
|
||||
}
|
||||
if (temp > max) {
|
||||
max = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
const uint16_t *color_palette = py_helper_arg_to_palette(args[ARG_color_palette].u_obj, PIXFORMAT_RGB565);
|
||||
const uint8_t *alpha_palette = py_helper_arg_to_palette(args[ARG_alpha_palette].u_obj, PIXFORMAT_GRAYSCALE);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
src_img.data = fb_alloc(src_img.w * src_img.h * sizeof(uint8_t), FB_ALLOC_NO_HINT);
|
||||
fir_fill_image_float_obj(&src_img, arg_to, min, max);
|
||||
fir_fill_image_float_obj(&src_img, ir_array, min, max);
|
||||
|
||||
imlib_draw_image(dst_img, &src_img, arg_x_off, arg_y_off, arg_x_scale, arg_y_scale, &arg_roi,
|
||||
arg_rgb_channel, arg_alpha, color_palette, alpha_palette, hint, NULL, NULL, NULL);
|
||||
imlib_draw_image(dst_img, &src_img, args[ARG_x].u_int, args[ARG_y].u_int, x_scale, y_scale, &roi,
|
||||
args[ARG_channel].u_int, args[ARG_alpha].u_int, color_palette, alpha_palette,
|
||||
args[ARG_hint].u_int, NULL, NULL, NULL);
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_draw_ir_obj, 2, py_fir_draw_ir);
|
||||
|
||||
mp_obj_t py_fir_snapshot(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
if (fir_sensor == FIR_NONE) {
|
||||
return mp_const_none;
|
||||
mp_obj_t py_fir_snapshot(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum {
|
||||
ARG_hmirror, ARG_vflip, ARG_transpose, ARG_x_scale, ARG_y_scale, ARG_roi, ARG_channel,
|
||||
ARG_alpha, ARG_color_palette, ARG_alpha_palette, ARG_hint, ARG_scale, ARG_pixformat,
|
||||
ARG_copy_to_fb, ARG_timeout
|
||||
};
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_hmirror, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false } },
|
||||
{ MP_QSTR_vflip, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false } },
|
||||
{ MP_QSTR_transpose, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false } },
|
||||
{ MP_QSTR_x_scale, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_y_scale, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_roi, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_rgb_channel, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1 } },
|
||||
{ MP_QSTR_alpha, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 256 } },
|
||||
{ MP_QSTR_color_palette, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_INT(COLOR_PALETTE_RAINBOW)} },
|
||||
{ MP_QSTR_alpha_palette, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_hint, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0 } },
|
||||
{ MP_QSTR_scale, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_pixformat, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = PIXFORMAT_RGB565 } },
|
||||
{ MP_QSTR_copy_to_fb, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false } },
|
||||
{ MP_QSTR_timeout, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1 } },
|
||||
};
|
||||
|
||||
// Parse args.
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// Sanity checks
|
||||
if (args[ARG_channel].u_int < -1 || args[ARG_channel].u_int > 2) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("RGB channel can be 0, 1, or 2"));
|
||||
}
|
||||
|
||||
bool arg_hmirror = py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hmirror), false);
|
||||
bool arg_vflip = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_vflip), false);
|
||||
bool arg_transpose = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_transpose), false);
|
||||
|
||||
image_t src_img;
|
||||
src_img.w = arg_transpose ? fir_height : fir_width;
|
||||
src_img.h = arg_transpose ? fir_width : fir_height;
|
||||
src_img.pixfmt = PIXFORMAT_GRAYSCALE;
|
||||
|
||||
float arg_x_scale = 1.f;
|
||||
bool got_x_scale = py_helper_keyword_float_maybe(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_x_scale), &arg_x_scale);
|
||||
|
||||
float arg_y_scale = 1.f;
|
||||
bool got_y_scale = py_helper_keyword_float_maybe(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_y_scale), &arg_y_scale);
|
||||
|
||||
rectangle_t arg_roi;
|
||||
py_helper_keyword_rectangle_roi(&src_img, n_args, args, 5, kw_args, &arg_roi);
|
||||
|
||||
int arg_rgb_channel = py_helper_keyword_int(n_args, args, 6, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
|
||||
if ((arg_rgb_channel < -1) || (2 < arg_rgb_channel)) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("-1 <= rgb_channel <= 2!"));
|
||||
if (args[ARG_alpha].u_int < 0 || args[ARG_alpha].u_int > 256) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Alpha ranges between 0 and 256"));
|
||||
}
|
||||
|
||||
int arg_alpha = py_helper_keyword_int(n_args, args, 7, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_alpha), 128);
|
||||
if ((arg_alpha < 0) || (256 < arg_alpha)) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("0 <= alpha <= 256!"));
|
||||
if ((args[ARG_pixformat].u_int != PIXFORMAT_GRAYSCALE) && (args[ARG_pixformat].u_int != PIXFORMAT_RGB565)) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid pixformat"));
|
||||
}
|
||||
|
||||
const uint16_t *color_palette = py_helper_keyword_color_palette(n_args, args, 8, kw_args, rainbow_table);
|
||||
const uint8_t *alpha_palette = py_helper_keyword_alpha_palette(n_args, args, 9, kw_args, NULL);
|
||||
image_t src_img = {
|
||||
.w = args[ARG_transpose].u_bool ? fir_height : fir_width,
|
||||
.h = args[ARG_transpose].u_bool ? fir_width : fir_height,
|
||||
.pixfmt = PIXFORMAT_GRAYSCALE,
|
||||
//.data is allocated later.
|
||||
};
|
||||
|
||||
image_hint_t hint = py_helper_keyword_int(n_args, args, 10, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hint), 0);
|
||||
rectangle_t roi = py_helper_arg_to_roi(args[ARG_roi].u_obj, &src_img);
|
||||
|
||||
float arg_x_size;
|
||||
bool got_x_size = py_helper_keyword_float_maybe(n_args, args, 11, kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_x_size), &arg_x_size);
|
||||
float x_scale = 1.0f;
|
||||
float y_scale = 1.0f;
|
||||
py_helper_arg_to_scale(args[ARG_x_scale].u_obj, args[ARG_y_scale].u_obj, &x_scale, &y_scale, &roi);
|
||||
|
||||
float arg_y_size;
|
||||
bool got_y_size = py_helper_keyword_float_maybe(n_args, args, 12, kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_y_size), &arg_y_size);
|
||||
|
||||
if (got_x_scale && got_x_size) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Choose either x_scale or x_size not both!"));
|
||||
}
|
||||
|
||||
if (got_y_scale && got_y_size) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Choose either y_scale or y_size not both!"));
|
||||
}
|
||||
|
||||
if (got_x_size) {
|
||||
arg_x_scale = arg_x_size / arg_roi.w;
|
||||
}
|
||||
|
||||
if (got_y_size) {
|
||||
arg_y_scale = arg_y_size / arg_roi.h;
|
||||
}
|
||||
|
||||
if ((!got_x_scale) && (!got_x_size) && got_y_size) {
|
||||
arg_x_scale = arg_y_scale;
|
||||
}
|
||||
|
||||
if ((!got_y_scale) && (!got_y_size) && got_x_size) {
|
||||
arg_y_scale = arg_x_scale;
|
||||
}
|
||||
|
||||
mp_obj_t scale_obj = py_helper_keyword_object(n_args, args, 13, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_scale), NULL);
|
||||
float min, max;
|
||||
|
||||
if (scale_obj) {
|
||||
mp_obj_t *arg_scale;
|
||||
mp_obj_get_array_fixed_n(scale_obj, 2, &arg_scale);
|
||||
min = mp_obj_get_float(arg_scale[0]);
|
||||
max = mp_obj_get_float(arg_scale[1]);
|
||||
}
|
||||
|
||||
int arg_pixformat = py_helper_keyword_int(n_args, args, 14, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_pixformat), PIXFORMAT_RGB565);
|
||||
if ((arg_pixformat != PIXFORMAT_GRAYSCALE) && (arg_pixformat != PIXFORMAT_RGB565)) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid pixformat!"));
|
||||
}
|
||||
|
||||
mp_obj_t copy_to_fb_obj = py_helper_keyword_object(n_args, args, 15, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy_to_fb), NULL);
|
||||
bool copy_to_fb = false;
|
||||
image_t *arg_other = NULL;
|
||||
|
||||
if (copy_to_fb_obj) {
|
||||
if (mp_obj_is_integer(copy_to_fb_obj)) {
|
||||
copy_to_fb = mp_obj_get_int(copy_to_fb_obj);
|
||||
} else {
|
||||
arg_other = py_helper_arg_to_image(copy_to_fb_obj, ARG_IMAGE_UNCOMPRESSED);
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_fb) {
|
||||
framebuffer_update_jpeg_buffer();
|
||||
}
|
||||
|
||||
image_t dst_img;
|
||||
dst_img.w = fast_floorf(arg_roi.w * arg_x_scale);
|
||||
dst_img.h = fast_floorf(arg_roi.h * arg_y_scale);
|
||||
dst_img.pixfmt = (arg_pixformat == PIXFORMAT_RGB565) ? PIXFORMAT_RGB565 : PIXFORMAT_GRAYSCALE;
|
||||
|
||||
size_t size = image_size(&dst_img);
|
||||
|
||||
if (copy_to_fb) {
|
||||
image_t dst_img = {
|
||||
.w = fast_floorf(roi.w * x_scale),
|
||||
.h = fast_floorf(roi.h * y_scale),
|
||||
.pixfmt = args[ARG_pixformat].u_int,
|
||||
};
|
||||
if (args[ARG_copy_to_fb].u_bool) {
|
||||
py_helper_set_to_framebuffer(&dst_img);
|
||||
} else if (arg_other) {
|
||||
bool fb = py_helper_is_equal_to_framebuffer(arg_other);
|
||||
size_t buf_size = fb ? framebuffer_get_buffer_size() : image_size(arg_other);
|
||||
PY_ASSERT_TRUE_MSG((size <= buf_size),
|
||||
"The new image won't fit in the target frame buffer!");
|
||||
dst_img.data = arg_other->data;
|
||||
memcpy(arg_other, &dst_img, sizeof(image_t));
|
||||
py_helper_update_framebuffer(&dst_img);
|
||||
} else {
|
||||
dst_img.data = xalloc(size);
|
||||
dst_img.data = xalloc(image_size(&dst_img));
|
||||
}
|
||||
|
||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||
int arg_timeout = py_helper_keyword_int(n_args, args, 16, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_timeout), -1);
|
||||
#endif
|
||||
float min = FLT_MAX;
|
||||
float max = -FLT_MAX;
|
||||
py_helper_arg_to_minmax(args[ARG_scale].u_obj, &min, &max, NULL, 0);
|
||||
|
||||
const uint16_t *color_palette = py_helper_arg_to_palette(args[ARG_color_palette].u_obj, PIXFORMAT_RGB565);
|
||||
const uint8_t *alpha_palette = py_helper_arg_to_palette(args[ARG_alpha_palette].u_obj, PIXFORMAT_GRAYSCALE);
|
||||
|
||||
fb_alloc_mark();
|
||||
// Allocate source image data.
|
||||
src_img.data = fb_alloc(src_img.w * src_img.h * sizeof(uint8_t), FB_ALLOC_NO_HINT);
|
||||
|
||||
switch (fir_sensor) {
|
||||
@ -1146,14 +1031,11 @@ mp_obj_t py_fir_snapshot(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
case FIR_MLX90621: {
|
||||
float Ta, *To = fb_alloc(MLX90621_WIDTH * MLX90621_HEIGHT * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
fir_MLX90621_get_frame(&Ta, To);
|
||||
|
||||
if (!scale_obj) {
|
||||
if (args[ARG_scale].u_obj == mp_const_none) {
|
||||
fast_get_min_max(To, MLX90621_WIDTH * MLX90621_HEIGHT, &min, &max);
|
||||
}
|
||||
|
||||
imlib_fill_image_from_float(&src_img, MLX90621_WIDTH, MLX90621_HEIGHT, To, min, max,
|
||||
arg_hmirror ^ true, arg_vflip, arg_transpose, true);
|
||||
fb_free();
|
||||
imlib_fill_image_from_float(&src_img, MLX90621_WIDTH, MLX90621_HEIGHT, To, min, max, !args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, true);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -1161,14 +1043,11 @@ mp_obj_t py_fir_snapshot(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
case FIR_MLX90640: {
|
||||
float Ta, *To = fb_alloc(MLX90640_WIDTH * MLX90640_HEIGHT * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
fir_MLX90640_get_frame(&Ta, To);
|
||||
|
||||
if (!scale_obj) {
|
||||
if (args[ARG_scale].u_obj == mp_const_none) {
|
||||
fast_get_min_max(To, MLX90640_WIDTH * MLX90640_HEIGHT, &min, &max);
|
||||
}
|
||||
|
||||
imlib_fill_image_from_float(&src_img, MLX90640_WIDTH, MLX90640_HEIGHT, To, min, max,
|
||||
arg_hmirror ^ true, arg_vflip, arg_transpose, false);
|
||||
fb_free();
|
||||
imlib_fill_image_from_float(&src_img, MLX90640_WIDTH, MLX90640_HEIGHT, To, min, max, !args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, false);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -1176,14 +1055,11 @@ mp_obj_t py_fir_snapshot(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
case FIR_MLX90641: {
|
||||
float Ta, *To = fb_alloc(MLX90641_WIDTH * MLX90641_HEIGHT * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
fir_MLX90641_get_frame(&Ta, To);
|
||||
|
||||
if (!scale_obj) {
|
||||
if (args[ARG_scale].u_obj == mp_const_none) {
|
||||
fast_get_min_max(To, MLX90641_WIDTH * MLX90641_HEIGHT, &min, &max);
|
||||
}
|
||||
|
||||
imlib_fill_image_from_float(&src_img, MLX90641_WIDTH, MLX90641_HEIGHT, To, min, max,
|
||||
arg_hmirror ^ true, arg_vflip, arg_transpose, false);
|
||||
fb_free();
|
||||
imlib_fill_image_from_float(&src_img, MLX90641_WIDTH, MLX90641_HEIGHT, To, min, max, !args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, false);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -1191,58 +1067,59 @@ mp_obj_t py_fir_snapshot(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
case FIR_AMG8833: {
|
||||
float Ta, *To = fb_alloc(AMG8833_WIDTH * AMG8833_HEIGHT * sizeof(float), FB_ALLOC_NO_HINT);
|
||||
fir_AMG8833_get_frame(&Ta, To);
|
||||
|
||||
if (!scale_obj) {
|
||||
if (args[ARG_scale].u_obj == mp_const_none) {
|
||||
fast_get_min_max(To, AMG8833_WIDTH * AMG8833_HEIGHT, &min, &max);
|
||||
}
|
||||
|
||||
imlib_fill_image_from_float(&src_img, AMG8833_WIDTH, AMG8833_HEIGHT, To, min, max,
|
||||
arg_hmirror ^ true, arg_vflip, arg_transpose, true);
|
||||
fb_free();
|
||||
imlib_fill_image_from_float(&src_img, AMG8833_WIDTH, AMG8833_HEIGHT, To, min, max, !args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, true);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||
case FIR_LEPTON: {
|
||||
fir_lepton_fill_image(&src_img, fir_width, fir_height, !scale_obj, min, max,
|
||||
arg_hmirror, arg_vflip, arg_transpose, arg_timeout);
|
||||
bool auto_range = args[ARG_scale].u_obj == mp_const_none;
|
||||
fir_lepton_fill_image(&src_img, fir_width, fir_height, auto_range, min, max,
|
||||
args[ARG_hmirror].u_bool, args[ARG_vflip].u_bool,
|
||||
args[ARG_transpose].u_bool, args[ARG_timeout].u_int);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
break;
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
}
|
||||
|
||||
imlib_draw_image(&dst_img, &src_img, 0, 0, arg_x_scale, arg_y_scale,
|
||||
&arg_roi, arg_rgb_channel, arg_alpha, color_palette, alpha_palette,
|
||||
(hint & (~IMAGE_HINT_CENTER)) | IMAGE_HINT_BLACK_BACKGROUND, NULL, NULL, NULL);
|
||||
imlib_draw_image(&dst_img, &src_img, 0, 0, x_scale, y_scale, &roi,
|
||||
args[ARG_channel].u_int, args[ARG_alpha].u_int, color_palette, alpha_palette,
|
||||
(args[ARG_hint].u_int & (~IMAGE_HINT_CENTER)) | IMAGE_HINT_BLACK_BACKGROUND, NULL, NULL, NULL);
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
if (args[ARG_copy_to_fb].u_bool) {
|
||||
framebuffer_update_jpeg_buffer();
|
||||
}
|
||||
return py_image_from_struct(&dst_img);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_snapshot_obj, 0, py_fir_snapshot);
|
||||
|
||||
STATIC const mp_rom_map_elem_t globals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_fir) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_NONE), MP_ROM_INT(FIR_NONE) },
|
||||
#if (OMV_ENABLE_FIR_MLX90621 == 1)
|
||||
#if (OMV_ENABLE_FIR_MLX90621 == 1)
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_SHIELD), MP_ROM_INT(FIR_MLX90621) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_MLX90621), MP_ROM_INT(FIR_MLX90621) },
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90640 == 1)
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90640 == 1)
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_MLX90640), MP_ROM_INT(FIR_MLX90640) },
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90641 == 1)
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_MLX90641 == 1)
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_MLX90641), MP_ROM_INT(FIR_MLX90641) },
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_AMG8833 == 1)
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_AMG8833 == 1)
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_AMG8833), MP_ROM_INT(FIR_AMG8833) },
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||
#endif
|
||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_LEPTON), MP_ROM_INT(FIR_LEPTON) },
|
||||
#endif
|
||||
#endif
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&py_fir_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&py_fir_deinit_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&py_fir_type_obj) },
|
||||
@ -1250,23 +1127,23 @@ STATIC const mp_rom_map_elem_t globals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&py_fir_height_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&py_fir_refresh_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_resolution), MP_ROM_PTR(&py_fir_resolution_obj) },
|
||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||
{ MP_ROM_QSTR(MP_QSTR_radiometric), MP_ROM_PTR(&py_fir_radiometric_obj) },
|
||||
#if defined(OMV_FIR_LEPTON_VSYNC_PRESENT)
|
||||
#if defined(OMV_FIR_LEPTON_VSYNC_PRESENT)
|
||||
{ MP_ROM_QSTR(MP_QSTR_register_vsync_cb), MP_ROM_PTR(&py_fir_register_vsync_cb_obj) },
|
||||
#else
|
||||
#else
|
||||
{ MP_ROM_QSTR(MP_QSTR_register_vsync_cb), MP_ROM_PTR(&py_func_unavailable_obj) },
|
||||
#endif
|
||||
#endif
|
||||
{ MP_ROM_QSTR(MP_QSTR_register_frame_cb), MP_ROM_PTR(&py_fir_register_frame_cb_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_get_frame_available), MP_ROM_PTR(&py_fir_get_frame_available_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_trigger_ffc), MP_ROM_PTR(&py_fir_trigger_ffc_obj) },
|
||||
#else
|
||||
#else
|
||||
{ MP_ROM_QSTR(MP_QSTR_radiometric), MP_ROM_PTR(&py_func_unavailable_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_register_vsync_cb), MP_ROM_PTR(&py_func_unavailable_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_register_frame_cb), MP_ROM_PTR(&py_func_unavailable_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_get_frame_available), MP_ROM_PTR(&py_func_unavailable_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_trigger_ffc), MP_ROM_PTR(&py_func_unavailable_obj) },
|
||||
#endif
|
||||
#endif
|
||||
{ MP_ROM_QSTR(MP_QSTR_read_ta), MP_ROM_PTR(&py_fir_read_ta_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read_ir), MP_ROM_PTR(&py_fir_read_ir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_draw_ir), MP_ROM_PTR(&py_fir_draw_ir_obj) },
|
||||
|
||||
@ -145,9 +145,9 @@ void fir_lepton_spi_callback(omv_spi_t *spi, void *userdata, void *buf) {
|
||||
|
||||
// Are we in sync with the flir lepton?
|
||||
if ((pid != fir_lepton_spi_rx_cb_expected_pid)
|
||||
#if defined(OMV_FIR_LEPTON_CHECK_CRC)
|
||||
#if defined(OMV_FIR_LEPTON_CHECK_CRC)
|
||||
|| (!fir_lepton_spi_check_crc(base))
|
||||
#endif
|
||||
#endif
|
||||
|| (fir_lepton_3 && (pid == VOSPI_SPECIAL_PACKET) && (sid != fir_lepton_spi_rx_cb_expected_sid))) {
|
||||
fir_lepton_spi_rx_cb_expected_pid = 0;
|
||||
fir_lepton_spi_rx_cb_expected_sid = 0;
|
||||
@ -588,13 +588,11 @@ void fir_lepton_fill_image(image_t *img, int w, int h, bool auto_range, float mi
|
||||
}
|
||||
}
|
||||
|
||||
void fir_lepton_trigger_ffc(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
void fir_lepton_trigger_ffc(int timeout) {
|
||||
if (LEP_RunSysFFCNormalization(&fir_lepton_handle) != LEP_OK) {
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("FFC Error!"));
|
||||
}
|
||||
|
||||
int timeout = py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_timeout), -1);
|
||||
|
||||
if (timeout >= 0) {
|
||||
for (uint32_t start = mp_hal_ticks_ms();;) {
|
||||
LEP_SYS_STATUS_E status;
|
||||
|
||||
@ -20,5 +20,5 @@ mp_obj_t fir_lepton_read_ta();
|
||||
mp_obj_t fir_lepton_read_ir(int w, int h, bool mirror, bool flip, bool transpose, int timeout);
|
||||
void fir_lepton_fill_image(image_t *img, int w, int h, bool auto_range, float min, float max,
|
||||
bool mirror, bool flip, bool transpose, int timeout);
|
||||
void fir_lepton_trigger_ffc(uint n_args, const mp_obj_t *args, mp_map_t *kw_args);
|
||||
void fir_lepton_trigger_ffc(int timeout);
|
||||
#endif // __PY_FIR_LEPTON_H__
|
||||
|
||||
Loading…
Reference in New Issue
Block a user