Flir (I7) Some Analysis

Introduction

I’m the proud owner of a Flir I7 Infrared camera.

With this nice camera, you can take 120×120 infrared pictures. These pictures are saved in an internal SD-Card. You can connect this camera to you computer.

On the picture, you can see the temperature of a 120×120 pixels area. You have a crossbar in the middle where you can see the temperature of the center. You have a scale at the bottom and the Flir logo on the top right.


Nice! Great! A pretty good camera for an expensive, but decent price.

 

My issue

Sadly the resolution is not high, and 30% of the image is covered by useless things (The logo, the temperature, the scale and the date).

It seams that the provided software can “take these things out of the interesting part”, I have not been able to test this software.

My configuration
– I’m on Linux, and the provided software only works on Windows (Not even on Mac…)
– I have a Windows in Virtual Box, but the provided software crashes!!! You can download a more recent version on the web site, but this version only loads images directly from the camera (and it doesn’t work for me), or from the SD-Card (and the SD-card is not mounted/accessible through my Windows).

Basically the Flir Team doesn’t seam to be able to write a correct software.

 

Goal

My goal is to be able to extract the original image without all the useless things (Logo, …) on Linux. You can probably use the same software on mac.

The provided software should be compatible with other models. (The old 120×120 and the new 140×140 Flir i7, Flir i5, Flir i3, and probably other models.)

 

Analysis

Let’s first analyze the JPG image.

> jhead IR_0248.jpg
File name : IR_0248.jpg
File size : 36197 bytes
File date : 2012:02:11 14:17:08
Camera make : FLIR Systems AB
Camera model : FLIR_i7
Date/Time : 2012:02:11 14:17:08
Resolution : 240 x 240
Focal length : 6.7mm
Exposure time: 0.031 s (1/32)
Focus dist. : 1.00m

Nothing really interesting here.

 

If you open this image with an hex editor (GHEX), you will see a PNG header.

#89 50 4E 47 0D 0A… PNG…

Flir have inserted a PNG image in your JPG image, interesting! This image is not visible when you use a normal viewer.

I can find the position of this PNG segment using
> strings -a -3 --radix=d IR_0248.jpg | grep PNG
8035 PNG

So my PNG image is starting at position 8034. Before the PNG segment you have a character “0x89”.

Let’s extract this PNG image
tail --bytes=+8035 IR_0248.jpg > t.png

And let’s get some information about this png file.

> file t.png
t.png: PNG image data, 120 x 120, 16-bit grayscale, non-interlaced
Data is stored on 16 bytes (A value between 0 – 65535). The image size is 120×120 as expected, it’s the size of my camera.

It’s looks really interesting, the temperature levels seams to be wrong, but you can recognize the original image without the added information (logo, …).

Let’s convert the PNG file to a raw file. This file will contains the first pixel in the first two bytes, then the second pixels in the two next bytes. The size of the file is 120*120*2 bytes.
> convert t.png -depth 16 gray:t.raw

0xa730, 0x9830, … seams to be the temperature of 20,3°c
We see that bytes are inverted (little endian), but after comparing different image, we cannot just rely on this information.
Let’s analyze the JPEG file again

 

If you open the file with an HEX editor (ghex2), you will see that the format of a JPEG file is
0xFF D8 E0 00 {2 bytes size of segment 1} [name and data of segment 1] {2 bytes size of segment 2} [name and data of segment 1]

Analyzing one of my files I have
0x0006: JFIF : Just a header
0x0018: Exif : This header is “classical” and contains description about the image. Date, camera brand and model, width and height, etc..
0x0e2a: FLIR : This header looks really interesting, this is where you have the PNG file and other data. This header is specific to FLIR, it means most of the viewer just ignore it.
0x4e02: Other data

 

We will focus on the FLIR segment.

I have first “analyzed” the file with PhotoMe, we see 10 “Manufacturer notes” segments.
0x01: Rational -> That’s the maximum temperature in the image in °K
0x02: Rational -> That’s the minimum temperature in the image in °K
0x03: Rational -> 0.8, 0.95 ??
0x04: Rational -> 250 – Always the same, perhaps the minimal “reliable” temperature of the camera
0x05: Rational -> 523 – Always the same, perhaps the maximum “reliable” temperature of the camera
0x06: Rational -> 273 – Always the same, it’s perhaps temperature 0°C
0x07: ASCII -> 00000
0x08: ASCII -> 0000
0x09: Undefined -> Binary
0x0A: Long -> 1 – Always the same

 

To better understand the Exif/FLIR format, you can read this PDF: DC-008-2010_E.pdf
This chapter explains how a data is structured in this FLIR segment: 4.6.2 IFD Structure
Bytes 0-1 Tag — Bytes 2-3 Type — Bytes 4-7 Count — Bytes 8-11 Value Offset

So if I take the first segment of one of my files:
Tag: 0x 00 01
Type: 0x 00 00
Count: 0x 46 46 46 00
Value offset: 0x

 

 

TO BE CONTINUED

 

7 thoughts on “Flir (I7) Some Analysis

  1. Borja

    Thank you for your work!

    I’m also interested in getting the temperature data from the Flir image files using my own script.

    Can you share how to convert each 2-byte pixel data from the png file to temperature?

    Grettings,
    Borja.

    • gabriel Post author

      I would love to, but I still have issue finding the scale to convert the bytes to temperature. The scale doesn’t seams to be linear 🙁

      What you can do is to install the camera on windows, start a flir tools (I don’t have the name here), “telnet or ftp 192.168.1.2 or 192.168.0.2”, then you can change some settings like the logo. (I have a transparent logo.)

      • Borja

        Using FLIR tools ( http://goo.gl/gxUOi ) I have extracted the temperature values from your image and plotted them vs the 16bit big-endian values ( http://goo.gl/ezctu ). The result is almost linear but I need the exact formula.

        Disassembling the FLIR tools library Flir.Cronos.IR.Math.dll using .NET reflector found an obfuscated function in the class EmissivityCalculator
        that dependens on IRValue (the 16bit value?) and the image properties:

        private static IRValue X(IRImage A_0, IRValue A_1)
        {
        // This item is obfuscated and can not be translated.
        }

        Maybe the temperature is determined by the 16bit value and some correction related to the image/objetct configuration.

        I couldn’t find any useful formula in the camera manual: http://goo.gl/UvJVf

  2. Andy

    Thanks for the article, very interesting. This is just a casual observation, but looking at that image, (the black and white one) it looks like you are missing the top bits/byte of the data. The image is ‘rolling over’, in the same way as 3 and 103 look the same if you ignore the hundreds (so when it gets too hot the output goes back to black – e.g. the cat’s body is black, but so is the shadow under the chair).

    I’d have a look through the file for more information – I bet that there is a second image in there that contains the upper bits or maybe that png isn’t 16 bit after all? could the Jpeg wrapper be encoding the upper bits? … not sure… best of luck.

  3. Hn

    Maybe “0×03: Rational -> 0.8, 0.95 ??” is the “emissivity” value?

  4. tomas

    only with exiftool and Imagemagick you can convert your cat IR_0248.jpg to this image

    a simple way for changing lsb/msb byte order is:
    $ convert IR_0248.png gray:- | convert -depth 16 -endian msb -size 120×120 gray:- -auto-level cat.png

    source:
    http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4898.msg24230.html#msg24230

    background infos with some color palettes:
    http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4898.msg23763.html#msg23763
    http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4898.msg23944.html#msg23944

Comments are closed.