From a74dd50eaf19d423ff7ee3066f853017afc2ed82 Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Thu, 24 Mar 2016 19:52:00 -0400 Subject: [PATCH] Improved IR code. Return min and max from read_ir now. Also, made drawing functions take IR values. Example scripts have been updated to work with the new module code. --- src/omv/py/py_fir.c | 46 +++++++++++++++---------------- usr/examples/fir.py | 21 +++++++++++++++ usr/examples/fir_lcd.py | 23 ++++++++++++++++ usr/examples/mlx.py | 51 ----------------------------------- usr/examples/mlx_lcd.py | 60 ----------------------------------------- 5 files changed, 66 insertions(+), 135 deletions(-) create mode 100644 usr/examples/fir.py create mode 100644 usr/examples/fir_lcd.py delete mode 100644 usr/examples/mlx.py delete mode 100644 usr/examples/mlx_lcd.py diff --git a/src/omv/py/py_fir.c b/src/omv/py/py_fir.c index 85068a742..5f474cd10 100644 --- a/src/omv/py/py_fir.c +++ b/src/omv/py/py_fir.c @@ -253,8 +253,8 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) int16_t a_common = (int16_t)((eeprom[CAL_ACOMMON_H]<<8)|eeprom[CAL_ACOMMON_L]); uint8_t a_i_scale = (uint8_t)((eeprom[CAL_AI_SCALE]&0xF0)>>4); uint8_t b_i_scale = (uint8_t)(eeprom[CAL_BI_SCALE]&0x0F); - uint16_t aplha_0 = (uint16_t)((eeprom[CAL_A0_H]<<8)|eeprom[CAL_A0_L]); - uint8_t aplha_0_scale = (uint8_t)eeprom[CAL_A0_SCALE]; + uint16_t alpha_0 = (uint16_t)((eeprom[CAL_A0_H]<<8)|eeprom[CAL_A0_L]); + uint8_t alpha_0_scale = (uint8_t)eeprom[CAL_A0_SCALE]; uint8_t delta_a_scale = (uint8_t)eeprom[CAL_D_A_SCALE]; for (int i=0; i<64; i++) { @@ -265,7 +265,7 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) b_ij[i] = ((int8_t)eeprom[CAL_BI_OFFSET+i]) / powf(2,b_i_scale+(3-ADC_resolution)); // Sensitivity coefficient - float t0 = aplha_0/powf(2,aplha_0_scale); + float t0 = alpha_0/powf(2,alpha_0_scale); float t1 = ((uint8_t)eeprom[CAL_A_CP_OFFSET+i])/powf(2,delta_a_scale); alpha_ij[i] = (t0+t1) / powf(2,3-ADC_resolution); @@ -278,7 +278,7 @@ mp_obj_t py_fir_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) ksta = ((int16_t)((eeprom[CAL_KSTA_H]<<8)|eeprom[CAL_KSTA_L])) / 1048576.0f; alpha_cp = ((uint16_t)((eeprom[CAL_ALPHA_CP_H]<<8)|eeprom[CAL_ALPHA_CP_L])) / - powf(2,aplha_0_scale+(3-ADC_resolution)); + powf(2,alpha_0_scale+(3-ADC_resolution)); uint8_t ks_scale = (uint8_t)(eeprom[CAL_KS_SCALE]&0x0F); ks4 = ((int8_t)eeprom[CAL_KS4_EE]) / @@ -322,7 +322,7 @@ mp_obj_t py_fir_read_ta() mp_obj_t py_fir_read_ir() { if (type == FIR_NONE) return mp_const_none; - float Ta = calculate_Ta(), To[64]; + float Ta = calculate_Ta(), To[64], min = FLT_MAX, max = FLT_MIN; calculate_To(Ta, To); // Copy temperature array. @@ -331,17 +331,21 @@ mp_obj_t py_fir_read_ir() // Rotate temperatures array (sensor memory is read column wise). for (int x=15; x>=0; x--) { for (int y=0; y<4; y++) { - To[x+(y*16)] = *To_rot_p++; + float temp = To[x+(y*16)] = *To_rot_p++; + min = IM_MIN(min, temp); + max = IM_MAX(max, temp); } } - mp_obj_t tuple[2]; + mp_obj_t tuple[4]; tuple[0] = mp_obj_new_float(Ta); tuple[1] = mp_obj_new_list(64, NULL); + tuple[2] = mp_obj_new_float(min); + tuple[3] = mp_obj_new_float(max); for (int i=0; i<64; i++) { mp_obj_list_store(tuple[1], mp_obj_new_int(i), mp_obj_new_float(To[i])); } - return mp_obj_new_tuple(2, tuple); + return mp_obj_new_tuple(4, tuple); } mp_obj_t py_fir_display_ta(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) @@ -351,7 +355,7 @@ mp_obj_t py_fir_display_ta(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) PY_ASSERT_FALSE_MSG(IM_IS_JPEG(arg_img), "Operation not supported on JPEG"); - float Ta = calculate_Ta(); + float Ta = mp_obj_get_float(args[1]); float min = -17.7778, max = 37.7778; // 0F to 100F int alpha = IM_MIN(IM_MAX(py_helper_lookup_int(kw_args, @@ -400,20 +404,14 @@ mp_obj_t py_fir_display_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) PY_ASSERT_FALSE_MSG(IM_IS_JPEG(arg_img), "Operation not supported on JPEG"); - float Ta = calculate_Ta(), To[64]; - calculate_To(Ta, To); - float min = FLT_MAX, max = FLT_MIN; + mp_obj_t *arg_To; + mp_obj_get_array_fixed_n(args[1], 64, &arg_To); - // Copy temperature array. - float To_rot[64], *To_rot_p = To_rot; - memcpy(To_rot, To, sizeof(To)); - // Rotate temperatures array (sensor memory is read column wise). - for (int x=15; x>=0; x--) { - for (int y=0; y<4; y++) { - float temp = To[x+(y*16)] = *To_rot_p++; - min = IM_MIN(min, temp); - max = IM_MAX(max, temp); - } + float To[64], min = FLT_MAX, max = FLT_MIN; + for (int i=0; i<64; i++) { + float temp = To[i] = mp_obj_get_float(arg_To[i]); + min = IM_MIN(min, temp); + max = IM_MAX(max, temp); } int alpha = IM_MIN(IM_MAX(py_helper_lookup_int(kw_args, @@ -467,8 +465,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_height_obj, py_fir_height); STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_type_obj, py_fir_type); STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_read_ta_obj, py_fir_read_ta); STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_read_ir_obj, py_fir_read_ir); -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_display_ta_obj, 1, py_fir_display_ta); -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_display_ir_obj, 1, py_fir_display_ir); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_display_ta_obj, 2, py_fir_display_ta); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_display_ir_obj, 2, py_fir_display_ir); static const mp_map_elem_t globals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_fir) }, { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&py_fir_init_obj }, diff --git a/usr/examples/fir.py b/usr/examples/fir.py new file mode 100644 index 000000000..166b19284 --- /dev/null +++ b/usr/examples/fir.py @@ -0,0 +1,21 @@ +# Thermopile Shield Demo +# +# Note: To run this example you will need a Thermopile Shield for your OpenMV Cam. +# +# The Thermopile Shield allows your OpenMV Cam to see heat! + +import sensor, image, time, fir + +sensor.reset() # Initialize the camera sensor. +sensor.set_pixformat(sensor.RGB565) # or sensor.GRAYSCALE +sensor.set_framesize(sensor.QVGA) # or sensor.QQVGA (or others) +fir.init() # Initialize the thermal sensor + +clock = time.clock() # Tracks FPS. + +while(True): + clock.tick() + ta, ir, min_temp, max_temp = fir.read_ir() + fir.display_ir(sensor.snapshot(), ir) + print("FPS: %f - Ambient Temp: %f C - Min Temp %f C - Max Temp %f C" % \ + (clock.fps(), ta, min_temp, max_temp)) diff --git a/usr/examples/fir_lcd.py b/usr/examples/fir_lcd.py new file mode 100644 index 000000000..5362b8d71 --- /dev/null +++ b/usr/examples/fir_lcd.py @@ -0,0 +1,23 @@ +# Thermopile Shield Demo 2 +# +# Note: To run this example you will need a Thermopile Shield for your OpenMV +# Cam and a LCD Shield. + +import sensor, image, time, fir, lcd + +sensor.reset() # Initialize the camera sensor. +sensor.set_pixformat(sensor.RGB565) # or sensor.GRAYSCALE +sensor.set_framesize(sensor.QVGA) # or sensor.QQVGA (or others) +fir.init() # Initialize the thermal sensor +lcd.init() # Initialize the lcd sensor + +clock = time.clock() # Tracks FPS. + +while(True): + clock.tick() + ta, ir, min_temp, max_temp = fir.read_ir() + img = sensor.snapshot() + fir.display_ir(img, ir) # draws on img + lcd.display(img) + print("FPS: %f - Ambient Temp: %f C - Min Temp %f C - Max Temp %f C" % \ + (clock.fps(), ta, min_temp, max_temp)) diff --git a/usr/examples/mlx.py b/usr/examples/mlx.py deleted file mode 100644 index 1c1f98c18..000000000 --- a/usr/examples/mlx.py +++ /dev/null @@ -1,51 +0,0 @@ -import sensor, mlx, time - -# Initialize the MLX module -mlx.init(mlx.IR_REFRESH_64HZ) - -# Reset sensor -sensor.reset() - -# Set sensor settings -sensor.set_contrast(1) -sensor.set_brightness(0) -sensor.set_saturation(2) -sensor.set_pixformat(sensor.RGB565) -sensor.set_framesize(sensor.QQVGA) - -# The following registers fine-tune the image -# sensor window to align it with the FIR sensor. -if (sensor.get_id() == sensor.OV2640): - sensor.__write_reg(0xFF, 0x01) # switch to reg bank - sensor.__write_reg(0x17, 0x19) # set HSTART - sensor.__write_reg(0x18, 0x43) # set HSTOP - -# FPS clock -clock = time.clock() - -# Ambient temperature -ta = 0.0 -# Minimum object temperature -to_min = 0.0 -# Maximum object temperature -to_max = 0.0 - -while (True): - clock.tick() - # Capture an image - image = sensor.snapshot() - - # Capture an FIR image - ta, to_min, to_max, ir = mlx.read_ir(mlx.RAINBOW, 80, 0.90) - - # Scale the image and belnd it with the framebuffer - ir.scale((160, 32)) - image.blend(ir, (0, int(120/2-32/2), 0.6)) - - # Draw ambient, min and max temperatures. - image.draw_string(0, 0, "Ta: %0.2f"%ta, color = (0xFF, 0x00, 0x00)) - image.draw_string(0, 8, "To min: %0.2f"%(to_min+ta), color = (0xFF, 0x00, 0x00)) - image.draw_string(0, 16, "To max: %0.2f"%(to_max+ta), color = (0xFF, 0x00, 0x00)) - - # Print FPS. - print(clock.fps()) diff --git a/usr/examples/mlx_lcd.py b/usr/examples/mlx_lcd.py deleted file mode 100644 index 749e562d6..000000000 --- a/usr/examples/mlx_lcd.py +++ /dev/null @@ -1,60 +0,0 @@ -import sensor, mlx, time, lcd - -# Initialize the MLX module -mlx.init(mlx.IR_REFRESH_64HZ) - -# Reset sensor -sensor.reset() - -# Set sensor settings -sensor.set_contrast(1) -sensor.set_brightness(0) -sensor.set_saturation(2) -sensor.set_pixformat(sensor.RGB565) - -# Note: QQVGA2 is the LCD resolution. -sensor.set_framesize(sensor.QQVGA2) - -# The following registers fine-tune the image -# sensor window to align it with the FIR sensor. -sensor.__write_reg(0xFF, 0x01) # switch to reg bank -sensor.__write_reg(0x17, 0x1D) # set HSTART -sensor.__write_reg(0x18, 0x47) # set HSTOP - -# Initialize LCD -lcd = lcd.LCD() -#lcd.clear(0x00) -lcd.set_backlight(True) - -# FPS clock -clock = time.clock() - -# Ambient temperature -ta = 0.0 -# Minimum object temperature -to_min = 0.0 -# Maximum object temperature -to_max = 0.0 - -while (True): - clock.tick() - # Capture an image - image = sensor.snapshot() - - # Draw ambient, min and max temperatures. - image.draw_string(0, 0, "Ta: %0.2f"%ta, color = (0xFF, 0x00, 0x00)) - image.draw_string(0, 8, "To min: %0.2f"%(to_min+ta), color = (0xFF, 0x00, 0x00)) - image.draw_string(0, 16, "To max: %0.2f"%(to_max+ta), color = (0xFF, 0x00, 0x00)) - - # Capture an FIR image - ta, to_min, to_max, ir = mlx.read_ir(mlx.RAINBOW, 80, 0.90) - - # Scale the image and belnd it with the framebuffer - ir.scale((128, 32)) - image.blend(ir, (0, int(160/2-32/2), 0.6)) - - # Display the image on the LCD - lcd.write_image(image) - - # Print FPS. - print(clock.fps())