gtatters / Thermimage

R Package for working with radiometric thermal image files and data
GNU General Public License v3.0
164 stars 41 forks source link

DN to Temp conversion results in a data matrix that exceeds (696, 928) the dimensions of the original camera resolution (640x480) #5

Closed ReneHeim closed 4 years ago

ReneHeim commented 4 years ago

Issue Dear Glenn, I am using a batch function, based on your package function, to convert thermal image digital numbers into temperature values. Today I stumbled upon the fact that the exported data matrix containing the T values is larger (696, 928) than the original camera resolution (640x480). I can´t think of anything that results in this behavior and would appreciate some input if possible.

Thanks a lot,

René

To Reproduce I guess you only need my function and some images to reproduce my results:

`#' Converting digital numbers (DN), stored in a FLIR thermal jpg compressed image,

' into temperature (T) values. A temperature matrix is exported. The conversion

' is performed based on the conversion function implemented into the Thermimage

' package written by Tattersall GJ.

'

' @param imgpath

' @param searchpattern

' @param out

' @return

' @examples

' @details

flirdn2temp <- function(imgpath, searchpattern, out){

"data/raw/20190912/"

"*.jpg"

require(Thermimage) require(exiftoolr)

exif_version() #Evaluate whether exiftool is installed

ldf <- list() # creates a list to store thermal images vec.jpg <- dir(path = imgpath, pattern = searchpattern) # creates a vector containing all image names

for (k in 1:length(vec.jpg)){ldf[[k]] <- readflirJPG(paste(imgpath, sep="/", vec.jpg[k]), exiftoolpath = "C:\Windows\")} # loops through file names stored in vec.jpg and pastes them to the absolute path of the image folder, loads images in a list

settings <- flirsettings(paste(imgpath, sep="/", vec.jpg[1]), exiftoolpath = "installed")

truetemp <- list()

for (i in 1:length(ldf)){

truetemp[[i]] <- raw2temp(ldf[[i]],
                          E = settings$Info$Emissivity,
                          OD = settings$Info$SubjectDistance,
                          RTemp = settings$Info$ReflectedApparentTemperature,
                          ATemp = settings$Info$AtmosphericTemperature,
                          IRWTemp = settings$Info$IRWindowTemperature,
                          IRT = settings$Info$IRWindowTransmission,
                          RH = settings$Info$RelativeHumidity,
                          PR1 = settings$Info$PlanckR1,
                          PB = settings$Info$PlanckB,
                          PF = settings$Info$PlanckF,
                          PO = settings$Info$PlanckO,
                          PR2 = settings$Info$PlanckR2)

}

h = settings$Info$RawThermalImageHeight w = settings$Info$RawThermalImageWidth

for (k in 1:length(truetemp)){

write.csv(truetemp[[k]], file = paste(out, vec.jpg[[k]], sep = "", "matrix.csv"),row.names=FALSE)  

} }`

IMG_9038 IMG_9039

Expected behavior I would expect the output matrix of the attached function to produce a matrix that is larger than the possible image resolution (640x480).

Screenshots Not applicable.

Thanks for looking into it.

René

gtatters commented 4 years ago

Hmm...I'm not sure I fully understand the question, but I see from running exiftool the raw sensor width x height of your camera is 696x928:

Screen Shot 2019-10-24 at 9 49 55 AM

I can't quite get your function to run at the moment, but I can definitely load your image using readFlirJPG, but you will have to set your width and height to 696 and 928.

img<-readflirJPG("flirpic.jpg")

img.t<-raw2temp(img)

plotTherm(img.t, w=928, h=696)

Maybe I am confused by the statement "larger than the original camera resolution". The images above are from a T540, which is rated online as 464 × 348 resolution. It seems that model is capable of a supermax resolution (i.e. twice the resolution), so I'm not sure why we would expect it to be 640x480?

Are you getting an error statement I can replicate?

gtatters commented 4 years ago

can you save your function as an .R file? The formatting didn't copy over properly.

ReneHeim commented 4 years ago

Oh no. Glenn. I am super sorry. Sitting here working with a flu and should have looked more properly at the exif information. I read the image resolution. About the supermax resolution, could I set width and height in your function to 464 × 348?

As I am currently doing most of my image processing in Python, would you be interested in converting your functions into Python functions? Python has some amazing image processing tools but your FLIR conversion tool would be an interesting addition.

Cheers,

Rene

gtatters commented 4 years ago

I think your real width and heights are 928 x 696 for those images. the readflirJPG function and the flirsettings functions or the raw2temp functions do not discriminate or care about the width and height. When reading the image in, however, I take the raw binary output from Exiftool and then have to interpolate that it corresponds to an image of w x h dimensions. I gave up working in matrixes in R since it seemed easiest to simply import the entire image as a vector and reconstitute it as a matrix later (usually vectors show faster computation).

If I knew more python, I would convert the functions. I think a few people have forked Thermimage already and may have done some of their own functions. I'd need to learn more Python to do this. I know it is far more powerful for image analysis, especially with ML.

To answer you question...no I don't think you can set the resolution to 464 x 348 since that is the camera's normal sensor size, but with the ultramax image, FLIR has up-sampled your image by capitalising on the vibration in the camera to sample ~16 images at once and blow up the resolution to double the true sensor size. It's a bit of a cheat and it can confuse us when we think we know the camera's true resolution.

gtatters commented 4 years ago

just be careful with some of the output from Exiftool that might confuse. For example, the Exif width is listed as 640 for your images. I don't know if that refers to a digital camera image that is also being captured and stored along with the thermal image or not?

ReneHeim commented 4 years ago

Wow! I really admire your knowledge on that topic. I will be starting a postdoc in Belgium/Ghent with Wouter Maes. He has done a lot of work in thermal imaging and UAV research.

Regarding Python, I don´t know how to build modules but for starters, it would be great to build a function that could convert DN to T. Unfortunately, I could not manage to use exiftools in Python. A wrapper exists but I didn´t find anyone how made it work. I was thinking that I could use your function and translate it into Python...

ReneHeim commented 4 years ago

Interestingly, when I convert the image DNs into T with FLIR Tools+, the output has a resolution of 464 × 348...

gtatters commented 4 years ago

I think that FLIR tools+ won't extract the ultramax data. On purpose. They want you to have a different software for that, or you have to click an option to extract the ultramax data when importing. If I tackle this in Python, it likely won't be soon enough for you, unfortunately. :( A steep learning curve for me and lack of time at the moment.

ReneHeim commented 4 years ago

I will start converting your function and send it to you once I feel it is useful if you like.

Cheers, Rene

gtatters commented 4 years ago

sounds like a plan. It would be fine if someone forked this and started a python version of Thermimage as well.

aloisklink commented 4 years ago

@ReneHeim, if you are still interested in a Python port of Thermimage, I've ported the raw2temp functionality of Thermimage into a Python package at aloisklink/flirextractor. It currently just works for extracting FLIR .jpgs (since that's all I need), but as it is open-source, feel free to extend it in your own work if you need to do anything else with it.