Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temp info getting #23

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open

Temp info getting #23

wants to merge 12 commits into from

Conversation

undera
Copy link

@undera undera commented Apr 3, 2018

@undera undera mentioned this pull request Apr 3, 2018
@maartenvds
Copy link
Collaborator

Thanks for your contribution. I will merge your code after my holidays.

@Achref-Dachraoui
Copy link

Hi Andrey,

I tried your contribution concerning temperature on Maarten Project. However, i still can't understand how you managed to get these informations. Can you please explain a bit more your method and eventually how you did to obtain your linear trend line on excel.

Thank you in advance for your help.

@undera
Copy link
Author

undera commented May 4, 2018

@AchrefDash I'm curious, was the information you got meaningful? Did it match real world temperatures?

The method is trivial: I have googled out that raw pixel values from camera are absolute. This means they contain actual temperature data, expressed in Kelvin value with some linear representation. Thus, I made some experiments to figure out linear law for these values, based on ice, boiling water and human body. The values for trend line are expessed in my source code comments.

@Achref-Dachraoui
Copy link

Hi @undera Thank you for your quick response.

So, the results I have are almost similar to the results obtained with Seek App with a coefficient in addition. After doing some tests on human body, the soldering iron, lamps, electrical cabinets and others, I got an average coefficient of 0.8 to get almost the same Seek App tempetures values but this approach remains very approximate depending on the tests conditions.

@rainer38
Copy link

rainer38 commented Jun 4, 2018

I modified your version a little bit to show the max/min hot/cold points with colored circles in the image and show the temperature with one decimal point at that location. It's not very nice but it works as a proof of concept. My problem at this point is that the shown temperatures are a bit too high. But i have to verify this with a known reference temperature.

Example image:
example

Source file:
seek_viewer.zip

@undera
Copy link
Author

undera commented Jun 4, 2018

The ways to visualize the point may vary.
Indeed, the biggest question is the formula of translating raw value to temperature. We need more data, probably, to calibrate it.

@pauledd
Copy link

pauledd commented Jun 12, 2018

just as a side note, Seek Thermal states that

All Seek imagers are generally accurate within 5 degrees C above or below the reading
(http://www.eevblog.com/forum/thermal-imaging/seek-compact-pro-temperature-readout-issue/msg1403982/#msg1403982)

I got a new CompactPro last week that had a offset of ~6-7°C after 5! minutes...
There is a huge variation in the readings from device to device. But I noticed once you know
when the readings has stabilized over time its quite constant and you could use an offset. That adjustable offset is what I really miss with the official Seek App...

@pauledd
Copy link

pauledd commented Jun 17, 2018

@undera can you please explain how you came to this line of code?
return (0.0171156038 * x + 37) - 273;
Where do you got the 0.0171156038 and the 37 from?
Did you got it from Excel as curve function?

@undera
Copy link
Author

undera commented Jun 18, 2018

@pauledd Yes, I took it from excel function.

@pauledd
Copy link

pauledd commented Jun 19, 2018

@undera thanks, just one more question:
you state

// 330C => 603K => 32768 raw (known upper limit, full 15 bits - 2^15)

in your seek_viewer.cpp. Can you pls explain where you got this 15bits from?
As I was reading through the eevblog I've only seen that the cam outputs 14bits,
then stretched to uint16... how does the 15 come into play?

@undera
Copy link
Author

undera commented Jun 19, 2018

I don't remember exactly. In my experiments, I used candle as maxed temp value, and probably got this 32768 raw number.

@pauledd
Copy link

pauledd commented Jun 19, 2018

ah, okay. I will try that too :)

@undera
Copy link
Author

undera commented Jul 19, 2018

