Temperature value of each pixel captured by LEPTON

It’s easier to just look at the C code API here:

Notice how there are so many functions. This is why I did the IOCTLs. Because, it is not possible to do a wrapper for each one.

Hi! Made some progress here. Please see code below. I’ve initialized the sensor. Then, I used radspotmeterroi to create a rectangle roi with coord. 0,0,10,10. Then I want to use the set_attribute command send this information to the Lepton and to set this attribute. I am getting an error at line 14 though (can’t convert ‘int’ object to str implicitly). Am I going about this the right way?

import sensor, image, time, math, struct

print("Resetting Lepton...")
# These settings are applied on reset
sensor.reset()
sensor.ioctl(sensor.IOCTL_LEPTON_SET_MEASUREMENT_MODE, True)

#radspotmeter ROI

data1 = struct.pack(">HHHH", 0,0,10,10) # defining rectangle coordinates at 0,0,10,10 and putting in structure
print(data1)
sensor.ioctl(sensor.IOCTL_LEPTON_SET_ATTRIBUTE, 0x4ECD, 4)


#radspotmeter value
data2 = sensor.ioctl(sensor.IOCTL_LEPTON_GET_ATTRIBUTE, 0x4ED0, 4)
radSpotmeterValue, radSpotmeterMaxValue, radSpotmeterMinValue, radSpotmeterPopulation = struct.unpack("<HHHH", data2)

