lib/imlib: Refactor fill_image_from_lepton out of py_fir_lepton.

This commit is contained in:
Kwabena W. Agyeman 2025-06-20 22:01:19 -07:00
parent 7a9e1f31ac
commit 8e543c2a96
5 changed files with 86 additions and 79 deletions

View File

@ -456,6 +456,76 @@ void imlib_fill_image_from_float(image_t *img, int w, int h, float *data, float
}
}
// This function fills a grayscale image from an array of lepton 8/14/16-bit values that are scaled
// between min and max. The image w*h must equal the floating point array w*h.
void imlib_fill_image_from_lepton(image_t *img, int w, int h, uint16_t *data, float min, float max,
bool auto_range, bool radiometric, int kelvin_offset,
bool mirror, bool flip, bool transpose) {
int new_min;
int new_max;
if (auto_range) {
new_min = INT_MAX;
new_max = INT_MIN;
for (int i = 0; i < w * h; i++) {
int temp = data[i];
if (!radiometric) {
temp = (temp - 8192) + kelvin_offset;
}
if (temp < new_min) {
new_min = temp;
}
if (temp > new_max) {
new_max = temp;
}
}
} else {
float tmp = min;
min = (min < max) ? min : max;
max = (max > tmp) ? max : tmp;
new_min = fast_roundf((min + 273.15f) * 100.f); // to kelvin
new_max = fast_roundf((max + 273.15f) * 100.f); // to kelvin
}
float diff = 255.f / (new_max - new_min);
for (int y = 0; y < h; y++) {
int y_dst = flip ? (h - 1 - y) : y;
const uint16_t *raw_row = data + (y * w);
uint8_t *row_pointer = ((uint8_t *) img->data) + (y_dst * w);
uint8_t *t_row_pointer = ((uint8_t *) img->data) + y_dst;
for (int x = 0; x < w; x++) {
int x_dst = mirror ? (w - 1 - x) : x;
int raw = raw_row[x];
if (!radiometric) {
raw = (raw - 8192) + kelvin_offset;
}
if (raw < new_min) {
raw = new_min;
}
if (raw > new_max) {
raw = new_max;
}
int pixel = __USAT(fast_roundf((raw - new_min) * diff), 8);
if (!transpose) {
row_pointer[x_dst] = pixel;
} else {
t_row_pointer[x_dst * h] = pixel;
}
}
}
}
int8_t imlib_rgb565_to_l(uint16_t pixel) {
float r_lin = xyz_table[COLOR_RGB565_TO_R8(pixel)];
float g_lin = xyz_table[COLOR_RGB565_TO_G8(pixel)];

View File

@ -1187,6 +1187,9 @@ void imlib_deinit_all();
// Generic Helper Functions
void imlib_fill_image_from_float(image_t *img, int w, int h, float *data, float min, float max,
bool mirror, bool flip, bool dst_transpose, bool src_transpose);
void imlib_fill_image_from_lepton(image_t *img, int w, int h, uint16_t *data, float min, float max,
bool auto_range, bool radiometric, int kelvin_offset,
bool mirror, bool flip, bool transpose);
// Bayer Image Processing
pixformat_t imlib_bayer_shift(pixformat_t pixfmt, int x, int y, bool transpose);

View File

@ -1089,9 +1089,10 @@ mp_obj_t py_fir_snapshot(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
#if (OMV_FIR_LEPTON_ENABLE == 1)
case FIR_LEPTON: {
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);
imlib_fill_image_from_lepton(&src_img, fir_width, fir_height,
fir_lepton_get_frame(args[ARG_timeout].u_int), min, max, auto_range,
fir_lepton_get_radiometry_enabled(), fir_lepton_get_temperature(),
args[ARG_hmirror].u_bool, args[ARG_vflip].u_bool, args[ARG_transpose].u_bool);
break;
}
#endif

View File

@ -441,7 +441,7 @@ mp_obj_t fir_lepton_get_frame_available() {
return mp_obj_new_bool(framebuffer_tail != framebuffer_head);
}
static const uint16_t *fir_lepton_get_frame(int timeout) {
uint16_t *fir_lepton_get_frame(int timeout) {
int sampled_framebuffer_tail = framebuffer_tail;
if (timeout >= 0) {
@ -464,7 +464,11 @@ static const uint16_t *fir_lepton_get_frame(int timeout) {
return framebuffers[sampled_framebuffer_tail];
}
static int fir_lepton_get_temperature() {
bool fir_lepton_get_radiometry_enabled() {
return fir_lepton_rad_en;
}
int fir_lepton_get_temperature() {
LEP_SYS_FPA_TEMPERATURE_KELVIN_T kelvin;
if (LEP_GetSysFpaTemperatureKelvin(&fir_lepton_handle, &kelvin) != LEP_OK) {
@ -529,78 +533,6 @@ mp_obj_t fir_lepton_read_ir(int w, int h, bool mirror, bool flip, bool transpose
return mp_obj_new_tuple(4, tuple);
}
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) {
int kelvin = fir_lepton_get_temperature();
const uint16_t *data = fir_lepton_get_frame(timeout);
int new_min;
int new_max;
if (auto_range) {
new_min = INT_MAX;
new_max = INT_MIN;
for (int i = 0, ii = w * h; i < ii; i++) {
int temp = data[i];
if (!fir_lepton_rad_en) {
temp = (temp - 8192) + kelvin;
}
if (temp < new_min) {
new_min = temp;
}
if (temp > new_max) {
new_max = temp;
}
}
} else {
float tmp = min;
min = (min < max) ? min : max;
max = (max > tmp) ? max : tmp;
new_min = fast_roundf((min + 273.15f) * 100.f); // to kelvin
new_max = fast_roundf((max + 273.15f) * 100.f); // to kelvin
}
float diff = 255.f / (new_max - new_min);
int w_1 = w - 1;
int h_1 = h - 1;
for (int y = 0; y < h; y++) {
int y_dst = flip ? (h_1 - y) : y;
const uint16_t *raw_row = data + (y * w);
uint8_t *row_pointer = ((uint8_t *) img->data) + (y_dst * w);
uint8_t *t_row_pointer = ((uint8_t *) img->data) + y_dst;
for (int x = 0; x < w; x++) {
int x_dst = mirror ? (w_1 - x) : x;
int raw = raw_row[x];
if (!fir_lepton_rad_en) {
raw = (raw - 8192) + kelvin;
}
if (raw < new_min) {
raw = new_min;
}
if (raw > new_max) {
raw = new_max;
}
int pixel = fast_roundf((raw - new_min) * diff);
pixel = __USAT(pixel, 8);
if (!transpose) {
row_pointer[x_dst] = pixel;
} else {
t_row_pointer[x_dst * h] = pixel;
}
}
}
}
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!"));

View File

@ -31,9 +31,10 @@ void fir_lepton_register_vsync_cb(mp_obj_t cb);
mp_obj_t fir_lepton_get_radiometry();
void fir_lepton_register_frame_cb(mp_obj_t cb);
mp_obj_t fir_lepton_get_frame_available();
uint16_t *fir_lepton_get_frame(int timeout);
bool fir_lepton_get_radiometry_enabled();
int fir_lepton_get_temperature();
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(int timeout);
#endif // __PY_FIR_LEPTON_H__