Added more things to this PR:

  • added device temp sensor data getting to investigate further topic of absolute values getting (temp/raw drop issue #29)
  • max/min position pointers (thanks @rainer38, but had to modify code to support rotation and scaling)
    seekthermal_001

@pauledd
Copy link

pauledd commented Jul 19, 2018

made seekpro to have 15fps by default

What do you mean with this? Isn't the Seek Pro restricted to ~9fps?

@undera
Copy link
Author

undera commented Jul 19, 2018

@pauledd Discrard what I've wrote there, I found I was confused

@undera
Copy link
Author

undera commented Jul 19, 2018

Now I also have added gradient on the side and central point measurement, hoping we'll collect some more data on raw values.

seekthermal_006

@undera
Copy link
Author

undera commented Jul 19, 2018

Ok, my latest hypothesis is that formula is simple linear calculation, assuming 330C is max of 14bit value. Would be cool to gather some more observations.

@undera
Copy link
Author

undera commented Jul 19, 2018

Values from app when camera self-temp is ~26C:
rmin,rmax,central,devtemp: 15060 15708 15298 6577 / min-max-center: 30.3 43.4 35.1

Same setup, camera cooled down to ~18C:
rmin,rmax,central,devtemp: 16384 17002 16932 6723 / min-max-center: 57.0 69.4 68.0

And after 10minutes:
rmin,rmax,central,devtemp: 14654 15584 15147 6582 / min-max-center: 22.2 40.9 32.1

Which makes me conclude that camera self-temperature highly relates to values measured. I'll look for a way to use devtemp plus linear 14bit value to 330C hypothesis together...

@undera
Copy link
Author

undera commented Jul 22, 2018

I have spent a lot of time calibrating dev sensor versus known temperatures, and I came up with compensation model that should react on device temperature and compensate it. I have added my Excel file calculations.ods for reference.

@hoehermann
Copy link

@undera Great work! However, from my Seek Compact, I read measurements like

rmin,rmax,central,devtempsns: 15556 15828 15628 4252	min-max-center-device: 890.3 895.8 891.8 591.7

. Did you do your research with a CompactXR or CompactPRO? I suspect there could be different formulae for each model.

@undera
Copy link
Author

undera commented Nov 4, 2018

I have only one CompactPro for Android device.

@hoehermann
Copy link

@undera Good to know. So I want to do experiments with a Seek Compact and share my findings.

@hoehermann
Copy link

Id did a series of calibration experiments. In the process, I wrote a viewer which stores the raw data in 16bit images for later processing. Unfortunately, finding a function to infer the actual device temperature from the raw value leaves me stumped. @undera How did you find the NTC information? Did you open your camera? I gave up and resorted to a linear approximation which seems to be exact within ±1°C after the device has warmed up. I published the adjustments in the temp-info_compact in my fork.

@hoehermann
Copy link

During my experiments, I also noticed some vignetting. After the device warmed up, the edges of an approximately uniform temperature surface appear 1.6 °C warmer than the centre.

Example: (normalized)
seekframe_008190

This graph shows, the vignette increases with device temperature, too.

@undera
Copy link
Author

undera commented Nov 10, 2018

vignetting is a known thing for cameras, it is known that Seek uses software way to compensate it in their apps.

The problem of simple linear approach is that device's temperature will affect measurements, and I perfectly see that in my experiments.

My approach of making sure sensor has certain temperature is simple: I turn camera off in a room with air conditioner set to certain temp, I let it quite of time to stabilize temp, then I quickly turn it on and record values. I also use trustworthy thermometer to tell what was the temp around it (and inside it).

@pauledd
Copy link

pauledd commented Nov 10, 2018

My approach of making sure sensor has certain temperature is simple: I turn camera off in a room with air conditioner set to certain temp, I let it quite of time to stabilize temp, then I quickly turn it on and record values. I also use trustworthy thermometer to tell what was the temp around it (and inside it).

Thats not practical at all if you want a quick location-independent measurement without doing heavy cool-down calibration measurements and waiting for the sensor to finally settle after 30 minutes (that's what my device takes). My guess is Seek uses some kind of forward prediction math with a predefined characteristic curve for that thermal-sensors that it produces good temp values just right after powering up... just my 2 cents ;)

@undera
Copy link
Author

undera commented Nov 10, 2018

Yes, I have same feeling that they have some formula they know.
I was playing around thermistor formulas, assuming internal sensor is thermistor. I still believe that having right guess and some measurements would give good enough results.

@hoehermann
Copy link

Thank you for your input.

(…) I turn camera off in a room with air conditioner set to certain temp (…)

Unfortunately, I currently have no options to produce environments with a range of stable temperatures wide enough to explore the non-linear parts of the assumed NTC reading. For the non-PRO variant of the Seek Compact, we are left with a linear approximation best fitting for a device temperature of whatever raw value of 4236 is standing for. Which is better than nothing, I guess.

Thats not practical at all if you want a quick location-independent measurement (…)

Fortunately, I want to do a long-term fixed-location measurement (for quick measurements on the go, I'd actually use the official app).

@lchop
Copy link

lchop commented May 24, 2019

Hello,
Any updates on this topic ?
I have the feeling that the sensor values changed. I tried your code but I get tempertatures around 80 degrees.
How do you get the values used in this fct ?

double device_sensor_to_k(double sensor) {
    // formula from http://aterlux.ru/article/ntcresistor-en
    double ref_temp = 297.0; // 23C from table
    double ref_sensor = 6616.0; // ref value from table
    double beta = 200; // best beta coef we've found
    double part3 = log(sensor) - log(ref_sensor);
    double parte = part3 / beta + 1.0 / ref_temp;
    return 1.0 / parte;
}

Thank you in advance

@undera
Copy link
Author

undera commented May 25, 2019

Nothing has changed. My impression is that people get different temperature because my formula is somehow wrong. But I have just one camera, so I have no way to validate this. Nobody brought any reliable measurements to compare, still.

@hoehermann
Copy link

Until we somehow find a reliable formula, you can resort to static calibration:

  1. Let your camera run for a couple of minutes until it has warmed up (takes about 15 minutes, see below for a graph from the Seek Compact camera).
  2. Store an image showing an object with a reference temperature.
  3. Hope your camera does not change temperature during measurements.

I have an example application at my branch which stores the raw frames so you can do corrective temperature processing after the measurements.

Compact

@cjnqt
Copy link

cjnqt commented Oct 13, 2019

@hoehermann - In step 2 above, don’t we need an image with (at least) two different reference temperatures to make a linear interpolation of the relationship?

Or how do you do it using only one reference temperature?

@hoehermann
Copy link

@cjnqt I measured a plane of known temperature. As the device temperature changes, the reading changes. I calculated the offset of "reading should be" and "actual reading". Then I did a linear fit along a · device_temperature + b = corrective_offset. Sampling points in the example given above are any frames after frame 7000. This gives not only two, but a whole bunch of points to interpolate. Now I have a linear function I can apply to the measurements: measurement_value + corrective _function(device temperature) = corrected_value.

Copy link
Contributor

@Bostwickenator Bostwickenator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice additional functionality! I have a few suggested changes here.

@@ -197,6 +206,8 @@ bool SeekCam::get_frame()
if (!m_dev.fetch_frame(m_raw_data, m_raw_data_size))
return false;

// save_frame_img(m_raw_frame, frame_id());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left over debugging code?

double maxtemp=temp_from_raw(max, device_k);
double centraltemp=temp_from_raw(central, device_k);

printf("rmin,rmax,central,devtempsns: %d %d %d %d\t", (int)min, (int)max, (int)central, (int)device_temp_sensor);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to be pushing two lines to stdout for every frame? If these need to stay can you control their output with a command line parameter.

resize(frame_g8, frame_g8, Size(), scale, scale, INTER_LINEAR);
resize(frame_g8_nograd, frame_g8_nograd, Size(), scale, scale, INTER_LINEAR);

// add gradient
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider extending the image frame do that you don't end up overdrawing the thermal data so much?


// Apply colormap: http://docs.opencv.org/3.2.0/d3/d50/group__imgproc__colormap.html#ga9a805d8262bcbe273f16be9ea2055a65
if (colormap != -1) {
applyColorMap(frame_g8, outframe, colormap);
} else {
cv::cvtColor(frame_g8, outframe, cv::COLOR_GRAY2BGR);
}

// overlay marks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these overlays need to be controlled by a command line option defaulting to false.

void draw_temp(Mat &outframe, double temp, Point coord, Scalar color) {
char txt [64];
sprintf(txt, "%5.1f", temp);
putText(outframe, txt, coord-Point(20, -20), FONT_HERSHEY_COMPLEX_SMALL, 0.75, color, 1, CV_AA);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer FONT_HERSHEY_PLAIN, screen interfaces should use san-serif fonts.

@undera
Copy link
Author

undera commented Aug 11, 2020

Feel free to take from this PR whatever code you want and close it. I have no spare time now to spend on it, sorry.

@Bostwickenator
Copy link
Contributor

Bostwickenator commented Aug 12, 2020

Would you mind flipping on the reviewers can edit setting so I can make those changes and merge it up. That way your contributions will get attributed correctly. If that's not possible to change after starting a PR I'll fork your branch and merge it under a separate PR. Thanks for all the work you put in here by the way.

Feel free to take from this PR whatever code you want and close it. I have no spare time now to spend on it, sorry.

edit: Actually that may have already been on. Sorry, I guess since I was looking at the first file (the binary one) GitHub wasn't offering up any options in the webUI and I assumed that wasn't enabled.

@Bostwickenator Bostwickenator linked an issue Jan 2, 2021 that may be closed by this pull request
@BigMuscle85
Copy link

The converting flux values to temperatures is not so easy task. Each sensor is different, so you will need to do calibration for each piece of camera separately. The conversion model is also not linear, but it should be done according to Planck's law (or its RBFO approximation) including thermal parameters of the viewed scene, such as emissivity, background temperature or atmospheric transmissivity.

There is also an issue in this library, because it normalizes flat-field to value 0x4000. This can be correct only in the situation when the shutter temperature is constant (and is always the same as it was during the calibration). The correct way would be the normalization to mean value of FFC image, or better, to some value that corresponds to real flux emitted by the shutter. Because if shutter temperature is known (e.g. derived from camera temperature) it can be used for radiometric correction (flux viewed on shutter => shutter temperature). You just need to include some coefficient to correlate between shutter image and scene image to compensate for lens influence.

@hoehermann
Copy link

The conversion model is also not linear, but it should be done according to Planck's law (or its RBFO approximation)

Unfortunately, I am not a physicist and cannot implement this approximation without spending considerable time on educating myself first. :/

The correct way would be the normalization (…) some value that corresponds to real flux emitted by the shutter.

I just noticed that the data is actually available in m_flat_field_calibration_frame, but not used anywhere. I currently do not have a thermal camera at hand, so I cannot experiment with it. :(

@ava57r
Copy link

ava57r commented Oct 1, 2021

It does not work on OpenCV v4

I changed CV_AA => LINE_AA in https://github.com/undera/libseek-thermal/blob/temp-info/examples/seek_viewer.cpp#L70

@Bostwickenator
Copy link
Contributor

It does not work on OpenCV v4

I changed CV_AA => LINE_AA in https://github.com/undera/libseek-thermal/blob/temp-info/examples/seek_viewer.cpp#L70

Are you talking about just this branch or master?

@ava57r
Copy link

ava57r commented Oct 1, 2021

It does not work on OpenCV v4
I changed CV_AA => LINE_AA in https://github.com/undera/libseek-thermal/blob/temp-info/examples/seek_viewer.cpp#L70

Are you talking about just this branch or master?

only this branch.

master branch works for me :-)

@karlp
Copy link

karlp commented May 12, 2023

This branch reports values like rmin,rmax,central,devtempsns: 15687 15973 15751 7291 min-max-center-device: -31.4 -25.7 -30.2 -13.4 with my seek thermal pro (after makeing the CV_AA->LINE_AA changes above.) It's in a "normal" office space, about 22C or so, pointing at a board that might be 25-30 tops, but either way, nothing is negative here :)

So it seems more info is required? Still, super neat that this all "just worked" for the most part :)

@panamantis
Copy link

This forum and the corresponding Rpi2SeekDevA code suggest that the temperature profiles, calibration info etc can be sourced via specific pixels. https://www.eevblog.com/forum/thermal-imaging/running-seek-thermal-cameras-(-others)-on-a-raspberry-pi/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Absolute temperature readings