sensor.ioctl(sensor.IOCTL_LEPTON_SET_ATTRIBUTE

Should have data1 I think instead of 4.

Okay, I changed “4” to “data1” for radspotmeterroi, but I received an error when running the code:

sensor control failed!

By the way, thank you for helping and being so quick with responses. You are very helpful.

Oh, the lepton rejected the command then. What lepton module do you have? The command needs to be supported by the module.

The ROI command should be 0x4ECC.

The result index is 0x4ED0.

Please get the command values from the C code I linked to.

Hello,

We were able to get the code running using the radspotmeterRoi and radspotmeterValue commands taken from the FLIR Lepton SDK. Now, we are able to create a rectangle on the screen and get temperature measurements back. However, the temps are a bit off. For example, pointing at my hand as reference, I get 104F back. Pointing at the wall inside my room, I get 93F back. These are obviously wrong. Do you perhaps have some insight as to why this is happening?

Thank you in advance.

Are you using a FLIR Lepton 3.5? Other leptons don’t really return right temperature readings.

I’ve never used the rad-spot-o-meter command. I just know it exists. I can’t quite say what’s wrong.

Hi Iseeinir23,

I’m definitely not an expert but it sounds like you need to calibrate the lepton off a black body source. The camera should be doing FFC automatically so the core temperature of the camera shouldn’t be an issue. The lepton is calibrated at factory for a scence with 100% emissivity in close proximity to the camera which is probably not realistic in the real world. This Flir guide describes how to calibrate the lepton https://www.flir.com/globalassets/imported-assets/document/lepton-with-radiometry-quickstart-guide.pdf

Hi,

When I issue the rad spot-o-meter set command with the following values I get a sensor control failed error. The code I use is:

roi = struct.pack("<HHHH", 0,0,159,119) # defining rectangle coordinates and putting in structure
sensor.ioctl(sensor.IOCTL_LEPTON_SET_ATTRIBUTE, 0x4ECD, roi)
    

data = sensor.ioctl(sensor.IOCTL_LEPTON_GET_ATTRIBUTE, 0x4ED0, 4)
radSpotmeterValue, radSpotmeterMaxValue, radSpotmeterMinValue, radSpotmeterPopulation = struct.unpack("<HHHH", data)

I’m trying to set the ROI to cover the entire image but these values don’t seem to work, if I change them to 0,0,10,10 it works fine. From my reading of their SDK document it can be done because the maximum value the radSpotmeterPopulation variable can hold is 19200 which is the entire pixel array. Any ideas?

The result of the get operation does not seem to be based on the values I set on the occasions that it works.

Thanks

Do you have a FLIR Lepton 3/3.5 or less? Only the 3 accepts the 160x120.

Sorry I can’t be more help here… We just supply the I/O layer. Getting the commands to work takes quite a bit of effort.

During the driver development we spent countless hours fighting the VOSPI bus which locks up unless it’s clocked constantly.

Hi,

I have the 3.5. I can set the coordinates and get the coordinates to make sure they are set to mine but when I query the ROI for min, max, avg temp and population it seems to be based off of other coordinates as far as I can see.

I don’t know. Maybe there’s more setup that’s needed. Check the API document and try calling other RAD commands.

https://github.com/openmv/openmv/blob/master/src/lepton/include/LEPTON_RAD.h#L80

FLIR doesn’t really have documentation on anything other than generating pretty images. I think they want to keep how to use temperature values close to their chest.

Yes I’ll have a look. I also agree that the Flir documentation is quite poor given the complexity of the subject matter. Thank you.

Hi,

Just to let you know, and for anyone else that may need it, I got the spotmeter stuff working. There were two things happening. I had to put a time.sleep(500) between the setting of the ROI and the getting of the ROI to allow the changes to take effect. The other thing I wanted was to set the ROI to the entire image. I had just interpreted the order of the coordinates wrong. From my understanding you have 160 pixels across and and 120 pixels down. This would mean that the maximum value for the columns is 119 and the maximum value for the row is 159 which is not what is shown in the image.

To get the spotmeter working I did the following:

roi = struct.pack("<HHHH", 0,0,119,159) # defining rectangle coordinates and putting in structure
sensor.ioctl(sensor.IOCTL_LEPTON_SET_ATTRIBUTE, 0x4ECD, roi)
    
time.sleep(500)

data = sensor.ioctl(sensor.IOCTL_LEPTON_GET_ATTRIBUTE, 0x4ED0, 4)
radSpotmeterValue, radSpotmeterMaxValue, radSpotmeterMinValue, radSpotmeterPopulation = struct.unpack("<HHHH", data)

print('Number of pixels used: ', radSpotmeterPopulation, '  ', radSpotmeterValue)

Thanks for the note!

160 → columns (x or width)
120 → rows (y or height)

Hi,

I thought this might be useful if someone like me wants the raw data or the reassurance that the 8 bit conversion the OpenMV board does is still quite accurate. I done two comparisons. The top comparison uses the Flir radiometric ROI SDK function to return the average temperature in Kelvin scaled by a factor of 100. I convert this temperature to Celsius. The key point is I set the ROI to the entire image so I am getting an average temperature for the entire image.

I then modified the firmware so the snapshot function returned an array of raw 16 bit temperature values which again are in Kelvin and scaled by a factor of 100. Again I convert these values to Celsius and get an average for the entire image. These values were used to generate the first dataset so I could compare the data from the Flir SDK versus the 16 bit raw data I got from the OpenMV. Obviously these lines are almost identical as I would expect as Im comparing raw values with raw values in essence albeit from potentially different frames.

I then change the firmware back to its original state.

The other comparison I implemented is slightly more useful. Again I used the Flir radiometric ROI SDK function to return the average temperature in Kelvin scaled by a factor of 100 which I convert to Celsius. Then I get the average grayscale value for the entire image and convert it to Celsius using the function provided by OpenMV. These values were used to generate the second dataset. As you can see the loss of precision when the openmv firmware converts the raw data to 8 bit data is minimal. In fact both datasets in my case had 500 samples and only 1 sample in each dataset had a temperature difference greater than 0.2 degrees Celsius which I believe was caused by the camera running its FFC algorithm.

Long storey short a 16 bit image would be very nice but the 8 bit grayscale is probably enough as Kwabena tried to explain to me numerous times :smiley:

Thanks for posting about this! :slight_smile: