ExifTool Forum

ExifTool => Bug Reports / Feature Requests => Topic started by: tomas123 on March 20, 2013, 12:49:46 PM

Title: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 20, 2013, 12:49:46 PM
suggest for a enhancement: decrypt binary data in the EXIF-Header from a FLIR radiometric jpg




FLIR Infrared Software stamps every picture with a flir-logo and doesnt support batch processing.

Newer Flir Thermographie Cameras saves the 16 Bit sensor raw datas in the Exif Header of a normal jpg.
With this 16 Bit raw datas you can generate a own false color pictures (imagemagick etc.) without flir logo.

exiftool can't decrypt the embedded raw values (binary)
Quoteexiftool.exe -v5 IR_0193.jpg
...snip
JPEG APP1 (42312 bytes):
    104e: 46 4c 49 52 00 01 00 00 46 46 46 00 00 00 00 00 [FLIR....FFF.....]  // magic bytes sequence / 8. Byte+1 = numbers of linked blocks (max 65532 Bytes see sample below)
    105e: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 [...............d]
    106e: 00 00 00 40 00 00 00 0e 00 00 00 02 00 00 00 00 [...@............]
    107e: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a5 40 [...............@]
    108e: 00 00 00 00 6d df 65 d4 00 20 00 01 00 00 00 71 [....m.e.. .....q]
    109e: 00 00 00 01 00 00 02 00 00 00 09 ac 00 00 00 00 [................]  // start address 1. segment + length (address is relative to this block - see awk script)
    10ae: 00 00 00 00 db 1f ca ed 00 22 00 01 00 00 00 68 [.........".....h]
    10be: 00 00 00 01 00 00 0b ac 00 00 03 10 00 00 00 00 [................] // start address 2. segment + length
    10ce: 00 00 00 00 9b 9f 81 a2 00 21 00 01 00 00 01 05 [.........!......]
    10de: 00 00 00 01 00 00 0e bc 00 00 00 64 00 00 00 00 [...........d....] // start address 3. segment + length
    10ee: 00 00 00 00 6d 9d 1a a1 00 01 00 02 00 00 00 65 [....m..........e]
    10fe: 00 00 00 01 00 00 0f 20  00 00 96 20 00 00 00 00 [....... ... ....] // start address 4. segment + length (0x0f20+0x104e=0x1f6e)
    110e: 00 00 00 00 f9 d7 91 31 00 00 00 00 00 00 00 00 [.......1........]
    111e: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    112e: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
...
    1f6e: 33 93 92 43 31 00 00 00 02 00 a0 00 78 00 00 00 [3..C1.......x...]  // magic bytes 0200 and sensor size in little endian 0x00a0 0x0078
    1f7e: 00 00 00 00 9f 00 00 00 77 00 00 00 00 00 00 00 [........w.......]
    1f8e: 00 00 00 00 00 00 00 00 f9 2e e7 2e fb 2e ef 2e [................]   // here starts the 16 Bit Stream
    1f9e: 05 2f f6 2e e6 2e f2 2e 01 2f f7 2e 07 2f ea 2e [./......./.../..]
    1fae: f4 2e fb 2e fa 2e 03 2f 01 2f 06 2f f1 2e 07 2f [......./././.../]
...
    Warning = Ignored APP1 segment length 42312 (unknown header)


With reverse engineering I decrypted the header.
In the sample above there are a header for 4 segments (4x32Byte Header)
The address of first segments stands (6*16+5)Bytes from begin of JPEG-APP1-block.
3-Byte-Start-Address:  00 02 00, then 3 Byte with the length of the segment 00 09 ac
.... Second segment starts: 00 0b ac / length: 00 03 10
....  Fourth segment starts 00 0f 20 / length: 00 96 20

The problem is that the raw sensor values are always written in different segments (from first to fourth).
If you open the camera-jpg with a flir software (Flir Tools, Quicktools etc.) the software rewrites this block and save the raw values on another position.

As workaround I look in the top of every segment for a magic byte sequence "00 20" followed by the sensor size in little endian (!)
here Flir E40: W/H = 160 /120px = 0x00A0 / 0x0078

With this information over the sensor size you can calculate the the required segment size for saving all sensor raw data:
Segment_Size= sensor_width x sensor_height x 2Byte(16Bit) + 32Byte(Header)

in this sample above from a flir e40 we need: 160px* 120px * 2Byte + 32Byte = 38432 Byte = 0x9620 Bytes
With this information we can check the start address of segments above and the length of every segment
-> we found that the 4. segment has a necessary segment length of "00 09 ac" bytes for saving raw datas
-> result: the sensor raw values saved in the 4. segment

In the 4. segment, after discussed header of 32 Byte (with sensor size etc.), starts the stream of 16 Bit Raw Values (little endian).

I wrote a short awk-script for decoding the raw values and generating a *.pgm 16 Bit picture.
This script only works for newer Flir Cams with embedded 16 Bit RAW Data. I tested it successful with pictures from Flir E40, Flir E30bx, Flir T400, Flir i60 and Flir P640 downloaded from wikipedia and flickr ;-)

Some older Flir Thermal Imaging Cameras save a PNG in the exif header (B50, B60, P60, i7).
For this Cameras you need another code (see sample http://www.nuage.ch/site/flir-i7-some-analysis ).

The working awk script generates a picture in portable graymap format (PGM)
http://en.wikipedia.org/wiki/Netpbm_format:
# cat  raw.txt
{
  for(i=1; i <=NF; i++)
  {
     # find MagicBytes off JPEG APP1 (Flir) [8. Byte = 00/01/02]
     # 46 4c 49 52 00 01 00 ?? 46 46 46 00 00 00 00 00 [FLIR....FFF.....]
     if ( $(i)=="46" && $(i)$(i+1)$(i+2)$(i+3)$(i+4)$(i+5)$(i+6)"00"$(i+8)$(i+9)$(i+10) == "464c495200010000464646" )
      {
         # search first 5 segments of JPEG APP1 (address header of segments start at 0x50, step 0x20)
          for (i1=5*16; i1<256; i1=i1+32)
         {
           # MagicBytes: Block_Size= sensor_width x sensor_height x 2Byte(16Bit) + 32Byte(Header)
           # Flir E40:  160x120px -> 120*160*2+20=38432 = 0x9620
             # Flir T400: 320x240px -> 00 40 01 f0 00 -> 0140h x 00f0h -> 0x025820 (153632 Byte)
           # calculate entry address of segment
           a=i+sprintf("%d","0x"$(i+i1+5)$(i+i1+6)$(i+i1+7))+8;
             # magic bytes for following sensor size
             if ( $(a)$(a+1) == "0200" )
           {
               # sensor witdh and height in Little-Endian
               w=sprintf("%d","0x"$(a+3)$(a+2));
               h=sprintf("%d","0x"$(a+5)$(a+4));
               #  calculatte required segment_size= width x height x 2Byte + 32Byte(Header)
               bs_sensor=2*w*h+32;
               # read real segments size from header
               bs_exif=1*sprintf("%d","0x"$(i+i1+8)$(i+i1+9)$(i+i1+10)$(i+i1+11));
               if ( bs_sensor ==  bs_exif )
               {
                    # skip header
                    a=a+32;
                    # !! here you can set own values !!
                    min=0;
                    max=65535;
                    # now write 16 Bit gray scale picture
                    print "P2", w, h ,max-min;
                    print "# this is a *.pgm picture";
                 print "# sensor size: ",w,"x",h;
                    print "# start address of 16 Bit raw data: "a-1,"d / first 2 bytes: 0x",$(a),"+ 0x100 * 0x",$(a+1);
                    print "# raw values from range from min ", min, "to max ",max-min;
                    for (k=0; k < w*h*2; k=k+2)
                    {
                         # max Exif segment size 65534 Byte -> go to next segment (add 12 Byte to start address)
                         if ((a+k-i+4)%65536 == 0 ) a=a+12;
                          tmp=1*sprintf("%d","0x"$(a+k+1)$(a+k))-min;
                         if ( tmp >= (max-min) )
                           print max-min;
                       else
                         { if ( tmp <= 0 )
                              print "0";
                           else
                              print tmp;
                         }
                    }
               }
           }
         }
      }
   }
}


I'm not using gnu awk with binary extension.
For native awk (bsd) I use hexdump for generating Asci-Code from the jpg-binary.
In this way I can feeding awk with ascii code without stop code 0x00.

Therefore you must use the awk-code in a hexdump pipe (alternate save hexdump-ascii).
Save the result as a pgm picture...
# hexdump -v -e '1/1 "%02x" " "' IR_1955.jpg | awk -f raw.txt > 16bitRAW.pgm
ore use imegamagick convert for saving a 16 Bit png
# hexdump -v -e '1/1 "%02x" " "' IR_1955.jpg | awk -f raw.txt | convert - IR_1955.png

finished...



The Script can also decode large raw datas over multiple Exif-Segments (max size is 65534Byte / segment)
There is a nice sample for testing from a very large 640 x 480 Flir Infrared Camera  P640 in wikepdia:
http://commons.wikimedia.org/wiki/File:Man_in_water_-_IR_image.jpg

in the picture the sensor raw datas  are shared over 10 JPEG-APP1-Blocks

> exiftool.exe -v3 Man_in_water_-_IR_image.jpg
... snip
JPEG APP1 (65532 bytes):
    1d7a: 46 4c 49 52 00 01 00 [b]09[/b] 46 46 46 00 00 00 00 00 [FLIR....FFF.....]  // 09 => 10 Blocks linked
    1d8a: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 [...............d]
    1d9a: 00 00 00 40 00 00 00 0e 00 00 00 02 00 00 00 00 [...@............]
    1daa: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    1dba: 00 00 00 00 93 79 3c e2 00 01 00 02 00 00 00 65 [.....y<........e]
    1dca: 00 00 00 01 00 00 02 00 00 09 60 20 00 00 00 00 [..........` ....]
    1dda: 00 00 00 00 59 bc 40 05 00 20 00 01 00 00 00 6f [....Y.@.. .....o]
    [snip 65420 bytes]
  Warning = Ignored APP1 segment length 65532 (unknown header)
JPEG APP1 (65532 bytes):
   11d7a: 46 4c 49 52 00 01 01 09 78 3b 5e 3b 68 3b 50 3b [FLIR....x;^;h;P;]
   11d8a: 4d 3b 4d 3b 56 3b 61 3b 41 3b 39 3b 3a 3b 38 3b [M;M;V;a;A;9;:;8;]
   11d9a: 2a 3b 39 3b 2c 3b 06 3b 03 3b 15 3b 07 3b 0c 3b [*;9;,;.;.;.;.;.;]
   11daa: 0e 3b e5 3a 03 3b 1c 3b 4f 3b 2f 3b 08 3b ff 3a [.;.:.;.;O;/;.;.:]
   11dba: 11 3b 11 3b 29 3b 29 3b 31 3b 34 3b 2a 3b 53 3b [.;.;););1;4;*;S;]
   11dca: 53 3b 55 3b 5a 3b 60 3b 72 3b 6e 3b 5e 3b 76 3b [S;U;Z;`;r;n;^;v;]
   11dda: a8 3b bc 3b b3 3b 53 3b 30 3b 52 3b 58 3b 41 3b [.;.;.;S;0;R;X;A;]
    [snip 65420 bytes]
  Warning = Ignored APP1 segment length 65532 (unknown header)
JPEG APP1 (65532 bytes):
   21d7a: 46 4c 49 52 00 01 02 09 f4 3b ee 3b 05 3c 02 3c [FLIR.....;.;.<.<]
   21d8a: 02 3c 08 3c fe 3b 08 3c 09 3c 2f 3c 04 3c 16 3c [.<.<.;.<.</<.<.<]
   21d9a: f5 3b fe 3b f5 3b f4 3b 05 3c f1 3b fc 3b ec 3b [.;.;.;.;.<.;.;.;]
   21daa: ee 3b ee 3b f5 3b f5 3b ed 3b f2 3b f7 3b 05 3c [.;.;.;.;.;.;.;.<]
   21dba: e2 39 df 39 eb 39 ec 39 10 3a 57 3a 42 3a 33 3a [.9.9.9.9.:W:B:3:]
   21dca: 40 3a 5e 3a 78 3a 82 3a 81 3a a0 3a ac 3a 8b 3a [@:^:x:.:.:.:.:.:]
   21dda: b2 3a c3 3a 5d 3a 94 3a 9e 3a e8 3a bb 3a b6 3a [.:.:]:.:.:.:.:.:]
    [snip 65420 bytes]
  Warning = Ignored APP1 segment length 65532 (unknown header)
JPEG APP1 (65532 bytes):
   31d7a: 46 4c 49 52 00 01 03 09 a9 3a a6 3a 9b 3a 9e 3a [FLIR.....:.:.:.:]
   31d8a: bb 3a bb 3a bd 3a bc 3a b2 3a e2 3a dd 3a ba 3a [.:.:.:.:.:.:.:.:]
   31d9a: b4 3a b9 3a b5 3a b7 3a bf 3a ba 3a c1 3a ce 3a [.:.:.:.:.:.:.:.:]
   31daa: cb 3a d7 3a d0 3a c7 3a 74 3a 27 3a 3b 3a 15 3a [.:.:.:.:t:':;:.:]
   31dba: 2b 3a 23 3a 23 3a 12 3a 10 3a 39 3a 39 3a 63 3a [+:#:#:.:.:9:9:c:]
   31dca: a8 3a c0 3a be 3a 72 3a 08 3a e9 39 e7 39 01 3a [.:.:.:r:.:.9.9.:]
   31dda: 0c 3a 61 3a 2f 3a e6 39 a7 39 a3 39 a3 39 a2 39 [.:a:/:.9.9.9.9.9]
    [snip 65420 bytes]
  Warning = Ignored APP1 segment length 65532 (unknown header)
JPEG APP1 (65532 bytes):
   41d7a: 46 4c 49 52 00 01 04 09 4e 3b 5c 3b 61 3b 21 3b [FLIR....N;\;a;!;]
   41d8a: 09 3b 3a 3b d6 3a 64 3a 23 3b a4 3b ae 3b ac 3b [.;:;.:d:#;.;.;.;]
   41d9a: d3 3b c9 3b de 3b c4 3b b0 3b c6 3b c1 3b d2 3b [.;.;.;.;.;.;.;.;]
   41daa: ce 3b d4 3b cb 3b c4 3b cb 3b c8 3b 81 3b 7e 3b [.;.;.;.;.;.;.;~;]
   41dba: 85 3b a0 3b 7c 3b 74 3b 6d 3b 6b 3b 62 3b 69 3b [.;.;|;t;m;k;b;i;]
   41dca: 7f 3b 7f 3b 72 3b 5d 3b 58 3b 2d 3b 0b 3b 73 3b [.;.;r;];X;-;.;s;]
   41dda: 0e 3b 2a 3b 22 3b 2f 3b da 3a c1 3a cd 3a a8 3a [.;*;";/;.:.:.:.:]
    [snip 65420 bytes]
  Warning = Ignored APP1 segment length 65532 (unknown header)
JPEG APP1 (65532 bytes):
   51d7a: 46 4c 49 52 00 01 05 09 85 3a 84 3a 84 3a a1 3a [FLIR.....:.:.:.:]
   51d8a: a3 3a c1 3a da 3a cc 3a a6 3a e9 3a d6 3a a5 3a [.:.:.:.:.:.:.:.:]
   51d9a: 94 3a df 3a 08 3b 42 3b 97 3b ab 3b ac 3b 6c 3b [.:.:.;B;.;.;.;l;]
   51daa: 68 3b 80 3b 89 3b 79 3b 89 3b 78 3b 3c 3b 2b 3b [h;.;.;y;.;x;<;+;]
   51dba: 46 3b 41 3b 63 3b 91 3b 94 3b 96 3b 79 3b 77 3b [F;A;c;.;.;.;y;w;]
   51dca: 76 3b 99 3b 76 3b d6 3a 17 3b 48 3b 50 3b 5c 3b [v;.;v;.:.;H;P;\;]
   51dda: 6d 3b 6a 3b 6f 3b 78 3b 64 3b 93 3b 7c 3b 42 3b [m;j;o;x;d;.;|;B;]
    [snip 65420 bytes]
  Warning = Ignored APP1 segment length 65532 (unknown header)
JPEG APP1 (65532 bytes):
   61d7a: 46 4c 49 52 00 01 06 09 10 3b 06 3b f6 3a 09 3b [FLIR.....;.;.:.;]
   61d8a: 0b 3b 46 3b 79 3b cc 3b 9c 3b 8d 3b 6b 3b 94 3b [.;F;y;.;.;.;k;.;]
   61d9a: 85 3b 66 3b 5d 3b 6c 3b 93 3b 9a 3b aa 3b e4 3b [.;f;];l;.;.;.;.;]
   61daa: 92 3b b8 3b c8 3b b9 3b 8d 3b 70 3b 92 3b 9a 3b [.;.;.;.;.;p;.;.;]
   61dba: b2 3b 66 3b 5e 3b 69 3b 6c 3b 45 3b 45 3b 35 3b [.;f;^;i;l;E;E;5;]
   61dca: 2e 3b 67 3b dc 3b de 3b af 3b c6 3b cc 3b c9 3b [.;g;.;.;.;.;.;.;]
   61dda: 85 3b 32 3b 25 3b 87 3b b7 3b b0 3b 8c 3b 22 3b [.;2;%;.;.;.;.;";]
    [snip 65420 bytes]
  Warning = Ignored APP1 segment length 65532 (unknown header)
JPEG APP1 (65532 bytes):
   71d7a: 46 4c 49 52 00 01 07 09 98 3b 71 3b 5f 3b 47 3b [FLIR.....;q;_;G;]
   71d8a: 6d 3b c7 3b cb 3b cd 3b b0 3b a7 3b a1 3b c5 3b [m;.;.;.;.;.;.;.;]
   71d9a: 80 3b 87 3b 70 3b 6d 3b 92 3b ad 3b 86 3b c5 3b [.;.;p;m;.;.;.;.;]
   71daa: b4 3b af 3b c6 3b d6 3b d0 3b ac 3b b4 3b 8e 3b [.;.;.;.;.;.;.;.;]
   71dba: 91 3b bb 3b b1 3b b2 3b c4 3b c6 3b c9 3b a9 3b [.;.;.;.;.;.;.;.;]
   71dca: bb 3b ba 3b be 3b cb 3b b3 3b 9d 3b 9e 3b a6 3b [.;.;.;.;.;.;.;.;]
   71dda: a7 3b a3 3b a6 3b ae 3b 9b 3b 94 3b bb 3b bf 3b [.;.;.;.;.;.;.;.;]
    [snip 65420 bytes]
  Warning = Ignored APP1 segment length 65532 (unknown header)
JPEG APP1 (65532 bytes):
   81d7a: 46 4c 49 52 00 01 08 09 40 3b 5f 3b 45 3b 30 3b [FLIR....@;_;E;0;]
   81d8a: 27 3b 0c 3b 28 3b 51 3b 3d 3b 2a 3b 8e 3b 9f 3b [';.;(;Q;=;*;.;.;]
   81d9a: 51 3b 0e 3b 1d 3b 0c 3b 28 3b 35 3b 45 3b 06 3b [Q;.;.;.;(;5;E;.;]
   81daa: 07 3b 05 3b 08 3b 0f 3b f0 3a e8 3a f3 3a 06 3b [.;.;.;.;.:.:.:.;]
   81dba: 0f 3b 13 3b 13 3b fc 3a f5 3a f8 3a fc 3a d1 3a [.;.;.;.:.:.:.:.:]
   81dca: d0 3a c0 3a ef 3a d9 3a e2 3a 37 3b 4b 3b 4a 3b [.:.:.:.:.:7;K;J;]
   81dda: eb 3a ef 3a bb 3a bc 3a d6 3a e5 3a bc 3a 83 3a [.:.:.:.:.:.:.:.:]
    [snip 65420 bytes]
  Warning = Ignored APP1 segment length 65532 (unknown header)
JPEG APP1 (28644 bytes):
   91d7a: 46 4c 49 52 00 01 09 09 e4 3a fd 3a e8 3a f9 3a [FLIR.....:.:.:.:]
   91d8a: fe 3a 07 3b f8 3a fc 3a f4 3a fe 3a dc 3a e7 3a [.:.;.:.:.:.:.:.:]
   91d9a: d9 3a c3 3a c1 3a bd 3a ab 3a c5 3a c8 3a b2 3a [.:.:.:.:.:.:.:.:]
   91daa: d3 3a c7 3a a1 3a af 3a 94 3a 93 3a 92 3a 74 3a [.:.:.:.:.:.:.:t:]
   91dba: 7f 3a 86 3a ae 3a a4 3a b1 3a 97 3a b7 3a 9b 3a [.:.:.:.:.:.:.:.:]
   91dca: 9d 3a 91 3a 8a 3a 9e 3a 8f 3a 96 3a 93 3a a5 3a [.:.:.:.:.:.:.:.:]
   91dda: b3 3a b5 3a 96 3a b7 3a 7a 3a 96 3a 94 3a af 3a [.:.:.:.:z:.:.:.:]
    [snip 28532 bytes]
  Warning = Ignored APP1 segment length 28644 (unknown header)


as attachments the converted picture from wikipedia-site overlayed with 2 different palettes
# convert p640.png rain256.png -clut p640-rainbow.jpg
# convert p640.png Midgreen256.png -clut p640-Midgreen.jpg


Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 20, 2013, 01:56:43 PM
Hi Thomas,

Thanks for this information.  I'll look at it in detail within the next few days and let you know if I have any questions.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 20, 2013, 06:27:47 PM
another test pictures from wikipedia with full radiometric data in exif header

large 640x480 image from a Flir SC640
http://commons.wikimedia.org/wiki/File:IRWater.jpg

medium 320x240 image from a Flir E60
http://commons.wikimedia.org/wiki/File:IR_Fussbodenheizung.jpg

small 160x120 image from a Flir E30bx
http://commons.wikimedia.org/wiki/File:Image_thermique_de_l%27%C3%A9mission_d%27un_radiateur_%C3%A0_travers_un_mur.jpg



you can convert this samples with a one-liner by using your one colour palette
(use raw.txt from my first post)
$ hexdump -v -e '1/1 "%02x" " "' IR.jpg | awk -f raw.txt | convert - -auto-level rain256.png -clut converted.jpg
instead -auto-level (= -contrast-stretch 0%,0% ) you can use clipping of spikes for better results:  -contrast-stretch 2%,2%

as attachments some nice colour palettes for this one-liner ... and the three samples with rainbow palette
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 25, 2013, 08:45:47 AM
I haven't forgotten about this, but this will take a bit of work.  I'm hoping to get to it soon.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 25, 2013, 06:50:58 PM
 no problem, it's a hint for you - my awk script works fine as workaround ...  ;)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 28, 2013, 02:37:30 PM
I have added the ability to extract the thermal image data.  It will appear in ExifTool 9.25.

Things went well.  There is lots of other information I would like to decode, but for now I am just extracting the thermal image data.

The only difference that may impact you is that I have formatted it as a TIFF image instead of PGM.

If you want to play with this before the official release, you can download a pre-release here (https://exiftool.org/Image-ExifTool-9.25p.tar.gz).

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 28, 2013, 07:44:33 PM
wow, you knew that I'm using a mac osx binary...

all works fine
exiftool -b -FlirImage IR_2284.jpg | convert - -auto-level test.png
I tested it with a photo from a Flir E40 (120x160) and Flir SC640 (640x480).
Also successfull tested it with converted images from Flir Software "Flir Tools" and "Flir QuickReport".

exiftool -a -u -g1 IR_2262.jpg
...
---- FLIR ----
FLIR Image                      : (Binary data 38616 bytes, use -b option to extract)
FLIR Image Type                 : TIFF

better describe it with "FLIR 16 bit raw data"
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 29, 2013, 07:26:02 AM
Great!  Glad it works for you.

About the description... You're talking about the tag name?  (I can't change the "Binary data ..." description.)  I like FLIRImage because exiftool returns a valid image file format (either TIFF or PNG).  If I called it FLIRRawData then there would be no indication that the data is returned in a usable image format.

I am keen to try to decode more of the FLIR information, including the maker notes.  If you have FLIR hardware and/or software, maybe you can figure some of this out.  Use the -u option to see the MakerNotes information:

> exiftool -u -makernotes:all ../testpics/FLIR/Man_in_water_-_IR_image.jpg
Unknown 0x0001                  : 283
Unknown 0x0002                  : 276
Unknown 0x0003                  : 0.95
Unknown 0x0004                  : 238
Unknown 0x0005                  : 393
Unknown 0x0006                  : 233
Unknown 0x0007                  : 9C9E9EFA0A25446E21E3FFA54BCFD87
Unknown 0x0008                  : 00000000000000000000000000000000
Unknown 0x0009                  : 4........@oQ?Cp:.p:[...]
Unknown 0x000a                  : 1


Also, there are other records in the FLIR APP1 metadata that may have some interesting information.  Record number 0x01 contains the raw data ( I am identifying this by the record number instead of your technique of looking for 0x0200, but for the Man_in_water image for example there are also records 0x20, 0x22 and 0x21 (in that order) -- you can see these now with the -v3 option.

Thanks for any help you can provide in decoding more of this information.  I'll do what I can myself, but without FLIR equipment and software I probably won't be able to figure out very much.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 29, 2013, 01:25:22 PM
I know, there are same magic temperatures fields in jpg.

as attachment a screenshot from (free) Flir Software with loaded "Man_in_water_-_IR_image.jpg"
Link: http://support.flir.com/SwDownload/app/RssSWDownload.aspx?ID=38

I'm only sure with this three tags:
Unknown 0x0003                  : 0.95 (adjust emissivity, see: http://en.wikipedia.org/wiki/Thermography#Emissivity )

Unknown 0x0005                  : 393 Kelvin (upper value of temperature range)
Unknown 0x0006                  : 233 Kelvin (lower value of temperature range)


the FLIR P640 has two temperature ranges:
  –40°C to +120°C (–40°F to +248°F)
  0°C to +500°C (+32°F to +932°F)

but if you are loading the Man_in_water in Flir Software above, then changes the values to

Unknown 0x0001                  : 300 K (max. Temp in Image)
Unknown 0x0002                  : 274K (min. Temp in Image)
Unknown 0x0003                  : 0.95 (emissivity)
Unknown 0x0004                  : 238
Unknown 0x0005                  : 292K ??
Unknown 0x0006                  : 275K ??


I think its not worth to decode this values, but you can export the decoded sensor size (16 bit tiff)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 29, 2013, 02:44:57 PM
This is very useful, thanks!  I didn't know about the free software.  I'll download it and run some tests when I can get access to a Windows system (it will be a few days).

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 29, 2013, 03:48:18 PM
Quote from: Phil Harvey on March 29, 2013, 07:26:02 AM
I like FLIRImage because exiftool returns a valid image file format (either TIFF or PNG).  If I called it FLIRRawData then there would be no indication that the data is returned in a usable image format.

... or maybe RawThermalImage?

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 29, 2013, 05:51:31 PM
Quote from: tomas123 on March 28, 2013, 07:44:33 PM
wow, you knew that I'm using a mac osx binary...
your binary is a perl script   :-[

I looked at your FLIR.pm and saw, that you also decoded the strange PNG files from Flir B50, B60, P60, i7 Etc.  8)

RawThermalImage is nice

some background infos:
the dependency between 16 Bit RAW and temperature is not 100% linear.
the Flir software calculates between sensor values and some physical environment conditions
google:    flir "The measurement formula"

on a sample picture I got following correlation between RAW and Grad Celsius.
my temperature range is 0 = –40°C and 2^16  = +120°C

RAW    Grad Celsius
0 -40,011
18498 25,791
18598 26,319
18722 26,969
18861 27,694
18980 28,311
19080 28,826
19180 29,34
19280 29,851
19380 30,359
19480 30,865
19580 31,369
19680 31,871
19782 32,381
19884 32,888
19992 33,423
20104 33,975
20210 34,495
20315 35,008
20433 35,581
20567 36,23
20721 36,97
20928 37,958
21121 38,872
21379 40,083
21620 41,204
21813 42,094
21985 42,882
22114 43,47
22270 44,177
22417 44,839
22611 45,709
22891 46,953
23446 49,385
24636 54,454


the batch decoding of raw values is very usefull for making of panorama pictures (no scale and logo on the single picture)
the resolution of a "low cost" infrared cam is awfull
but I you make 4x4 pictures (or more), then you get a nice upgrade...

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 29, 2013, 06:16:10 PM
a comment:
ExifTool.pm
4932                my $chunkNum = Get8u($segDataPt, 6);
4933                my $chunksTot = Get8u($segDataPt, 7) + 1; # (note the "+ 1"!)
4934                $verbose and print $out "$$self{INDENT}FLIR chunk $chunkNum of $chunksTot\n";


this gives from
  FLIR chunk 0 of 10
to last
  FLIR chunk 9 of 10
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 29, 2013, 07:19:48 PM
it's crazy:
for decoding the PNG you must swap upper and lower byte (little endian)

link to cat picture:
http://www.nuage.ch/site/flir-i7-some-analysis/

$ exiftool -b -FlirImage IR_0248.jpg | convert - -compress none cat.pgm
$ awk -f png.txt cat.pgm | convert -  -auto-level cat.png
$ cat png.txt
{
if (NR < 4)
   { print $0 }
else
   { for(i=1; i <= NF ; i++)
     {
      k = 256*($(i)%256)+int($(i)/256)
      printf("%d ",k)
     }
     print ""
   } 
}


see attachment for result


a larger PNG (180x180) from Flir B60
http://commons.wikimedia.org/wiki/File:Aqua_Tower_thermal_image.jpg

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 29, 2013, 07:51:08 PM
Quote from: tomas123 on March 29, 2013, 05:51:31 PM
your binary is a perl script   :-[

Yes.  All I needed to know was that you weren't running the Windows EXE version.  The other versions are pure Perl.

QuoteI looked at your FLIR.pm and saw, that you also decoded the strange PNG files from Flir B50, B60, P60, i7 Etc.  8)

Yes.  I noticed the funny colours too, but I understand now that you tell me they swapped the byte order.  Funny.

QuoteRawThermalImage is nice

Great.  I'll go with that then.

Quotesome background infos:
the dependency between 16 Bit RAW and temperature is not 100% linear.
the Flir software calculates between sensor values and some physical environment conditions
google:    flir "The measurement formula"

Thanks for the info.

Quotethis gives from
  FLIR chunk 0 of 10
to last
  FLIR chunk 9 of 10

Yes.  I wasn't entirely happy about this either, but it is accurate.  The chunks are numbered from 0.  However, it does make sense for me to add 1 for the print statement.  I'll think about this.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 29, 2013, 07:52:21 PM
There's no rule without an exception

I found here
http://forums.mtbr.com/lights-night-riding/modding-p60-dropin-style-torch-better-heat-dissipation-674339.html
some pics from a ThermaCAM E65
$ exiftool IR_0627.jpg
Make                            : FLIR Systems AB
Camera Model Name               : ThermaCAM E65
...
FLIR Image                      : (Binary data 20065 bytes, use -b option to extract)
FLIR Image Type                 : PNG


there is the byte order in the PNG correct
this gives the correct image
exiftool -b -FlirImage IR_0627.jpg > IR_0627.png

but if you open this picture with Flir Software Quickreport (see above) and save it then you also change the byte order (reverse PNG)

The ThermaCAM E65 is from year 2006.
You should not invest too much power in this old versions from Flir.
Newer Cam don't use embedded PNG or saves PNG with reverse byte order.



it has the appearance that the reverse byte order is a global switch

you can see, that the Flir Software changed all byte to little endian (header+data)
old native file from cam
exiftool -v3 IR_0627.jpg
  FLIR Record 0x01, offset 0x01c0, length 0x4e3c
    0000: 02 00 a0 00 78 00 00 00 00 00 00 00 3f 01 00 00 [....x.......?...]
    0010: ef 00 0f 00 02 00 01 00 6c 0e 06 00 00 00 00 00 [........l.......]
    0020: 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 [.PNG........IHDR]
    0030: 00 00 00 a0 00 00 00 78 10 00 00 00 00 00 59 7a [.......x......Yz]
    0040: f0 00 00 20 00 49 44 41 54 78 01 45 dd 09 94 5f [... .IDATx.E..._]
    0050: 59 55 2e f0 73 6b 48 aa 92 4a a5 32 a7 d3 69 e8 [YU..skH..J.2..i.]

   
same file after editing with Flir Software
exiftool -v3 IR_0627_quickreport.jpg
  FLIR Record 0x01, offset 0x0200, length 0x4e81
    0000: 00 02 00 a0 00 78 00 00 00 00 00 00 01 3f 00 00 [.....x.......?..]
    0010: 00 ef 00 0f 00 02 00 02 0e 6c 00 06 00 00 00 00 [.........l......]
    0020: 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 [.PNG........IHDR]
    0030: 00 00 00 a0 00 00 00 78 10 00 00 00 00 00 59 7a [.......x......Yz]
    0040: f0 00 00 20 00 49 44 41 54 78 01 45 dd 09 74 67 [... .IDATx.E..tg]
    0050: d9 55 1e fa 73 a4 52 95 54 52 a9 54 73 75 75 d9 [.U..s.R.TR.Tsuu.]

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 29, 2013, 09:04:37 PM
off topic but nice:
imagemagick can change byte order in raw files

use our cat: http://www.nuage.ch/site/flir-i7-some-analysis/

$ exiftool -b -FlirImage IR_0248.jpg > cat1.png
$ convert cat1.png gray:- | convert -depth 16 -endian msb -size 120x120 gray:- -auto-level cat2.png

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 29, 2013, 09:36:19 PM
Hi Thomas,

This is interesting, but I don't plan to modify the raw data.  I just return the PNG as is, or tack a TIFF header onto the raw data, but that's as far as I'll go.  (ExifTool doesn't do image manipulations -- that's for other software.)

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 30, 2013, 05:13:03 AM
I am of the same opinion and was surprised that you have ever extract the funny PNG images.
You can write a note about the reverse byte order of some Flir PNG in your history...
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 04, 2013, 12:39:31 PM
Hi Tomas, (sorry if I spelled your name wrong before)

I've really done a LOT of work on this, and have managed to accumulate a collection of images from 31 different FLIR camera models (now available in my metadata repository (https://exiftool.org/sample_images.html)).

I have decoded more potentially useful information:

> exiftool ../testpics/FLIR/Man_in_water_-_IR_image.jpg -a -flir:all
Image Maximum Temperature       : 283
Image Minimum Temperature       : 276
Emissivity                      : 0.95
Raw Thermal Image Width         : 640
Raw Thermal Image Height        : 480
Raw Thermal Image Type          : TIFF
Raw Thermal Image               : (Binary data 614604 bytes, use -b option to extract)
Emissivity                      : 0.95
Distance                        : 1.00 m
Reflected Apparent Temperature  : 20.0 C
Atmospheric Temperature         : 20.0 C
IR Window Temperature           : 20.0 C
IR Window Transmission          : 1.00
Relative Humidity               : 50.0 %
Camera Maximum Temperature      : 120.0 C
Camera Minimum Temperature      : -40.0 C
Camera                          : FLIR P640
Camera Serial 1                 : 40402-1100X1
Camera Serial 2                 : 404002646
Camera Firmware                 : 15.0.14
Lens                            : FOL38
Lens Serial 1                   : T197089
Lens Serial Number              : 407802518
Palette Colors                  : 224
Above Color                     : 170 128 128
Below Color                     : 50 128 128
Overflow Color                  : 67 216 98
Underflow Color                 : 41 110 240
Isotherm 1 Color                : 100 128 128
Isotherm 2 Color                : 100 110 240
Palette Method                  : 0
Palette Stretch                 : 2
Palette File Name               : \FlashFS\system\iron.pal
Palette Name                    : Iron
Palette                         : (Binary data 672 bytes, use -b option to extract)


I plan to release the official version in a few days, but I have updated the pre-release (https://exiftool.org/Image-ExifTool-9.25p.tar.gz) in case you get a chance to test it out before then.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 04, 2013, 07:43:40 PM
great and hard work!

You have not changed the dirty hack
if (length $val == $w * $h * 2)  :)
I have also seen the color palette...

some hints:
Camera Serial 1 = Part Number
Camera Firmware = App Core ??
(I changed my Camera Firmware from 2.10.7 to 2.19.10 but the exiftool-value is unchanged 20.0.0)

$exiftool IR_0088.jpg -a -flir:all
Camera                          : FLIR E40
Camera Serial 1                 : 49001-2001
Camera Serial 2                 : 4903xxxx
Camera Firmware                 : 20.0.0
Lens                            : FOL18
Lens Serial 1                   :
Lens Serial Number              :


with web frontend of camera I get:
http://192.168.64.1/SysInfo.asp

Camera
Name: FLIR E40
Part # 49001-2001
Serial # 4903xxxx

Kits
Name Version Date
SW combination  2.10.7
appkit 3.0.8 4-Sep-2012
userconf E40 0.10  28-Apr-2011 
extfontkit 1.1 29-Nov-2011 
SLCO OS image  15.4.4 2012-06-25
prodkit 3.0.0.7 28-Aug-2012 


Firmware
Name Version Date From
MIRA_FPGA 5.3.1.18 - FLIR

Software
Name Version Date From
AppCore 20.0.0.1 03-Sep-2012  upalmer@SE-BRYGG5/ALPHA_1.6 
AppServices 20.0.0.1 03-Sep-2012  upalmer@SE-BRYGG5/ALPHA_1.6 
Bootloader 15.0.10.0 - FLIR
ProdApp 20.0.0.1 28-Aug-2012  upalmer@SE-BRYGG5/ALPHA_1.6 
RTP 20.0.0.1 04-Sep-2012  upalmer@SE-BRYGG5/ALPHA_1.6 
ResMon 20.0.0.1 04-Sep-2012  upalmer@SE-BRYGG5/ALPHA_1.6 
WinCE 6.0.0.0 2005 Microsoft
appcore_dll 1.6.1.1 03-Sep-2012  upalmer@SE-BRYGG5
common_dll 1.6.1.1 03-Sep-2012  upalmer@SE-BRYGG5
fvd 15.0.28.0 - -
ui 20.0.0.1 04-Sep-2012  upalmer@SE-BRYGG5/ALPHA_1.6 





Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 04, 2013, 08:51:11 PM
Great, thanks!

I'll make your suggested changes, but I'm going to mark the AppCoreVersion as Unknown because that one is a bit funny.

And yes, the "$w * $h * 2" test has been very reliable! :)

Please let me know if you notice anything else that should be changed.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 05, 2013, 07:59:02 AM
I think I'll go with "CameraSoftware" instead of "AppCoreVersion", and remove the Unknown flag.  Actually, this is equivalent to the original "CameraFirmware" guess, except that that it doesn't imply the software is persistent in memory.

Also, I'm changing a few other names so your output will change to this:

Camera Model                    : FLIR E40
Camera Part Number              : 49001-2001
Camera Serial Number            : 4903xxxx
Camera Software                 : 20.0.0
Lens Model                      : FOL18
Lens Part Number                :
Lens Serial Number              :


One question:  When you use the -u option you will see a number of unknown temperatures.  Do you have any idea about the significance of these?  For the "Cat" image for example, the Unknown information is:

[MakerNotes]    Unknown Temperature             : 0
[MakerNotes]    Unknown Maximum Temperature     : 37
[MakerNotes]    Unknown Minimum Temperature     : 22
[MakerNotes]    FLIR 0x0007                     :
[MakerNotes]    FLIR 0x0008                     :
[MakerNotes]    FLIR 0x0009                     :
[APP1]          Unknown Temperature 2           : 150.0 C
[APP1]          Unknown Temperature 3           : -60.0 C
[APP1]          Unknown Temperature 4           : 120.0 C
[APP1]          Unknown Temperature 5           : -40.0 C
[APP1]          Unknown Temperature 6           : 150.0 C
[APP1]          Unknown Temperature 7           : -60.0 C


I'm talking about the 6 unknown temperatures from APP1.  (We already discussed the ones in the MakerNotes.)

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 07, 2013, 12:29:49 PM
@Phil
I think decoding of this unknown values make no sense. Flir has no common usages of this free variables.




I'm sorry for this off-topic posting, but I will give some hints for other readers for using Flir raw images with some scripting tools. (google hit this page)

use:
Exiftool V 9.25
sample image from attachment
Imagemagick convert Q16 (16 Bit)

for panorama stitching:
- 16 Bit Panorama Software
- Unix Tools: awk, hexdump



(sample 1) Extract Color Table and Raw Image from Flir radiometric JPG and generate a new Image

the embedded Flir Color Palette uses Y Cr Cb (you must change the channel Cb with Cr ->  YCbCr )

first check numbers of colors of current table
$ exiftool IR_1546.jpg | grep Palette
Palette Colors                  : 224
Palette Method                  : 0
Palette Stretch                 : 1
Palette Name                    : Iron
Palette                         : (Binary data 672 bytes, use -b option to extract)


Size is here 224x1 Pixel (=672/3)
$ exiftool IR_1546.jpg -b -Palette | convert -size 224X1 -depth 8 YCbCr:- -separate -swap 1,2 -set colorspace YCbCr -combine -colorspace RGB pal-iron.png

hint: this is a  ugly [16,235] video pal color table ( see http://avisynth.org/mediawiki/ColorBars_theory )
for better color tables [0,255] use color tables from attachment

now extract the Flir Raw Image (a 16 Bit Tiff from -40 Grad to +120 Grad)
$ exiftool -b -RawThermalImage IR_1546.jpg > IR_1546.tiff
( for multiple images - use exiftool -b -RawThermalImage IR*.jpg -w %f.tif )

transform the Color Lookup Table to the grayscale Image
you must expand your Tiff to suitable 8 Bit Values (suggest: use contrast-stretch 2%,2%)

$ convert IR_1546.tiff  -contrast-stretch 2%,2% -depth 8 -resize 200\% pal-iron.png -clut entrance-iron.png

the temperature values can be calculated only with the Flir Software ( a little bit non linear )
if you compare your own maked colors with a flir tool, then you can write the known temperature to many images  (batch)

check your sensor values
$  identify -verbose IR_1546.tiff | grep -E "min:|max:"
      min: 12417 (0.189471)
      max: 15410 (0.235142)


use absolute contrast level for all images in your serie, try some values
I choose min=13400 / max=14500
now generate an image with a temperature scale
use: pal-iron.png and IR_1546.tiff from above

$ convert -size 20x256 gradient: pal-iron.png -clut -mattecolor white -frame 5x5 gradient.png
$ convert gradient.png -background white -font ArialB -pointsize 15 label:'+4.0' +swap -gravity Center -append  label:'-5.9' -append gradient-tmp.png
$ convert IR_1546.tiff -level 13400,14500 -depth 8 -resize 300\% pal-iron.png -clut -background white -flatten +matte gradient-tmp.png -gravity East +append raw2color.png

see result raw2color.png in attachments
for other color tables see also attachment






(sample 2) make a panorama from raw images
here I use a Flir E40 with 160x120 Pixel for generating a 800x600 Pixel panorama image

extract RAW images
$ exiftool -b -RawThermalImage IR*.jpg -w %f.tif

find max / min sensor values and expand Tiff for better recognition of panorama software

min=$(identify -verbose IR*.tif | grep -n3 statist | grep min | sort -k 3 | head -n 1 | cut -d' '  -f8)
max=$(identify -verbose IR*.tif | grep -n3 statist | grep max | sort -k 3 | tail -n 1 | cut -d' '  -f8)
echo $min $max
for i in IR*.tif; do convert $i -level $min,$max -resize 200\% _$i;done


now you have some 16-Bit-Grayscale-Tiff for stitching (don't forget  $min $max for later correction, see below)

I'm using two panorame softwares for stitching 16 Bit Images

stitch your 16 Bit _IR*.tif images and save result to a 16 Bit Tif

now comes the hardest part:

Variant 1: you can colorize your panorama with imagemagick (see above) -> you're done

Variant 2: generate a new Flir Radiometric Panaroma JPG for measuring with Flir Software

- now you need a Flir Image with enough space for injecting your new Raw Values in the space of a dummy Flir Picture
- you can generate a large Flir Dummy Image with the very bad Panorama function of Software Flir Tools  ( use 30 day Trial)
- alternative use an other large Flir Images from Internet ( see my attachment for a 800x600 Pixel sample)
- or Phil has an idea how to write a new JPEG APP1 (Flir) segment

in this sample I create a 800x600 Panorama

(1) with your Panorama Software create a exact 800x600 Pixel Grayscale 16 Bit Image panorama.tif (same size like dummy-jpg!!)
(2) decode a 800x600 radiometric dummy image in decimal values (with hexdump) for using with awk (a flir800x600.jpg dummy you can use my attachment)
(3) inject your 800x600 Raw Panorama Values into the 800x600 dummy Image (don't forget reusing $min $max from above)

$ hexdump -v -e '1/1 "%u" " "' flir800x600.jpg > flir800x600.dec
$ convert panorama.tif -colorspace Gray +level $min,$max -background black -flatten gray:- | hexdump -v -e '1/1 "%u\n"' | awk -f pano_dec.txt - flir800x600.dec > Pano800x600.jpg

injecting awk script pano_dec.txt -> see attachment

open Pano800x600.jpg with Flir Software (this generates a new jpg from the embedded raw values)
select you color table and set some measuring points

-> see the result Pano800x600.jpg with two measuring points as attachment


Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 07, 2013, 04:00:45 PM
This is very useful, thanks.

I have changed my notes to indicate Y Cr Cb colors instead of Y Cb Cr.

You say that only FLIR software can calculate the temperatures, isn't the formula given in "the measurement formula" reference you gave?  Additionally, I think that ExifTool now extracts all of the necessary parameters to apply this formula.  The only thing I am not sure about is scaling the digital values to a voltage.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 07, 2013, 05:03:33 PM
you are right
With some reference values and the measurement formula you can calculate beetwen sensor voltage (=RAW??) and object temperature
- but I wanted to give to other users a simple guide  ::)

In Flir Quicktool you can export a (Excel) *.csv table with temperature of every pixel.
With the known raw values then you have enough reference values (Voltage to Temperature) for further studies about the measurement formula ;)
see my message: https://exiftool.org/forum/index.php/topic,4898.msg23663.html#msg23663

PS: The injection of panorama raw values to another large Flir JPG (same size) is a dirty hack.
Can Exiftool with minor adjustments write the JPEG APP1 (Flir) segments with a RawThermalImage of another size?
There are only two places where the image size H/W and (H-1)/(W-1) are entered.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 08, 2013, 08:56:11 AM
I am only decoding the raw image size from the RawData record, but this information is also duplicated in the CameraInfo record, and possibly other places.  So changing the image size may be more difficult than you think.  Plus, it would require a significant hack to ExifTool because there would still be a lot of work to do to rewrite the FLIR APP1 structure.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 10, 2013, 06:30:21 AM
ok, no problem


only for your information:

I found here a nice support document for the Flir FFF Header (google is my friend )
http://www.workswell.cz/manuals/flir/hardware/A3xx_and_A6xx_models/Streaming_format_ThermoVision.pdf

with this information we can decode all unknown Bytes off Flir Header:

$ exiftool -v5 IR_1135.jpg

JPEG APP1 (42312 bytes):
    0f0c: 46 4c 49 52 00 01 00 00                         [FLIR....        ]
----------------------tagFLIRFILEHEAD---------------------------------------
                                  46 46 46 00             [        FFF.....] char szFormatID[4]; /* Fileformat ID 'FFF\0'       4  4
                                              00 00 00 00 [           .....] char szOrigin[16]; /* File origin                 16 20
    0f1c: 00 00 00 00 00 00 00 00 00 00 00 00
                                              00 00 00 64 [...............d] unsigned long dwVersion; /* File format version    4 24 
    0f2c: 00 00 00 40                                                        unsigned long dwIndexOff; /* Pointer to indexes    4 28
                      00 00 00 0e                                            unsigned long dwNumUsedIndex; /* Number of indexes 4 32
                                  00 00 00 02                                unsigned long dwNextID; /* Next free index ID      4 36
                                              00 00                          unsigned short usSwapPattern;/* endian order(!!)   2 38
                                                    00 00 [...@............] unsigned short Spare[7]; /* Spare                 14 52
    0f3c: 00 00 00 00 00 00 00 00 00 00 00 00
                                              00 00 a5 40 [...............@] unsigned long reserved[2]; /* reserved             8 60
    0f4c: 00 00 00 00                                                       
                      56 52 ac e1                                            unsigned long dwChecksum; /* Head & index checksum 4 64 bytes */
---------------------- 1. tagFLIRFILEINDEX-----------------------------------------
                                  00 01                                      TAG_MAIN_T wMainType; /* Main type of index       2  2
                                        00 02                                unsigned short wSubType; /* Sub type of index     2  4
                                              00 00 00 65 [....VR.........e] unsigned long dwVersion; /* Version for data      4  8
    0f5c: 00 00 00 01                                                        unsigned long dwIndexID; /* Index ID              4 12
                      00 00 02 00                                            unsigned long dwDataPtr; /* Pointer to data       4 16
                                  00 00 96 20                                unsigned long dwDataSize; /* Size of data         4 20
                                              00 00 00 00 [........... ....] unsigned long dwParent; /* Parentnr               4 24
    0f6c: 00 00 00 00                                                        unsigned long dwObjectNr; /* This object nr       4 28
                      a2 95 6b 65                                            unsigned long dwChecksum; /* Data checksum        4 32 bytes */
---------------------- 2. tagFLIRFILEINDEX-----------------------------------------
                                  00 20                                      TAG_MAIN_T wMainType; /* Main type of index       2  2
                                        00 01                                unsigned short wSubType; /* Sub type of index     2  4
                                              00 00 00 71 [......ke. .....q] unsigned long dwVersion; /* Version for data      4  8
    0f7c: 00 00 00 01 00 00 98 20 00 00 09 ac 00 00 00 00 [....... ........]
    0f8c: 00 00 00 00 fc e2 f6 68
---------------------- 3. tagFLIRFILEINDEX-----------------------------------------
                                  00 22 00 01 00 00 00 68 [.......h.".....h]
    0f9c: 00 00 00 01 00 00 a1 cc 00 00 03 10 00 00 00 00 [................]
    0fac: 00 00 00 00 9b 9f 81 a2
---------------------- 4. tagFLIRFILEINDEX-----------------------------------------
                                  00 21 00 01 00 00 01 05 [.........!......]
    0fbc: 00 00 00 01 00 00 a4 dc 00 00 00 64 00 00 00 00 [...........d....]
    0fcc: 00 00 00 00 6d 9d 1a a1
----------------------END-----------------------------------------
                                  00 00 00 00 00 00 00 00 [....m...........]
    0fdc: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]


with your great work the "wMainType; /* Main type of index" decoded to
0x01 => {        Name => 'RawData',
0x20 => {        Name => 'CameraInfo',
0x21 - ToolInfo (spot tool, line tool, area tool)
0x22 => {        Name => 'PaletteInfo',
0x23 => {        Name => 'TextInfo',
0x24 => {        Name => 'EmbeddedAudioFile',
# 0x27: 01 00 08 00 10 00 00 00
0x2b => {        Name => 'GPSInfo',
0x2e => {        Name => 'ParamInfo',


they say:  if wMainType = 01 =  FFF_TAGID_Pixels
then are the next 2 Bytes wSubType
/* Sub Tags for FFF_TAGID_Pixels */
enum {
FFF_Pixels_BE = 1, /* Big endian pixel data block */
FFF_Pixels_LE = 2, /* Little endian pixel data block */
FFF_Pixels_PNG = 3 /* PNG compressed pixel data block
*/

but I think, that 1 and 2 apply for all tags ( endian order)


Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 10, 2013, 07:51:10 AM
Great find!  Thanks for the link!

I'll study this and see if I missed anything useful.  Just one point though...

Quote from: tomas123 on April 10, 2013, 06:30:21 AM
they say:  if wMainType = 01 =  FFF_TAGID_Pixels
then are the next 2 Bytes wSubType
/* Sub Tags for FFF_TAGID_Pixels */
enum {
FFF_Pixels_BE = 1, /* Big endian pixel data block */
FFF_Pixels_LE = 2, /* Little endian pixel data block */
FFF_Pixels_PNG = 3 /* PNG compressed pixel data block
*/

but I think, that 1 and 2 apply for all tags ( endian order)

I already thought of this, and had compared the "subtype" for the raw data records, but I must have been comparing the wrong values because I found exceptions and so discounted this correlation.  But trying again now I find the relationship 2=TIFF, 3=PNG to hold true.  To date, I haven't seen a big-endian TIFF.   For all other record types, the "subtype" is 1 in all my samples, regardless of whether record fields are big or little endian.

- Phil

P.S. From this documentation it looks like FLIR is a stand-alone file format (not just in JPEG APP1).  Have you ever come across any samples of this?

Edit: I found one sample here (http://www.camerahacker.com/Forums/DisplayComments.php?file=SDK/FFF_file_format)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 10, 2013, 09:41:38 AM
I have gone over fff.h carefully, but haven't found anything that makes me want to change my current decoding.  It did confirm a number of my suspicions though, so this was useful.  Also, I updated the comments to be more complete.  The header file is a bit out of date though, and doesn't include a number of additional records that I have decoded.

Too bad I didn't know about this earlier, it would have saved a lot of work.  The same thing happened when I decoded the CRW format -- I found the format document after I had already reverse-engineered the format (https://exiftool.org/canon_raw.html) myself.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 10, 2013, 01:31:54 PM
sorry, I found the document today, when I searched for: Flir FFF
a simple ask and the document is the 4. hit  :-\
( I think, the pdf is not public)

You can open FFF Files with free Software: Flir Tools
...but it gives us no new information

only for information:
as atachment a free-of-sense-picture native from my B40 in FFF format
its the same file structure, as you snip the JPG EXIF-TAG APP1 at the position: FFF (first magic bytes of *.fff)


Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 10, 2013, 02:49:50 PM
Thanks.  I'll add the ability to read the FFF files too.  (It is easy, since it is the same as the APP1 segment as you mentioned, except for a couple of minor complications... not the least of which is that Hasselblad uses the same file extension for their image format.)

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 11, 2013, 06:18:27 AM
some minor informationen

I looked around for "unsigned long dwNumUsedIndex; /* Number of indexes" and compared the header from some Flir Tools.
The index number is a large place holder for zero filled "tag data (Tag Size 32Byte=>0x20)" and you can correct calculate the first address of camera datas

see my sample
Quote
unsigned long dwIndexOff; /* Pointer to indexes
unsigned long dwNumUsedIndex; /* Number of indexes


Flir B40
JPEG APP1 (42268 bytes):
    0cb4: 46 4c 49 52 00 01 00 00 46 46 46 00 00 00 00 00 [FLIR....FFF.....]
    0cc4: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 [...............d]
    0cd4: 00 00 00 40 00 00 00 0e 00 00 00 02 00 00 00 00 [...@............] 0x40+0x0e*0x20=0x0200
    0ce4: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a5 14 [................]
    0cf4: 00 00 00 00 8d 50 c2 44
----------------------tagFLIRFILEHEAD---------------------------------------
                                  00 20 00 01 00 00 00 71 [.....P.D. .....q] 0x20 =>  'CameraInfo', TAG_MAIN_T wMainType; /* Main type of index
    0d04: 00 00 00 01 00 00 02 00 00 00 09 ac 00 00 00 00 [................] Address of FLIR Record 0x20 unsigned long dwDataPtr; /* Pointer to data
    0d14: 00 00 00 00 38 d1 b5 bc 00 22 00 01 00 00 00 68 [....8....".....h]



Flir Quickreport
JPEG APP1 (42200 bytes):
    0306: 46 4c 49 52 00 01 00 00 46 46 46 00 4d 54 58 20 [FLIR....FFF.MTX ]
    0316: 49 52 00 00 00 00 00 00 00 00 00 00 00 00 00 64 [IR.............d]
    0326: 00 00 00 40 00 00 00 0c 00 00 00 02 00 00 00 00 [...@............] 0x40+0x0c*0x20=0x01c0
    0336: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    0346: 00 00 00 00 00 00 00 00
----------------------tagFLIRFILEHEAD---------------------------------------
                                  00 01 00 02 00 00 00 64 [...............d] 0x01 => Name => 'RawData',
    0356: 00 00 00 01 00 00 01 c0 00 00 96 20 00 00 00 00 [........... ....] Address of FLIR Record 0x01
    0366: 00 00 00 00 00 00 00 00 00 20 00 01 00 00 00 66 [......... .....f]



Flir Tools
JPEG APP1 (42784 bytes):
    e544: 46 4c 49 52 00 01 00 00 46 46 46 00 4d 54 58 20 [FLIR....FFF.MTX ]
    e554: 49 52 00 00 00 00 00 00 00 00 00 00 00 00 00 64 [IR.............d]
    e564: 00 00 00 40 00 00 00 1e 00 00 00 02 00 00 00 00 [...@............] 0x40+0x1e*0x20=0x0400
    e574: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    e584: 00 00 00 00 00 00 00 00
----------------------tagFLIRFILEHEAD---------------------------------------
                                  00 01 00 02 00 00 00 64 [...............d] 0x01 => Name => 'RawData'
    e594: 00 00 00 01 00 00 04 00 00 00 96 20 00 00 00 00 [........... ....] Address of FLIR Record 0x01
    e5a4: 00 00 00 00 00 00 00 00 00 20 00 01 00 00 00 71 [......... .....q]



Flir WebViewer (Silverlight)
JPEG APP1 (65532 bytes):
    15a8: 46 4c 49 52 00 01 00 19 46 46 46 00 4d 54 58 20 [FLIR....FFF.MTX ]
    15b8: 49 52 00 00 00 00 00 00 00 00 00 00 00 00 00 64 [IR.............d]
    15c8: 00 00 00 40 00 00 00 0d 00 00 00 02 00 00 00 00 [...@............] 0x40+0x0d*0x20=0x01e0
    15d8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    15e8: 00 00 00 00 00 00 00 00
----------------------tagFLIRFILEHEAD---------------------------------------
                                  00 01 00 02 00 00 00 64 [...............d] 0x01 => Name => 'RawData'
    15f8: 00 00 00 01 00 00 01 e0 00 09 60 20 00 00 00 00 [..........` ....] Address of FLIR Record 0x01
    1608: 00 00 00 00 00 00 00 00 00 20 00 01 00 00 00 6a [......... .....j]

Only the camera calculates a checksum. All Tools sets dwChecksum to zero.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 11, 2013, 07:19:43 AM
These numbers just give the location and the number of entries in what I call the record directory (the FLIR equivalent of the EXIF IFD).  You aren't guaranteed that the camera data comes immediately after this, but in practice it is likely that it does.  Instead, the offsets in the record directory should be used to determine the location of the camera data records.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 11, 2013, 08:15:21 AM
These are only minor hints to complete the puzzle.
Nobody will calculate the first address if he can read the adress direct from "tagFLIRFILEINDEX  unsigned long dwDataPtr; /* Pointer to data ."

I write a awk script for saving a stitched 16 Bit panorama in radiometric jpg and so I must rebuild all header values...

Nice hint: if you rename a *.fff  to *.jpg you can open the picture with Flir Quickreport V1.2 SP2 (my windows runs in a VirtualBox)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 11, 2013, 11:17:40 AM
I found another interesting reference while Googling around today:

http://support.flir.com/DocDownload/Assets/62/English/1557488%24A.pdf

This gives some details about the "FLIR public image file format" (FPF), which shares some characteristics with the FFF format, and provides hints about the meanings of some of the unknown tags.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 11, 2013, 12:11:31 PM
here is the missing header file fpfimg.h (see page 97)
http://code.google.com/p/dvelib/source/browse/trunk/flirPublicFormat/fpfConverter/Fpfimg.h?spec=svn3&r=3

and here is a fpf file
http://dvelib.googlecode.com/svn-history/r3/trunk/flirPublicFormat/fpfConverter/test/1.fpf
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 11, 2013, 12:52:43 PM
let's play Rosetta Stone

I loaded my file IR_1546.jpg from B40 to ThermaCAM Researcher Pro 2.10 (trial) and saved it without some manipulation as Ir_1546.fpf
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 11, 2013, 02:47:39 PM
This is fantastic!

I have gone through your samples in detail, and have improved the tag names for a few tags and confirmed some others.

The only potentially useful information in the FPF file that I am missing from the FFF information is:

1) the date/time stamp (although this is in the JPEG EXIF, it should be in the FFF somewhere too) <-- I'll look for this

2) The are the filter name, part number and serial number. <-- perhaps you could locate these by writing random ASCII strings into the FFF information after the LensSerialNumber?

Here is what I am currently decoding:

> exiftool ../testpics/FLIR/IR_1546.* -flir:all -H -G
======== ../testpics/FLIR/IR_1546.fpf
[FLIR]          0x0028 Image Type                      : Temperature
[FLIR]          0x002a Pixel Format                    : float
[FLIR]          0x002c Image Width                     : 160
[FLIR]          0x002e Image Height                    : 120
[FLIR]          0x0030 Trig Count                      : 0
[FLIR]          0x0034 Frame Count                     : 1
[FLIR]          0x0078 Camera Model                    : FLIR E40
[FLIR]          0x0098 Camera Part Number              : 49001-2001
[FLIR]          0x00b8 Camera Serial Number            : 49033333
[FLIR]          0x00d8 Blackbody Range Min             : -20.0 C
[FLIR]          0x00dc Blackbody Range Max             : 120.0 C
[FLIR]          0x00e0 Lens Model                      : FOL18
[FLIR]          0x0100 Lens Part Number                :
[FLIR]          0x0120 Lens Serial Number              :
[FLIR]          0x0140 Filter Model                    :
[FLIR]          0x0150 Filter Part Number              :
[FLIR]          0x0180 Filter Serial Number            :
[FLIR]          0x01e0 Emissivity                      : 0.95
[FLIR]          0x01e4 Object Distance                 : 1.00 m
[FLIR]          0x01e8 Reflected Apparent Temperature  : 20.0 C
[FLIR]          0x01ec Atmospheric Temperature         : 20.0 C
[FLIR]          0x01f0 Relative Humidity               : 50.0 %
[FLIR]          0x01f4 Computed Atmospheric Trans      : 0.99
[FLIR]          0x01f8 Estimated Atmospheric Trans     : 0.00
[FLIR]          0x01fc Reference Temperature           : 20.0 C
[FLIR]          0x0200 IR Window Temperature           : 20.0 C
[FLIR]          0x0204 IR Window Transmission          : 1.00
[FLIR]          0x0248 Date Time                       : 2013:02:22 11:19:20.891
[FLIR]          0x02a4 Camera Scale Min                : -5.9 C
[FLIR]          0x02a8 Camera Scale Max                : 4.0 C
[FLIR]          0x02ac Calculated Scale Min            : -13.2 C
[FLIR]          0x02b0 Calculated Scale Max            : 6.5 C
[FLIR]          0x02b4 Actual Scale Min                : -5.9 C
[FLIR]          0x02b8 Actual Scale Max                : 4.0 C
======== ../testpics/FLIR/IR_1546.jpg
[MakerNotes]    0x0001 Image Maximum Temperature       : 8
[MakerNotes]    0x0002 Image Minimum Temperature       : -13
[MakerNotes]    0x0003 Emissivity                      : 0.95
[APP1]          0x0001 Raw Thermal Image Width         : 160
[APP1]          0x0002 Raw Thermal Image Height        : 120
[APP1]          0x0010 Raw Thermal Image Type          : TIFF
[APP1]          0x0010 Raw Thermal Image               : (Binary data 38604 bytes, use -b option to extract)
[APP1]          0x0020 Emissivity                      : 0.95
[APP1]          0x0024 Object Distance                 : 1.00 m
[APP1]          0x0028 Reflected Apparent Temperature  : 20.0 C
[APP1]          0x002c Atmospheric Temperature         : 20.0 C
[APP1]          0x0030 IR Window Temperature           : 20.0 C
[APP1]          0x0034 IR Window Transmission          : 1.00
[APP1]          0x003c Relative Humidity               : 50.0 %
[APP1]          0x0090 Blackbody Range Max             : 120.0 C
[APP1]          0x0094 Blackbody Range Min             : -20.0 C
[APP1]          0x00d4 Camera Model                    : FLIR E40
[APP1]          0x00f4 Camera Part Number              : 49001-2001
[APP1]          0x0104 Camera Serial Number            : 49033333
[APP1]          0x0114 Camera Software                 : 20.0.0
[APP1]          0x0170 Lens Model                      : FOL18
[APP1]          0x0190 Lens Part Number                :
[APP1]          0x01a0 Lens Serial Number              :
[APP1]          0x0000 Palette Colors                  : 224
[APP1]          0x0006 Above Color                     : 169 128 128
[APP1]          0x0009 Below Color                     : 49 128 128
[APP1]          0x000c Overflow Color                  : 67 215 98
[APP1]          0x000f Underflow Color                 : 40 109 239
[APP1]          0x0012 Isotherm 1 Color                : 99 128 128
[APP1]          0x0015 Isotherm 2 Color                : 92 115 209
[APP1]          0x001a Palette Method                  : 0
[APP1]          0x001b Palette Stretch                 : 1
[APP1]          0x0050 Palette Name                    : Iron
[APP1]          0x0070 Palette                         : (Binary data 672 bytes, use -b option to extract)
    2 image files read


- Phil

Edit:  I found the date/time stamp: two long integers at offset 0x384 in the CameraInfo.  My only problem is handling the time zone.  For many of my samples this time is different from the EXIF times by an integral number of hours, but for your samples these times are the same.  What time zone are you in?  I'm hoping +00:00.  If so, could you try changing your system timezone and converting IR_1546.jpg again to see if the time stored in the FPF file is GMT or local time?  Thanks.  (I'm on a Mac, so running the ThermaCAM software is difficult for me.)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 12, 2013, 05:04:43 AM
I changed all camera settings to different values and took different photos:
- DST -1
- DST +/- 0
- DST +1
- Picture in  Picture
- Infrared Zoom 2x
then I patched one photo by writing random ASCII strings after the LensSerialNumber

all these pictures I converted to FPF-Format
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 12, 2013, 05:39:46 AM
 
Quote from: Phil Harvey on April 11, 2013, 02:47:39 PM
I'm on a Mac, so running the ThermaCAM software is difficult for me.
on my Mac I work with virtualbox (on old XP-machine and a small Win7x32) for running some nice windows tools (like Hxd HexEditor etc.)

unfortunately the free "Flir Tools for Mac" are not stable, but it works

if you install Silverlight on MAC :-\ then you can start the Flir Online Viewer http://support.flir.com/webviewer
if you type * in the open file dialog box, then you can upload a *.fff file vor viewing and you can save the FFF-file as radiometric jpg  :)
the Flir Online Viewer needs 1Mbit/sec  >:(
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 12, 2013, 06:51:17 AM
I got your files, thanks!  I have only taken a look at the "Name_patched" file so far, but unfortunately your random ASCII strings stopped just before where I expected the filter name to be stored. (After the LensSerialNumber.)

I'll try downloading the FLIR tools for Mac when I'm on a faster internet connection (I'm on dialup right now).

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 12, 2013, 07:27:54 AM
OK, I am now able to decode the time zone from the FFF information (it was located at offset 0x38c in the CameraInfo):

> exiftool ~/Desktop/{fpf,jpg}/*1* -datetimeoriginal -G1
======== /Users/phil/Desktop/fpf/Ir_2517_dst-1.fpf
[FLIR]          Date/Time Original              : 2013:04:12 09:24:01.131
======== /Users/phil/Desktop/fpf/Ir_2519_dst+0.fpf
[FLIR]          Date/Time Original              : 2013:04:12 09:24:44.292
======== /Users/phil/Desktop/fpf/Ir_2521_dst+1.fpf
[FLIR]          Date/Time Original              : 2013:04:12 09:25:14.279
======== /Users/phil/Desktop/jpg/IR_2517_DST-1.jpg
[ExifIFD]       Date/Time Original              : 2013:04:12 09:24:01
[FLIR]          Date/Time Original              : 2013:04:12 09:24:01.131-01:00
======== /Users/phil/Desktop/jpg/IR_2519_DST+0.jpg
[ExifIFD]       Date/Time Original              : 2013:04:12 09:24:44
[FLIR]          Date/Time Original              : 2013:04:12 09:24:44.292+00:00
======== /Users/phil/Desktop/jpg/IR_2521_DST+1.jpg
[ExifIFD]       Date/Time Original              : 2013:04:12 09:25:14
[FLIR]          Date/Time Original              : 2013:04:12 09:25:14.279+01:00
    6 image files read


And the times in all of my samples are now consistent.  Thanks!

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 12, 2013, 07:33:19 AM
you are a hard tag hunter

I repatched the jpg and converted it to fpf
Also two screenshots from Flir Tools with the Name of lens_filter and objectiv

I don't think anyone on this planet reaches this point :-)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 12, 2013, 07:55:24 AM
GOT IT!  Thanks!  I can now decode the filter strings too! :)

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 12, 2013, 12:53:25 PM
I haven't had any luck with the FLIR software.  I have FLIR Tools v1.01 installed on my Mac, and had already downloaded FLIR ResearchIR v3.4 so I installed it on my old PC (the installation took over an hour!), but in neither software can I find any options to save FPF-format images.  Are you saying that the FLIR Tools should be able to write FPF images?  I can't find this option anywhere.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 12, 2013, 01:22:35 PM
sorry for your lost time

Quote from: tomas123 on April 11, 2013, 12:52:43 PM
I loaded my file IR_1546.jpg from B40 to ThermaCAM Researcher Pro 2.10 (trial) and saved it without some manipulation as Ir_1546.fpf

you found the old document Thermacam Researcher 2001 with defination of old flir fild format fpf.

So I installed the Thermacam Researcher and found there the function to save jpg as fpf.
http://www.flir.com/cs/emea/en/view/?id=42404

The flir fpf is a exotic old file format. It's not worth to write some code for it. It's a good Rosetta Stone.
We should focus on the flir radiometric jpg. There are thousands of cams and user.

With Flir Tools you can play around the nice color palettes  ;) and read Flir fff-Files (rename to jpg as workaround).

The  Thermacam Resarcher  is not the FLIR ResearchIR...
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 12, 2013, 01:44:53 PM
Thanks for explaining.  I'll download the old Thermacam software when I can get on a faster connection.  I just wanted to run the software to see if I could locate the only 2 pieces of information from the FPF that we aren't yet decoding from the FFF:  The external trigger count, and the frame sequence count.

I have already added support for FPF files just because it was the easiest way for me to compare the samples you sent, so I might as well leave this in the official release (which I was hoping to release tomorrow).

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 12, 2013, 02:25:31 PM
it may be that external trigger count and the frame sequence count never coded in radiometric jpg

Flir has a special file formats for picture sequence of radiometric pictures ( *.seq)
This is a movie stream as sequence of blocks.
Every block start with a regular FFF header and contains four(!) raw 16 bit pictures in a single Tag 0x0001.
Here make  frame sequence count sense.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 14, 2013, 07:27:04 AM
only for informationen

as attachment a short movie stream of 14 frames with 30 frames/sec (0,467 sec) in flir stream format *.seq

the best thing - exiftool read this format:
$ exiftool -ver
9.26
$ exiftool Flir_Movie.seq -flir:all -H -G
[APP1]          0x0001 Raw Thermal Image Width         : 320
[APP1]          0x0002 Raw Thermal Image Height        : 240
[APP1]          0x0010 Raw Thermal Image Type          : TIFF
[APP1]          0x0010 Raw Thermal Image               : (Binary data 153804 bytes, use -b option to extract)
[APP1]          0x0020 Emissivity                      : 0.95
[APP1]          0x0024 Object Distance                 : 2.00 m
[APP1]          0x0028 Reflected Apparent Temperature  : 20.0 C
[APP1]          0x002c Atmospheric Temperature         : 15.0 C
[APP1]          0x0030 IR Window Temperature           : 19.0 C
[APP1]          0x0034 IR Window Transmission          : 1.00
[APP1]          0x003c Relative Humidity               : 50.0 %
[APP1]          0x0090 Camera Temperature Range Max    : 120.0 C
[APP1]          0x0094 Camera Temperature Range Min    : -20.0 C
[APP1]          0x00d4 Camera Model                    : FLIR E40
[APP1]          0x00f4 Camera Part Number              : 49001-2001
[APP1]          0x0104 Camera Serial Number            : 49033333
[APP1]          0x0114 Camera Software                 : 20.0.0
[APP1]          0x0170 Lens Model                      : FOL18
[APP1]          0x0190 Lens Part Number                :
[APP1]          0x01a0 Lens Serial Number              :
[APP1]          0x01ec Filter Model                    :
[APP1]          0x01fc Filter Part Number              :
[APP1]          0x021c Filter Serial Number            :
[APP1]          0x0384 Date/Time Original              : 2013:04:14 12:55:57.433+01:00
[APP1]          0x0000 Palette Colors                  : 224
[APP1]          0x0006 Above Color                     : 16 128 128
[APP1]          0x0009 Below Color                     : 16 128 128
[APP1]          0x000c Overflow Color                  : 16 128 128
[APP1]          0x000f Underflow Color                 : 16 128 128
[APP1]          0x0012 Isotherm 1 Color                : 16 128 128
[APP1]          0x0015 Isotherm 2 Color                : 16 128 128
[APP1]          0x001a Palette Method                  : 0
[APP1]          0x001b Palette Stretch                 : 1
[APP1]          0x0050 Palette Name                    : Gray
[APP1]          0x0070 Palette                         : (Binary data 672 bytes, use -b option to extract)


I saved with Flir Tools+ a single frames from movie in radiometric jpg format, but I can't found a frame sequence counter...
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 14, 2013, 09:27:32 AM
Hi Tomas,

Thanks.  I'll take a look at this tomorrow when I'm on a faster internet connection.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 14, 2013, 10:47:26 AM
Quote from: tomas123 on April 12, 2013, 02:25:31 PM
Every block start with a regular FFF header and contains four(!) raw 16 bit pictures in a single Tag 0x0001.
this is wrong, *seq is a following sequence of normal *.fff files
Flir  scaled up my sensor size from 160x120 to 320x240 in movie sequence (quadruple size)

$ exiftool Flir_Movie.seq
ExifTool Version Number         : 9.26
Raw Thermal Image Width         : 320
Raw Thermal Image Height        : 240
Raw Thermal Image Type          : TIFF
Raw Thermal Image               : (Binary data 153804 bytes, use -b option to extract)

$ exiftool Flir_Movie.seq -b -RawThermalImage > seq.tif

$ identify seq.tif
seq.tif TIFF 320x240 320x240+0+0 16-bit Grayscale DirectClass 154KB 0.000u 0:00.000

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 14, 2013, 01:25:43 PM
*snif*  I'm heartbroken that you used identify instead of ExifTool:

exiftool Flir_Movie.seq -b -RawThermalImage | exiftool -

;)

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 18, 2013, 05:23:46 PM
sorry for my ignorance and delayed feedback

Quote from: Phil Harvey on April 07, 2013, 04:00:45 PM
You say that only FLIR software can calculate the temperatures, isn't the formula given in "the measurement formula" reference you gave?
I worked hard on decoding the Flir variables for calculating pixel temperature

here is a explanation of Flir Raw value (Page 8)
http://www.workswell.cz/manuals/flir/hardware/A3xx_and_A6xx_models/AXXX_Control_Image_Interfaces.pdf
"RAW"=16 bit un-compressed IR image linear in signal with ancillary calibration data

I found a nice hint in this Flir documents:
http://flir.custhelp.com/ci/fattach/get/1667/
on page 2 they say, that the response of "A/D Counts" are linear to Radiance with a offset.

The Radiance formula you find in Planck's Law
http://en.wikipedia.org/wiki/Planck%27s_law

e^(h*c/(k*λ*T)−1 = (2*h*c^2/λ^5)/I
Planck's Constant h = 6.626068x10-34 joule sec 
Boltzman's Constant k =1.38066x10-23 joule deg-1
Speed of light in vacuum c =2.997925x10+8 m/s
T = object temperature in Kelvins
λ = wavelength in m
I = radiance in Joules/m^3/sec/steradian
e Euler Number

solve it to Temperature formula
T= B / ln(R/I +1)
with ln => Natural logarithm
by substitute with
R = 2*h*c^2/λ^5 
B = h*c/(k*λ)

as explained above is Radiance "I" linear to  Flir A/D Counts "S"
we can write
I = R2*(S+O)
with
S = 16 Bit A/D Counts
R2 = constant factor
O = offset

and with R = R1/R2
T= B / ln(R/I +1)
goes to
T = B / ln(R1/(R2(S+O))+1)

on page 14 in this FLIR document, I found a confirmation for this formulation:
Quotehttp://www.workswell.cz/manuals/flir/hardware/Ax5_models/ICD_GenICam_ICD_FLIR_Ax5_Camera_PC.pdf
Temperature (in Kelvin) = B / log(R / (S - O) + F)
S is the 14-bit digital signal value.
log(x) is the base-e logarithm of the x parameter.
R Planck R constant
B Value range 1300 - 1600.
F Value range 0.5 - 2
O (offset) constant

please note, that Flir replaced the constant 1 in Planck's Law with F (range 0.5 - 2)

now lets find this values in Flir FFF-sequence
here are the offsets (LensFieldOfViewDegree is bycatch)

exiftool FLIR.pm
# FLIR camera record (ref PH)
%Image::ExifTool::FLIR::CameraInfo = (
...
    0x58 => { Name => 'PlanckR1',     Format => 'float', PrintConv => 'sprintf("%f",$val)' },
    0x5C => { Name => 'PlanckB',     Format => 'float', PrintConv => 'sprintf("%f",$val)' },
    0x60 => { Name => 'PlanckF',     Format => 'float', PrintConv => 'sprintf("%f",$val)' },
    0x1b4 => { Name => 'LensFieldOfViewDegree',     Format => 'float', PrintConv => 'sprintf("%.1f",$val)' },
    0x308 => { Name => 'PlanckO',     Format => 'int16s', PrintConv => 'sprintf("%i",$val)' },
    0x30C => { Name => 'PlanckR2',     Format => 'float', PrintConv => 'sprintf("%.8f",$val)' },

please note Offset is a signed word and Flir substituted R = R1/R2

with this Exiftool patch I get:
$exiftool -flir:all IR_2530.jpg | grep Planck
Planck R1                       : 16030.829102
Planck B                        : 1406.699951
Planck F                        : 1.250000
Planck O                        : -7800
Planck R2                       : 0.09530587



Now we must consider the Emissivity with "Reflected Apparent Temperature"
here comes FLIR with the "the measurement formula" into play

S_obj = Radiance of object
S_refl = Radiance of reflected objects
S_mes = measured Radiance (total radiance)
Em = Emissivity of object

S_mes = Em*S_obj + (1-Em)*S_refl
can be written as
S_obj = (S_mes - (1-Em)*S_refl)/Em
and
T_obj = B/ln(R1/(R2(S_obj+O))+1)
thats all

I ignore the Emission of atmosphera. The influence is low by short distance. The calculation effort is high (distance, humidity).
Our calculated temperature is 100% identical with Flir temperature if you set the object distance to zero and let external optics transmission by 1.0!!

for testing I wrote a short shell script raw2tmp.sh

#!/bin/bash
echo "usage $0 flir.jpg PixelArea"
echo "see imagemagick crop for PixelArea, sample 1x1+0+0"

# get Flir values
Flir=$(exiftool -Flir:all "$1")
Type=$(echo "$Flir" | grep "Raw Thermal Image Type" | cut -d: -f2)
if [ "$Type" != " TIFF" ]
    then
        echo "only for RawThermalImage=TIFF"
        exit 1
fi

R1=$(echo "$Flir" | grep "Planck R1" | cut -d: -f2)
R2=$(echo "$Flir" | grep "Planck R2" | cut -d: -f2)
B=$(echo "$Flir" | grep "Planck B" | cut -d: -f2)
O=$(echo "$Flir" | grep "Planck O" | cut -d: -f2)
F=$(echo "$Flir" | grep "Planck F" | cut -d: -f2)

# get RAW Sensor value
RAW=$(exiftool -b -RawThermalImage "$1" 2>/dev/zero | convert - -crop $2 -colorspace gray -format "%[mean]" info: )

# calc spectral range of used Flir camera
echo -n "spectral range [micrometer]: "
echo "scale=2;14387.6515/$B"| bc -l

# calc Temperature of PixelArea with Emissivity = 1.0
degree=$(echo "scale = 8;$B/l($R1/($R2*($RAW+$O))+$F)-273.15" | bc -l )
echo "$RAW RAW => $degree degree Celsius at Emissivity=1.0"

# calc Temperature of PixelArea with saved Emissivity
Emissivity=$(echo "$Flir" | grep "Emissivity" | cut -d: -f2)
Refl_Temp=$(echo "$Flir" | grep "Reflected Apparent Temperature" | sed 's/[^0-9.-]*//g')

RAWrefl=$(echo "scale = 8;$R1/($R2*(e($B/($Refl_Temp+273.15))-$F))-$O" | bc -l )
RAWobj=$(echo "scale = 8;($RAW-(1-$Emissivity)*$RAWrefl)/$Emissivity" | bc -l )
echo $Emissivity $Refl_Temp $RAW $RAWrefl $RAWobj
degree=$(echo "scale = 8;$B/l($R1/($R2*($RAWobj+$O))+$F)-273.15" | bc -l )
echo "$RAWobj RAW => $degree °C at Emissivity=$Emissivity and $Refl_Temp °C reflected temp."


usage ./raw2tmp.sh flir.jpg PixelArea
see imagemagick crop for PixelArea, sample 1x1+0+0

here a sample with a area of 1x1 Pixel and the first pixel on top right (x,y => 0,0)
$ ./raw2tmp.sh IR_1546.jpg  1x1+0+0
spectral range [micrometer]: 10.30
12626 RAW => -9.51770751 degree Celsius at Emissivity=1.0
12373.04334215 RAW => -11.39208744 °C at Emissivity= 0.95 and 20.0 °C reflected temp.


With this values I also calculated the spectral range of camera
it's simple
B = h*c/(k*λ) goes to
λ[μm]=14387.6515/Planck_B
There are two sort of cams on market SW and LW cameras.
see Short Wave and Long Wave
http://en.wikipedia.org/wiki/Infrared

sample of spectral range with Flir E40:
calculated from Exif: 10.30 μm (Peak)
datasheet: 7.5–13 μm (Range)




script works only for Tiff Images
if you use "Raw Thermal Image Type"=PNG you must change upper/lower byte
$ convert cat1.png gray:- | convert -depth 16 -endian msb -size 120x120 gray:- -auto-level cat2.png


PH Edit: Fixed typo in a formula
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 18, 2013, 05:59:22 PM
here a sample for the quality of approximation

use shell script from previous post

here are the first 6 Pixel of first line with Emissivity = 0.7
$ for i in $(seq 0 5); do ./raw2tmp.sh IR_2521_em_0.7.jpg  1x1+$i+0 | grep reflected; done
17169.92339290 RAW => 18.60727574 °C at Emissivity= 0.70 and 30.0 °C reflected temp.
17187.06625004 RAW => 18.69889653 °C at Emissivity= 0.70 and 30.0 °C reflected temp.
17207.06625004 RAW => 18.80568329 °C at Emissivity= 0.70 and 30.0 °C reflected temp.
17195.63767861 RAW => 18.74467600 °C at Emissivity= 0.70 and 30.0 °C reflected temp.
17199.92339290 RAW => 18.76755800 °C at Emissivity= 0.70 and 30.0 °C reflected temp.
17187.06625004 RAW => 18.69889653 °C at Emissivity= 0.70 and 30.0 °C reflected temp.


as attachment the exported temperature csv matrix from Flir Tools
$ head -n 1 IR_2521_em_0.7.csv | tr ";" "\n" | head -n 6
18,607
18,699
18,806
18,745
18,768
18,699







and the first 6 Pixel of same picture with Emissivity=1.0

$ for i in $(seq 0 5); do ./raw2tmp.sh IR_2521_em_1.0.jpg  1x1+$i+0 | grep reflected; done
17845.00000000 RAW => 22.15501195 °C at Emissivity= 1.00 and 21.0 °C reflected temp.
17857.00000000 RAW => 22.21699384 °C at Emissivity= 1.00 and 21.0 °C reflected temp.
17871.00000000 RAW => 22.28925951 °C at Emissivity= 1.00 and 21.0 °C reflected temp.
17863.00000000 RAW => 22.24797078 °C at Emissivity= 1.00 and 21.0 °C reflected temp.
17866.00000000 RAW => 22.26345606 °C at Emissivity= 1.00 and 21.0 °C reflected temp.
17857.00000000 RAW => 22.21699384 °C at Emissivity= 1.00 and 21.0 °C reflected temp.


and the temperature csv matrix from Flir Tools
$ head -n 1 IR_2521_em_1.0.csv | tr ";" "\n" | head -n 6
22,155
22,217
22,289
22,248
22,263
22,217


you can see, its identical  :)
I was too lazy to use printf in shell script
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 18, 2013, 06:25:05 PM
Thank you very much for sharing your hard work here!  I'm sure this will be extremely useful to anyone else who wants to use the FLIR raw image data.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 18, 2013, 06:47:09 PM
I don't need the Raw temperature values for my work.
I only use the possibility to make nice panoramas from raw images...

After you've found so many FLIR tags I also wanted to be a cool tag hunter  8)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 18, 2013, 07:42:01 PM
Well, you certainly are a very cool tag hunter!!  I'll add your new tags, but I want to think about this for a while and study your notes before I decide on final names for them.  These were certainly too involved for me to decode by myself.  Thanks again for all your work on this!

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 19, 2013, 07:39:23 AM
Quote from: Phil Harvey on April 18, 2013, 07:42:01 PM
but I want to think about this for a while and study your notes before I decide on final names for them

I also thought hard about names.
I found two FLIR documents for the FLIR AX5 camera with register names for Planck's Law

Page 14 Measurement registers
http://www.workswell.cz/manuals/flir/hardware/Ax5_models/ICD_GenICam_ICD_FLIR_Ax5_Camera_PC.pdf
QuoteTemperature (in Kelvin) = B / log(R / (S - O) + F), where

S is the 14-bit digital signal
value.
log(x) is the base-e logarithm of the x parameter.
R   Integer   RW   Gets and sets the Planck R constant. This
value is used when converting from signal value to temperature.
B   Float   RW   Gets or sets Planck B constant. This value is
used when converting from signal value to temperature. Value range 1300 - 1600.
F   Float   RW   Gets or sets Planck F constant. This value is
used when converting from signal value to temperature. Value range 0.5 - 2.
O   Float   RW   Gets and sets Planck O (offset) constant. This
value is used when converting from signal value to temperature.

and Page 3
http://www.workswell.cz/manuals/flir/hardware/Ax5_models/Notice_to_customer_FLIR_Ax5%20I_O_synchronization_and_measurement.pdf
QuoteThe FLIR AX5 camera provides registers that can be used to convert object signal values to temperature.

For each measurement range (or gain mode) there is a set of register values that is used for this conversion.
Register name Type
R Integer
B Float
F Float
O Float
Please note that these registers will be automatically updated when switching between high gain mode and low gain mode.
The formula for calculating temperature is:
T (in Kelvin) = B / log(R/(S – O) + F)

In Flir FFF Format the register R is segemted in two registers.
I named they with  R1 and R2, because R1/R2= Flir_Register_R

The FOV "Field Of View" is the name in every Flir camera datasheet. There you find also the name "Spectral range"

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 19, 2013, 07:53:21 AM
Thanks for the explanation.  Your Planck names make sense now, and I'm leaning towards FieldOfView for the other tag.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 19, 2013, 11:40:50 AM
Quote from: Phil Harvey on April 18, 2013, 07:42:01 PM
but I want to think about this for a while and study your notes
for better reading a short summary of this post
https://exiftool.org/forum/index.php/topic,4898.msg23944.html#msg23944
without the physical part




Variant A: Emissivity of object = 1,0

boundary condition:
     object distance = 0
     external optics transmission = 1.0

T = B / ln(R1/(R2*(S+O))+F)

T = object temperature in Kelvins
S = 16 Bit RAW value
R1 Planck R1 constant
R2     Planck R2 constant
B    Planck B constant. Value range 1300 - 1600.
F     Planck F constant. Value range 0.5 - 2.
O    Planck O (offset) constant. Its a negative value.

ln() natural logarithm



Variant B: Emissivity of object < 1,0

boundary condition:
    object distance = 0
    external optics transmission = 1.0

now me must calculate the amount of radiance from reflected objects
for that, we need two auxiliary calculation

RAW_refl=R1/(R2*(e^(B/T_refl)-F))-O
T_refl = reflected temperature in Kelvins
RAW_refl is linear to amount of radiance of the reflected objects
e  Euler's number

RAW_obj=(S-(1-Emissivity)*RAW_refl)/Emissivity
RAW_obj is linear to amount of radiance of the measured object
  Emissivity = Emissivity of object
  S = 16 Bit FLIR RAW value

now we use the formula from variant A and replace the 16-Bit-Image-Value "S" with the calculated RAW_obj
T_obj= B / ln(R1/(R2*(RAW_obj+O))+F)
  T_obj = object temperature in Kelvins
  R1 Planck R1 constant
  R2     Planck R2 constant
  B    Planck B constant. Value range 1300 - 1600.
  F     Planck F constant. Value range 0.5 - 2.
  O    Planck O (offset) constant. Its a negative value.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 19, 2013, 11:44:26 AM
Great, thanks.  And I'll reference this post from the ExifTool FLIR CameraInfo tags documentation.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 20, 2013, 08:58:25 AM
I'm looking in your pre release Image-ExifTool-9.28p.tar.gz

you can't unfortunately print a tag twice in different formats ("Planck B" and  "spectral range" of camera )
a suggest as oneliner for Flir.pm
Line 252:     0x5C => { Name => 'PlanckB',  Format => 'float', PrintConv => 'sprintf("%.8g [%.1f µm]",$val,14387.6515/$val)' }, #1

Output
Planck B                        : 1395.7 [10.3 µm]

more accurate: Wavelength by max infrared sensitivity
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 20, 2013, 09:43:43 AM
Thanks for this suggestion.

Perhaps a separate Composite tag named SpectralRange would be better?:

======== ../testpics/FLIR/Cat.jpg
Planck B                        : 1375
Spectral Range                  : 10.5 um


... or may be "CameraSpectralRange"?

(note that I use a "u" instead of "µ" to avoid complications due to the special character sets.)

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 20, 2013, 09:58:01 AM
range for a single value is not a good description
let's use "sensor wavelength"
http://en.wikipedia.org/wiki/Infrared
or
"thermal wavelength"

All Flir "Thermal" Image Cameras with the capability to save a radiometric jpg are specified for a spectral range 7.5 to 13 μm.
But the internal calibrated value for calculating the temperature with Planck's Law is this single wavelength.
The saved values for Planck R1, R2, B, F, O are for every camera fixed values (for a preset temp range).
These values are a fingerprint and changed only after a calibration from FLIR service.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 20, 2013, 11:11:15 AM
This makes sense, thanks.  Or how about CalibratedWavelength?

- Phil

Edit: ... or perhaps PeakSpectralSensitivity?
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 20, 2013, 08:09:02 PM
PeakSpectralSensitivity is nice

I was looking for a way with all the included tags to create a new image with the same temperature range as the original FLIR image.
For this we need additional information about the temperature scale in Flir.jpg

I found the necessary  informationen in this two new tags:
   
# FLIR camera record (ref PH)
%Image::ExifTool::FLIR::CameraInfo = (
...
    0x338 => { Name => 'RAW_center',     Format => 'int16u', PrintConv => 'sprintf("%i",$val)' },
    0x33c => { Name => 'RAW_max-min',     Format => 'int16u', PrintConv => 'sprintf("%i",$val)' },

it's crazy, but Flir save the median [=(max+min)/2] 16-bit-AD-range of the calculated jpg-image and the (16 Bit) difference between max/min

With this two tags I wrote this short shell script, which calculates a new jpg only from Flir tags and embedded binary palette and RAW values. Only with exiftool and convert.

The function between 16-Bit-RAW to temperature is not linear. Therefore I used the imagemagick convert fx operator for calculating every pixel with Plancks Law and therefore with the natural logarithm  (fx is a great feature).

flir2jpg.sh
#!/bin/bash
echo "usage $0 flirSource.jpg Destination.jpg"

# test for Tiff or PNG
Flir=$(exiftool -Flir:all "$1")
Type=$(echo "$Flir" | grep "Raw Thermal Image Type" | cut -d: -f2)
if [ "$Type" != " TIFF" ]
    then
        echo "only for RawThermalImage=TIFF"
        exit 1
fi

# extract color table and expand [16,235] video pal color table
PalCol=$(exiftool -flir:all $1 | grep "Palette Colors" | cut -d: -f2)
exiftool $1 -b -Palette | convert -size ${PalCol}X1 -depth 8 YCbCr:- -separate -swap 1,2 -set colorspace YCbCr -combine -colorspace RGB -auto-level Palette.png

# get Flir values for Plancks Law
R1=$(echo "$Flir" | grep "Planck R1" | cut -d: -f2)
R2=$(echo "$Flir" | grep "Planck R2" | cut -d: -f2)
B=$(echo "$Flir" | grep "Planck B" | cut -d: -f2)
O=$(echo "$Flir" | grep "Planck O" | cut -d: -f2)
F=$(echo "$Flir" | grep "Planck F" | cut -d: -f2)

# echo $R1 $R2 $B $O $F

# get refl temp
Temp_refl=$(echo "$Flir" | grep "Reflected Apparent Temperature" | sed 's/[^0-9.-]*//g')
Emissivity=$(echo "$Flir" | grep "Emissivity" | cut -d: -f2)

RAWmedium=$(echo "$Flir" | grep "Raw Value Median" | cut -d: -f2)
RAWdelta=$(echo "$Flir" | grep "Raw Value Range" | cut -d: -f2)

RAWmax=$(echo "scale = 8;$RAWmedium+$RAWdelta/2" | bc -l )
RAWmin=$(echo "scale = 8;$RAWmedium-$RAWdelta/2" | bc -l )

# echo "RAW-Range: $RAWmin $RAWmax"

# calc Temperature Range of measured object with Emissivity < 1
RAWrefl=$(echo "scale = 8;$R1/($R2*(e($B/($Temp_refl+273.15))-$F))-$O" | bc -l )
RAWmaxobj=$(echo "scale = 8;($RAWmax-(1-$Emissivity)*$RAWrefl)/$Emissivity" | bc -l )
RAWminobj=$(echo "scale = 8;($RAWmin-(1-$Emissivity)*$RAWrefl)/$Emissivity" | bc -l )

Temp_max=$(echo "scale = 8;$B/l($R1/($R2*($RAWmaxobj+$O))+$F)-273.15" | bc -l )
Temp_min=$(echo "scale = 8;$B/l($R1/($R2*($RAWminobj+$O))+$F)-273.15" | bc -l )

# convert to "%.1f" for printing
LC_NUMERIC="en_US.UTF-8"
Temp_min=$(printf "%.1f" $Temp_min)
Temp_max=$(printf "%.1f" $Temp_max)

# draw temp scale
convert -size 20x256 gradient: Palette.png -clut -mattecolor white -frame 5x5 gradient.png
convert gradient.png -background white -font ArialB -pointsize 15 label:"$Temp_max °C" +swap -gravity Center -append  label:"$Temp_min" -append gradient.png

# convert every RAW-16-Bit Pixel with Planck's Law to a Temperature Grayscale value and append temp scale
Smax=$(echo "scale = 8;$B/l($R1/($R2*($RAWmax+$O))+$F)" | bc -l )
Smin=$(echo "scale = 8;$B/l($R1/($R2*($RAWmin+$O))+$F)" | bc -l )
Sdelta=$(echo "scale = 8;$Smax-$Smin" | bc -l )
exiftool -b -RawThermalImage $1 | convert - -fx "($B/ln($R1/($R2*(65535*u+$O))+$F)-$Smin)/$Sdelta" -resize 200\% Palette.png -clut -background white -flatten +matte gradient.png -gravity East +append $2

echo "wrote $2 with Temp-Range: $Temp_min / $Temp_max"


sample
./flir2jpg.sh IR_1546-rainbow.jpg flir2jpg-rainbow.jpg
You can compare the original image from attachment with this result from script - look at the same temperature range
... in the scale outside of the image;-)





some hints for interested readers:
- see my post here for a collection of nice palettes with fullrange level (0-255) instead of ugly embedded palalettes (16-235)
https://exiftool.org/forum/index.php/topic,4898.msg23763.html#msg23763

- you need the 16 Bit Version of Imagemagick
$ convert -version
Version: ImageMagick 6.7.8-8 2012-08-09 Q16 http://www.imagemagick.org

- convert need the freetype library for writing fonts
$ convert -list configure | grep DELEG
DELEGATES     bzlib freetype jpeg jng jp2 lcms png tiff x11 xml zlib

- with freetype library you get this error: "convert: unable to read font "
-> see http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=20529
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 20, 2013, 09:01:38 PM
where JD) found the names for this tags and what they mean?
Palette Method                  : 0
Palette Stretch                 : 3

I have some different displays of the iron palette and I think, it's a adjusted gamma value.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 20, 2013, 09:35:43 PM
PeakSpectralSensitivity it is then.

And wow, two more tags!  Cool!  8)

I think I'd like to call them RawValueMedian and RawValueRange.

I don't have any more details about the meaning of the Palette tags decoded by Jens Duttke.  He decoded these a while ago and hasn't been actively working on this recently.

I spent a bit of time trying to understand your script.  Very impressive.  You are certainly a power programmer when it comes to shell scripting.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 20, 2013, 09:48:05 PM
ok, thats fine

I edited the script above, before the server tomorrow closed the post for editing
RAWmedium=$(echo "$Flir" | grep "Raw Value Median" | cut -d: -f2)
RAWdelta=$(echo "$Flir" | grep "Raw Value Range" | cut -d: -f2)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 20, 2013, 09:49:56 PM
shell scripting is kids scripting compared to regex and perl ( http://en.wikipedia.org/wiki/Obfuscated_Perl_Contest )

convert is the swiss knife  :)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 21, 2013, 06:37:40 AM
Quote from: tomas123 on April 20, 2013, 09:49:56 PM
shell scripting is kids scripting compared to regex and perl

Funny.  I was thinking how much simpler your script would be if it was written in Perl. :)  (But one big reason for this is that you could call the API directly and avoid all of the "cut"-ing for each tag.)

- Phil

Edit: I sent and e-mail to Jens to ask about the Palette tags.  Looking back at the information he gave me, it seems as if he may have decoded these by reverse-engineering with the KLIRViewer iPad App.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 21, 2013, 01:13:57 PM
I downloaded the new version 9.28 and all works fine.

Question:
(1) How do you delete the images inside the jpg in your Meta Information Repository
( https://exiftool.org/sample_images.html )
I know, how to write thumbnails: $ exiftool 1.jpg '-ThumbnailImage<=thumb.jpg'

(2) I furthermore work at panorama radiometric images.
Could you imagine to enable write access for a complete FFF-File?
The advantage is the possibility to use FLIR Software for settings measuring point etc. in panorama.

I can create a FFF Header for a 16Bit-Tiff-Panorama self,  its simple.
Flir Software needs only the two tags for working (0x0001 RawData and 0x0020 CameraInfo)
Exiftool must "only" extend the  EXIF APP1 frame and fragment the file in 64KByte-Parts...
I tested it painful with a hexeditor - there is no recalculation of addresses required...



Thanks for your great work and have a great holiday!
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on May 06, 2013, 04:21:17 AM
Hallo Phil,

I hope, you are full recovered back from holiday  :)

You have not answered to my last post  :(

In the meantime I worked on Flir-PiP (Picture in Picture) Images
You find some nice samples here:

Flir B60: http://commons.wikimedia.org/wiki/File:Aqua_Tower_thermal_image.jpg
Flir E40: https://exiftool.org/forum/index.php/topic,4898.msg23838.html#msg23838
extract IR_2523_PiP.jpg from my attachment https://exiftool.org/forum/index.php?PHPSESSID=t6r4dh04hnsdhk4vj1h4ag6ku2&action=dlattach;topic=4898.0;attach=606
Flir T640 http://www.flickr.com/photos/prusajr/6945941592/sizes/o/in/photostream/ (large!)



You can decode some more tags with the config file config.txt from attachment

But there is a bug inside my config file.
I can't decode the reverse byte Order for first tag (float) Real2IR
Quoteexiftool.exe -config config.txt -flir:all Aqua_Tower_thermal_image.jpg -v3 | grep -B1 -A11 "Tag 0x002a"
| PIP (SubDirectory) -->
| - Tag 0x002a (64 bytes):
|    52008: f4 ff db 3f 02 00 f6 ff 24 00 8e 00 24 00 8e 00 [...?....$...$...]
|    52018: 35 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 [5...............]
|    52028: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
|    52038: 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 [................]
| + [BinaryData directory, 64 bytes]
| | Real2IR = -1.62168278564919e+032
| | - Tag 0x0000 (4 bytes, float[1]):
| |    52008: f4 ff db 3f                                     [...?]
| | OffsetX = 2
| | - Tag 0x0004 (2 bytes, int16s[1]):
| |    5200c: 02 00                                           [..]

correct is f4 ff db 3f -> 1,7187
you know, how to correct this ;-)

--------------------------------------------------

infos to the new tags

$ exiftool.exe -config config.txt -flir:all Aqua_Tower_thermal_image.jpg
...
Embedded Image Width            : 480  //see my sample below
Embedded Image Height           : 480
Embedded Image                  : (Binary data 335334 bytes, use -b option to extract)
Embedded Image Format           : PNG in YCbCr (see sample below)
Real 2 IR                       :  1,7187 (Image Size Relation Real/Radiometric, reverse byte order)
Offset X                        : +2 (X Offset from Center for Insertion Point)
Offset Y                        : -10
Pip X1                          : 36 (crop size position for radiometric image)
Pip X2                          : 142
Pip Y1                          : 36
Pip Y2                          : 142
Focus Distance RAW              : 0  // Flir E40/E50/E60 value proportional to rotation angle of focus ring)
Focus Distance                  : 4.5 m (with focus ring adjusted distance)




SAMPLE
now decode the aqua tower and overlay to a  full size images (ignore Plancks law for better reading)

download http://commons.wikimedia.org/wiki/File:Aqua_Tower_thermal_image.jpg

// extract real image, convert embedded YCbCr-PNG  to RGB
Quote$ exiftool -config config.txt Aqua_Tower_thermal_image.jpg -b -EmbeddedImage | convert -  -set colorspace YCbCr -colorspace RGB Tower.jpg

extract the palette, convert YCrCb-RAW to RGB
Quote$ exiftool Aqua_Tower_thermal_image.jpg -paletteco*
Palette Colors                  : 224
$ exiftool Aqua_Tower_thermal_image.jpg -b -Palette | convert -size 224X1 -depth 8 YCbCr:- -separate -swap 1,2 -set colorspace YCbCr -combine -colorspace RGB palette.png

next step is radiometric image
Quote$ exiftool -config config.txt Aqua_Tower_thermal_image.jpg -rawvalue* -rawtherm*
Raw Value Median                : 13102
Raw Value Range                 : 1995
Raw Thermal Image Width         : 180
Raw Thermal Image Height        : 180
Raw Thermal Image Type          : PNG
Raw Thermal Image               : (Binary data 48946 bytes, use -b option to extract)

calculate level for max/min temperature
// 13102-1995/2=12105
// 13102+1995/2=14100

extract radiometric image and change reverse byte order 16Bit-PNG
Quote
$ exiftool Aqua_Tower_thermal_image.jpg -b -RawThermalImage | convert - gray:- | convert -depth 16 -endian msb -size 180x180 gray:- -level 12105,14100 raw.png

now overlay all three images
Quote$ exiftool -config config.txt Aqua_Tower_thermal_image.jpg -real2ir -RawThermalImageWidth -EmbeddedImageWidth -Offset*
real 2 IR                       : 1,7187 // please correct my config file
Raw Thermal Image Width         : 180
Embedded Image Width            : 480
Offset X                        : +2
Offset Y                        : -10

calculate the resize factor
480/1,7187=279 Pixel horizontal for resized raw image
Quote$ convert raw.png palette.png -clut -resize 279x Tower.jpg +swap -gravity Center -geometry +2-10 -compose over -composite TowerPiP.jpg

you can see, we have now the twice size (quad pixel) as original
(73kByte)

we have some little differences in overlay, the photographer only saw the cropped image on display and the focus (move overlay) is not perfect...





for clarification the last tags, decode the original flir image size and compare with original
Quote$ exiftool -config config.txt Aqua_Tower_thermal_image.jpg -pip* -offset* -real2ir
Pip X1                          : 36
Pip X2                          : 142
Pip Y1                          : 36
Pip Y2                          : 142
Offset X                        : +2
Offset Y                        : -10
Real 2 IR                       : 1,7187

with this tags calculate the radiometric image size
  142-36+1= 107px horizontal
  142-36+1= 107px vertical
calculate the resize factor for radiometric image
480px/180px/1.71= 155%

and now: all-in-one (ImageMagick is great)
convert raw.png -gravity center -crop 107x107+0+0 palette.png -clut -resize 155% Tower.jpg +swap -gravity Center -geometry +2-10 -compose over -composite -crop 270x270+2-10 -resize 240x Aqua_Tower_thermal_image.jpg -gravity East +append compare.jpg


perfect

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on May 06, 2013, 08:16:09 AM
Hi Tomas,

Sorry, I missed this somehow.  I'm still on vacation, but I can answer these questions.

Quote from: tomas123 on April 21, 2013, 01:13:57 PM
Question:
(1) How do you delete the images inside the jpg in your Meta Information Repository
( https://exiftool.org/sample_images.html )
I know, how to write thumbnails: $ exiftool 1.jpg '-ThumbnailImage<=thumb.jpg'

The command to delete the ThumbnailImage is:  exiftool -thumbnailimage= 1.jpg

Quote(2) I furthermore work at panorama radiometric images.
Could you imagine to enable write access for a complete FFF-File?

Adding the ability to write a format is a lot more work than reading.  I don't think the demand for this feature would be great enough to justify this effort.

Thanks for the details about the PiP information.  I'll study this and post back here if I have any questions.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on May 06, 2013, 09:49:27 AM
thanks for your post from vacation and sorry for disturbing you :-[

I know. how to delete thumbnails.
My question is, how do you changed the full size images inside the jpg in your Meta Information Repository with white images 8x8 px.
( https://exiftool.org/sample_images.html )




I have some basic approaches with good old awk for change the size of a existing FFF-Tag (splitted in 64KB-parts) and fill it with an other image.
After tests with an Hex-Editor I think that I can change the size of a single "FF E1" APP1 Flir-FFF-segment without recalculate the adresses from other APP1-segments. There no absolute offsets.
(off course I edited the segment size in the FFE1 header of affected Flir FFF segment)
I'm not sure...  I must read the APP1 marker specification and look for terrible checksums etc.

You changed with some write commands of exiftool also the size of APP1 segments.
It is sufficient to only change the segment size in the APP1 header?
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on May 06, 2013, 10:15:55 AM
Ah.  I have a script I wrote that does this (attached).  It takes the image in t/images/Writer.jpg and uses it to replace the main image in the specified JPEG.  Other changes I do by hand.  From the JPEG point of view, changing the segment size word is sufficient, but depending on the format of the data within the segment some other changes may be necessary.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on May 06, 2013, 10:31:34 AM
thanks for clarification
I will come back, if I have new infos.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on May 14, 2013, 01:19:05 AM
Hi Phil,

I'm writing a script for expanding PiP images.

The definition of tags with a config file "exiftool -config ..." works great, but I can't change the byte order in the first tag with address 0x00.

https://exiftool.org/forum/index.php/topic,4898.msg24156.html#msg24156
%Image::ExifTool::FLIR::PIP = (
    GROUPS => { 0 => 'APP1', 2 => 'Image' },
    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
    FIRST_ENTRY => 0,
    NOTES => q{
        Picture in Picture
    },
     0x00 => {
    # determine the byte order
        RawConv => 'ToggleByteOrder()',
        Name => 'Real2IR',
Format => 'float',
#PrintConv => 'sprintf("%.2f",$val)'
    },


This doesn't work.
RawConv => 'ToggleByteOrder()' change the byte order for the next following tags.
Do you have an idea?

Thanks
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on May 14, 2013, 07:20:52 AM
Hi Tomas,

Thanks for reminding me about this thread now that I'm back again.

Are all of the PiP tags a specific byte order?  If so, you should be able to set the byte order in the SubDirectory definition:

    0x002a => {
        Name => 'PiP',
        SubDirectory => {
            TagTable => 'Image::ExifTool::FLIR::PiP',
            ByteOrder => 'LittleEndian',
        },
    },


Otherwise, you could do this for a single tag:

    0x00 => {
        Name => 'Real2IR',
        Format => 'undef[4]',
        RawConv => 'ToggleByteOrder(); $val = GetFloat(\$val, 0); ToggleByteOrder(); $val',
    },


- Phil

Edit: I have attached an updated FLIR.pm that may do what you want (provided the PiP is always little endian).  BTW, what is the meaning of the Real2IR tag?
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on May 14, 2013, 08:33:44 AM
your FLIR.pm works fine, ByteOrder => 'LittleEndian' was the solution :-)

Real2IR is the proportion between the "Field Of View" of real image to thermal image.
You need the factor for overlay two images with different focal length and pixel resolution.

I described real2IR here:
Quote from: tomas123 on May 06, 2013, 04:21:17 AM

Quote$ exiftool -config config.txt Aqua_Tower_thermal_image.jpg -real2ir -RawThermalImageWidth -EmbeddedImageWidth -Offset*
real 2 IR                       : 1,7187 // please correct my config file
...

calculate the resize factor
480/1,7187=279 Pixel horizontal for resized raw image

Quote$ convert raw.png palette.png -clut -resize 279x Tower.jpg +swap -gravity Center -geometry +2-10 -compose over -composite TowerPiP.jpg

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on May 14, 2013, 08:46:16 AM
don't forget

Focus Distance RAW          : Flir E40/E50/E60 value proportional to rotation angle of focus ring
Focus Distance                  : with focus ring adjusted distance in [m]

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::FLIR::CameraInfo' => {
          0x390 => { Name => 'FocusDistanceRAW', Format => 'int16u', Groups => { 2 => 'Image' } },
          0x45c => { Name => 'FocusDistance', Format => 'float', PrintConv => 'sprintf("%.1f m",$val)' },
     },


you can check "Focus Distance RAW" with this image
https://exiftool.org/forum/index.php?action=dlattach;topic=4898.0;attach=615

here you see the function of "Focus Distance RAW" to Distance [meter] for a FLIR E40
(I read it out with exiftool from hundreds of images)


Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on May 14, 2013, 09:00:08 AM
Hi Tomas,

Thanks!  I missed this.  I think I'll call it FocusStepCount instead of FocusDistanceRAW, since this corresponds to the name used for Olympus cameras.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on May 14, 2013, 09:07:28 AM
FocusStepCount is nice

Focus Distance is also tricky, there are more distance tags

Flir E40
Subject Distance                : 0 m
Object Distance                 : 0.00 m
FocusStepCount                : 2000
Focus Distance                  : 0.5 m


Flir B60
Subject Distance                : 1 m
Object Distance                 : 1.00 m
FocusStepCount              : 0
Focus Distance                  : 4.5 m


mostly SubjectDistance=ObjectDistance,
but a nice sample from your https://exiftool.org/sample_images.html
======== FLIR_ThermaCAM_T-400.jpg
Subject Distance                : 8.01 m
Object Distance                 : 2.44 m
FocusStepCount              : 0
Focus Distance                  : 0.6 m
======== FLIR_ThermaCamP660Wes.jpg
Subject Distance                : 5 m
Object Distance                 : 1.52 m
FocusStepCount              : 0
Focus Distance                  : 5.4 m
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on May 14, 2013, 04:03:02 PM
with the new tags I could finished my new script for extracting flir images

I use php so that windows users do not require some large installation (like perl)
it runs under Mac/Windows/Linux (only edit the path inside the script)

needs:
- Imagemagick convert
- Exiftool  :)

flir.php
#!/usr/bin/php
<?php
//------------- set necessary paramters -------------------------------------

if (strtoupper(substr(PHP_OS03)) === 'WIN') {
    
//WINDOWS user: set path to tools
    
$convert='"C:\Program Files\ImageMagick-6.8.5-Q16\convert.exe"';
    
$exiftool='"C:\Program Files\exiftool\exiftool.exe"';
    
//set font variable as needed (Mac/Win) for color scale
    
$font='-font c:\windows\Fonts\arialbd.ttf';

} else {
    
//Unix/Mac: set path to tools here 
    
$convert='/opt/ImageMagick/bin/convert';
    
$exiftool='/usr/bin/exiftool';
    
//set font variable as needed (Mac/Win) for color scale
    
$font='-font /Library/Fonts/Arial\ Bold.ttf';
}

//color scale
$font_color='white';
$frame_color='black';

//extract embedded palette to
$embpal='palette.png';

//--------------------------------------------------------------------------

$shortopts  "";
$shortopts .= "i:";  // Required value
$shortopts .= "o:";  
$shortopts .= "h";  

$longopts  = array(
    
"resize:",     // Required value
    
"rmin:",     
    
"rmax:",    
    
"pal:",
    
"tref:",
    
"emis:",
    
"pip::",       // opt. value
    
"clut",        // No value
    
"scale",      
    
"help",       
);
$options getopt($shortopts$longopts);
#var_dump($options);

function help()
{
global 
$argv;
echo <<<EOT

usage: 
$argv[0] [options] -i ir_file.jpg -o outputimage

Settings:
-i ir_file.jpg      flir radiometric image
-o output.jpg       save  8 Bit image jpg
-o output.png       save 16 Bit image png

Options Summary:
--resize val        scale sensor size with "convert -resize val" (val i.e. 600x or 100%, default is 200%)
--tref temp         overwrite embedded Reflected Apparent Temperature (degree Celsius) 
--emis val          overwrite embedded Emissivity (val i.e. 0.95)
--rmin raw_min      set min RAW value instead embedded value (set scale min temp)
--rmax raw_ma       set max RAW value instead embedded value (set scale max temp)
--pal iron.png      use own palette (instead of embedded palette.png)
--clut              disable "Color LookUp Table" and color scale (save a grayscale image)
--scale             disable color scale on the right edge
--pip[=AxB]         input image is a flir PiP radiometric image
                    overlay embedded "real image" with "ir image"
                    [optional] crop ir image to size AxB (i.e. --pip=90x90 )
--help              print this help
  
# source: 
# [1] https://exiftool.org/forum/index.php/topic,4898.0.html

EOT;
}

if (isset(
$options['help']) || isset($options['h']))
{
 
help();
};

if (isset(
$options['i']))
{
    
$flirimg="\"".$options['i']."\"";
    if (isset(
$options['o']))
    {
        
$destimg="\"".$options['o']."\"";    
    } else {
      print 
'Error: No output file specified! "-o filename"'."\n";
      exit(
1);
    }
} else {     
    
help();
    exit(
1);
};

if (isset(
$options['pal']))
{
    
$pal="\"".$options['pal']."\"";  
} else {
    
$pal=$embpal;
}

if (isset(
$options['resize']))
{
    
$resize='-resize '.$options['resize'];    
} else {
    
// default
    
$resize="-resize 200%";
}

//get Exif values (syntax for Unix and Windows)
eval('$exif='.shell_exec($exiftool.' -php -flir:all -q '.$flirimg));
//var_dump($exif);

if (isset($options['tref']))
{
    
$Temp_ref=$options['tref'];  
} else {
    
$tmp=explode(" ",$exif[0]['ReflectedApparentTemperature']);
    
$Temp_ref $tmp[0];
}
if (isset(
$options['emis']))
{
    
$Emissivity=$options['emis'];  
} else {
    
$Emissivity=$exif[0]['Emissivity'];
}
print(
"\nReflected Apparent Temperature: ".$Temp_ref." degree Celsius\nEmissivity: ".$Emissivity."\n");

// save Flir values for Plancks Law for better reading in short variables
$R1=$exif[0]['PlanckR1'];
$R2=$exif[0]['PlanckR2'];
$B$exif[0]['PlanckB'];
$O$exif[0]['PlanckO'];
$F$exif[0]['PlanckF'];

print(
'Plancks values: '.$R1.' '.$R2.' '.$B.' '.$O.' '.$F."\n\n");

// get displayed temp range in RAW values
$RAWmax=$exif[0]['RawValueMedian']+$exif[0]['RawValueRange']/2;
$RAWmin=$RAWmax-$exif[0]['RawValueRange'];

print(
'RAW Temp Range from sensor : '.exec($convert.' raw.png -format "%[min] %[max]" info:')."\n");
printf("RAW Temp Range FLIR setting: %d %d\n",$RAWmin,$RAWmax);

//overwrite with settings
if (isset($options['rmin'])) $RAWmin=$options['rmin'];
if (isset(
$options['rmax'])) $RAWmax=$options['rmax'];

printf("RAW Temp Range select      : %d %d\n",$RAWmin,$RAWmax);

// calc amount of radiance of reflected objects ( Emissivity < 1 )
$RAWrefl=$R1/($R2*(exp($B/($Temp_ref+273.15))-$F))-$O;
printf("RAW reflected: %d\n",$RAWrefl); 

// get displayed object temp max/min and convert to "%.1f" for printing
$RAWmaxobj=($RAWmax-(1-$Emissivity)*$RAWrefl)/$Emissivity;
$RAWminobj=($RAWmin-(1-$Emissivity)*$RAWrefl)/$Emissivity;
$Temp_min=sprintf("%.1f"$B/log($R1/($R2*($RAWminobj+$O))+$F)-273.15);
$Temp_max=sprintf("%.1f"$B/log($R1/($R2*($RAWmaxobj+$O))+$F)-273.15);

// extract color table, swap Cb Cr and expand video pal color table from [16,235] to [0,255]
// best results: Windows -colorspace sRGB | MAC -colorspace RGB
exec($exiftool.' '.$flirimg.' -b -Palette | '.$convert.' -size "'.$exif[0]['PaletteColors'].'X1" -depth 8 YCbCr:- -separate -swap 1,2 -set colorspace YCbCr -combine -colorspace RGB -auto-level '.$embpal);

// draw color scale
exec($convert." -size 30x256 gradient: $pal -clut -mattecolor ".$frame_color.' -frame 5x5 -set colorspace rgb gradient.png');

// if your imagemagick have no freetype library remove the next line
exec($convert." gradient.png -background ".$frame_color." ".$font." -fill ".$font_color." -pointsize 15 label:\"$Temp_max C\" +swap -gravity Center -append  label:\"$Temp_min\" -append gradient.png");

if (
$exif[0]['RawThermalImageType'] != "TIFF")
{
  
//16 bit PNG: change byte order
   
$size=$exif[0]['RawThermalImageWidth']."x".$exif[0]['RawThermalImageHeight'];
   
exec($exiftool." -b -RawThermalImage $flirimg | ".$convert." - gray:- | ".$convert." -depth 16 -endian msb -size ".$size." gray:- raw.png");   
}else{
   
exec($exiftool." -b -RawThermalImage $flirimg | ".$convert." - raw.png");      
}

// convert every RAW-16-Bit Pixel with Planck's Law to a Temperature Grayscale value and append temp scale
$Smax=$B/log($R1/($R2*($RAWmax+$O))+$F);
$Smin=$B/log($R1/($R2*($RAWmin+$O))+$F);
$Sdelta=$Smax-$Smin;
exec($convert." raw.png -fx \"($B/ln($R1/($R2*(65535*u+$O))+$F)-$Smin)/$Sdelta\" ir.png");

if ( !isset(
$options['pip']) )
{    
    if ( !isset(
$options['clut']) )
    {
        if ( !isset(
$options['scale']) )
            {
            
// with color scale
            
exec($convert." ir.png ".$resize.$pal -clut -background ".$frame_color." -flatten +matte gradient.png -gravity East +append $destimg");
        }else{
            
exec($convert." ir.png ".$resize.$pal -clut ".$destimg);
        }
    }else{
        
// only gray picture
            
exec($convert." ir.png ".$resize." ".$destimg);
    }    
}else{
//make PiP
    //read embedded image
    
exec($exiftool." -b -EmbeddedImage $flirimg | ".$convert." - -set colorspace YCbCr -colorspace RGB embedded.png");
    
$geometrie=$exif[0]['OffsetX'].$exif[0]['OffsetY'];
    if ( 
is_string($options['pip']) )
    {
        
$crop="-gravity Center -crop ".$options['pip']."+0+0";
    }  
    
$resize=100*$exif[0]['EmbeddedImageWidth']/$exif[0]['Real2IR']/$exif[0]['RawThermalImageWidth'];
    
$resize="-resize ".$resize.'%';
    
exec($convert." ir.png $crop +repage ".$resize.$pal -clut embedded.png +swap -gravity Center -geometry $geometrie -compose over -composite -background ".$frame_color." -flatten +matte gradient.png -gravity East +append ".$destimg);
}

print(
"wrote $destimg with Temp-Range: $Temp_min / $Temp_max degree Celsius\n");

?>




using
$ ./flir.php

usage: ./flir.php [options] -i ir_file.jpg -o outputimage

Settings:
-i ir_file.jpg      flir radiometric image
-o output.jpg       save  8 Bit image jpg
-o output.png       save 16 Bit image png

Options Summary:
--resize val        scale sensor size with "convert -resize val" (val i.e. 600x or 100%, default is 200%)
--tref temp         overwrite embedded Reflected Apparent Temperature (degree Celsius)
--emis val          overwrite embedded Emissivity (val i.e. 0.95)
--rmin raw_min      set min RAW value instead embedded value (set scale min temp)
--rmax raw_ma       set max RAW value instead embedded value (set scale max temp)
--pal iron.png      use own palette (instead of embedded palette.png)
--clut              disable "Color LookUp Table" and color scale (save a grayscale image)
--scale             disable color scale on the right edge
--pip[=AxB]         input image is a flir PiP radiometric image
                    overlay embedded "real image" with "ir image"
                    [optional] crop ir image to size AxB (i.e. --pip=90x90 )
--help              print this help
 
# source:
# [1] https://exiftool.org/forum/index.php/topic,4898.0.html




samples with a picure from Flir B60:
download http://commons.wikimedia.org/wiki/File:Aqua_Tower_thermal_image.jpg (http://commons.wikimedia.org/wiki/File:Aqua_Tower_thermal_image.jpg)

cropped PiP
./flir.php -i Aqua_Tower.jpg -o test1.jpg --pip=120x120
Reflected Apparent Temperature: 20.0 degree Celsius
Emissivity: 1
Plancks values: 13559.122 0.010364772 1368.1 -5202 1

RAW Temp Range from sensor : 6953 13994
RAW Temp Range FLIR setting: 12104 14099
RAW Temp Range select      : 12104 14099
RAW reflected: 17617
wrote "test1.jpg" with Temp-Range: -12.5 / 0.6 degree Celsius


full sized PiP
./flir.php -i Aqua_Tower.jpg -o test2.jpg --pip

only Thermal Image
./flir.php -i Aqua_Tower.jpg -o test3.jpg

set min/max temp with related raw values (see above "RAW Temp Range FLIR setting: 12104 14099" for orientation)
./flir.php -i Aqua_Tower.jpg -o test4.jpg --rmin 13000 --rmax 13500

use an other palette:
./flir.php -i Aqua_Tower.jpg -o rain.jpg --pal rainbow.png

see result in attachments





hint for windows user for using php as a portable version without some installations:
http://windows.php.net/downloads/releases/php-5.4.xy-nts-Win32-VC9-x86.zip
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on May 14, 2013, 07:07:08 PM
Hi Tomas,

You really are the FLIR master.  Great work!

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: b0rja on May 20, 2013, 06:46:45 AM
Thank you very much for sharing your work on FLIR image data.

I have noticed that the temperature calculus in the script flir.php does not take into account the interaction with the atmosphere (ObjectDistance, RelativeHumidity, AtmosphericTemperature).

My research focuses on the analysis of distant bodies where this correction may be important.

If you can point me the physical formulation of this correction, I would be glad to modify the script to include it.

Best regards,
Borja.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on May 20, 2013, 07:07:07 AM
Hi Borja,

You can find this information in online FLIR documents by googling FLIR "the measurement formula".

For example, page 155 of this manual (http://www.workswell.cz/manuals/flir/hardware/A3xx_and_A6xx_models/FLIR_A320_and_A325.pdf).

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on May 20, 2013, 04:08:44 PM
@b0rja
you are right:
Quote from: tomas123 on April 18, 2013, 05:23:46 PM
I ignore the Emission of atmosphera. The influence is low by short distance. The calculation effort is high (distance, humidity).
Our calculated temperature is 100% identical with Flir temperature if you set the object distance to zero and let external optics transmission by 1.0!!
read my full post here:
https://exiftool.org/forum/index.php/topic,4898.msg23944.html#msg23944
you can extend the formula for "ObjectDistance, RelativeHumidity, Atmospheric Temperature" but is not simple

read a fluke manual of Ti100, Ti105, Ti110, Ti125 - there is also no compensation of air influence

Quote from: b0rja on May 20, 2013, 06:46:45 AM
My research focuses on the analysis of distant bodies where this correction may be important.

here you find more informations (a sample with 100m (!) distance):
http://qirt.gel.ulaval.ca/archives/qirt2010/papers/QIRT%202010-092.pdf
from the book "Infrared Thermography Errors and Uncertainties" (google for preview, page 55)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hansss on July 23, 2013, 02:38:51 PM
I find this thread VERY interesting. I have a flir i3 camera and would like to automatically generate cvs files with raw sensor data. My question is if this: Can I do this with exiftool.

When I run this:

exiftool -common -csv test1.jpg > test1.csv

I get this result:

SourceFile,FileName,FileSize,Model,DateTimeOriginal,ImageSize,FocalLength,ShutterSpeed
test1.jpg,test1.jpg,21 kB,FLIR_i3,2003:01:11 00:29:07.919+01:00,240x240,6.7 mm,1/29

However what I would like is this:

24.332;24.419;24.419;24.364;24.31;24.386;24.332;24.

I am enclosing the original flir picture test1.jpg  (my foot) and test1flir.csv which I created by using the export feature in Flir tools.

Today I called FLIR and they told me that none of their software presently has batch processing for creating csv files. They are however working on adding batch processing to ResearchIR however this product costs around $3000!

I would appreciate any help!

kind regards,
Hans
Zurich

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on July 23, 2013, 07:01:16 PM
Hi Hans,

You can extract the raw thermal image as binary data using ExifTool:

exiftool -rawthermalimage -b test1.jpg > out.dat

But that is as far as ExifTool goes.  There are scripts posted here that convert the raw data to temperatures, and they could probably be modified to output CSV format, but it would take some programming skill.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hansss on July 24, 2013, 07:11:15 AM
Hi Phil,

Thank you for making such a great tool and giving me hope!

Thank you for the command:

exiftool -rawthermalimage -b test1.jpg > out.dat

I tried it and it does extract an image that I can open as a png.

One question:

Tomas123 in one post in this thread got these results using FLIR.pm

RAW    Grad Celsius
0   -40,011
18498   25,791
18598   26,319
18722   26,969
18861   27,694
18980   28,311
19080   28,826
19180   29,34

Is it possible get similar info from test1.jpg using exiftool?

Hans
Zurich
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on July 24, 2013, 07:14:10 AM
Hi Hans,

Sorry, no.  ExifTool doesn't do manipulations with the raw thermal data.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hansss on July 24, 2013, 02:01:46 PM
Hi Phil,

Thank you very much for your response. I have downloaded perl for windows and will experiment with FLIR.pm in order to try to extract these values:


RAW    Grad Celsius
0   -40,011
18498   25,791
18598   26,319
18722   26,969
18861   27,694
18980   28,311

Hans
Zurich
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on August 03, 2013, 10:49:28 AM
sorry for my late response

the flir i3 has a changed byte order

see sample code here for expanding raw datas from flir image and calculating the temperature from a raw value (draw a temperature scale)
https://exiftool.org/forum/index.php/topic,4898.msg24230.html#msg24230

expand raw data with
$ exiftool -b -RawThermalImage test1.jpg | convert - gray:- | convert -depth 16 -endian msb -size 60x60 gray:- raw.png

you can preview your result with
$ convert raw.png -auto-level myfoot.jpg

now expand the raw values to a text file
$ convert raw.png  -compress none raw.pgm

open raw.pgm with a text editor (see: http://en.wikipedia.org/wiki/Netpbm_format )
P2
60 60
65535
12781 12789 12789 12784 12779 12786 12781 12788 12777 12787 12792 12783 12781
12791 12783 12778 12782 12775 12778 12781 12773 12774 12772 12786 12780 12782
12769 12785 12780 12792 12797 12780 12785 12785 12772 12781 12778 12789 12778
12781 12780 12777 12776 12787 12774 12787 12773 12779 12779 12785 12782 12786
12787 12772 12779 12789 12788 12786 12775 12777 12785 12778 12778 12781 12786
12788 12780 12775 12788 12779 12785 12774 12781 12783 12782 12783 12780 12787
12780 12773 12781 12777 12785 12773 12780 12781 12788 12783 12783 12793 12787


now you can simple calculate with excel (or a small script for batch processing) the temperature of every point:
your values are:

$ exiftool -Pl* test1.jpg
Planck R1                       : 14145.437
Planck B                        : 1381.9
Planck F                        : 1.35
Planck O                        : -6635
Planck R2                       : 0.022316413


see formulas and theory
https://exiftool.org/forum/index.php/topic,4898.msg23972.html#msg23972


Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hansss on August 03, 2013, 01:27:09 PM
Hi  Tomas,

THANK YOU very much for your kind support!!  I look forward to trying this out!

hans
zurich
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Alexgm on October 25, 2013, 03:14:18 PM
I'm working on a website where among other things, I can load an image, in my case from the Flir E40, and point at different parts of the image and see the temperature.
And I just finished (yea!!!) a bash/awk script to generate a file that contains a matrix with all the temperatures on any given image that I can then use on the site.
So, first I want to thank Phil Harvey for the amazing ExifTool and also Tomas123 for all his great posts for doing this -- you guys are awesome!
Also I found a very slight difference, of between 0.07 and 0.08 degrees Celsius higher, between the temperatures generated by Tomas123's scripts and the temperatures generated by Flir's QuickReport tool.
It doesn't make any difference to my project but I just wanted to share that.
Thanks for all the great work!
-- Alex
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on October 26, 2013, 04:39:31 AM
Quote from: tomas123 on April 18, 2013, 05:23:46 PM

I ignore the Emission of atmosphera. The influence is low by short distance. The calculation effort is high (distance, humidity).
Our calculated temperature is 100% identical with Flir temperature if you set the object distance to zero and let external optics transmission by 1.0!!

read my full post for more informations about calculation

and this
https://exiftool.org/forum/index.php/topic,4898.msg24310.html#msg24310
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: emiliozb on November 06, 2013, 10:52:28 PM
Phil and Tomas123, great work.

Should I use the Reflected Apparent Temperature for the T_refl on your formula?

Thanks,
E.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on November 07, 2013, 03:47:13 AM
Answer: yes

I think you mean T_refl from this post
https://exiftool.org/forum/index.php/topic,4898.msg23972.html#msg23972

see this post for a code sample (php)
Quote from: tomas123 on May 14, 2013, 04:03:02 PM
Options Summary:
--tref temp         overwrite embedded Reflected Apparent Temperature (degree Celsius)

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: filippo on November 07, 2013, 11:08:45 AM
Good morning everybody,
I'm new to this conversation (and to this forum too)... first I would like to do many compliments to tomas123 for his work.
I was trying to rewrite the original script from tomas123 in Python, just to extract raw thermal data from a jpg image coming from a FLIR camera, exiftool doesn't work with my images and so I decided to try this way.
I followed step-by step your reverse-engineering work, all seems to be similar in my picture except to the fact that I cannot find a segment with size equal to the image size computed from sensor dimensions (w*h*2+32).
My camera is the FLIR B335 one, I attached to this message a picture taken with this camera, can you suggest me a solution to properly extract raw thermal data?
Thank you a lot, regards
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on November 07, 2013, 11:14:56 AM
Quote from: filippo on November 07, 2013, 11:08:45 AM
just to extract raw thermal data from a jpg image coming from a FLIR camera, exiftool doesn't work with my images

Thanks for the sample.

I can extract the raw thermal PNG image just fine from the sample you posted:

exiftool FLIR_B335.jpg -rawthermalimage -b > out.png

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on November 07, 2013, 11:38:58 AM
Quote from: filippo on November 07, 2013, 11:08:45 AM
exiftool doesn't work with my images and so I decided to try this way.
no - exiftool works fine

you png has a reverse byte order
change it with imagemagick convert
>exiftool FLIR_B335.jpg -b -RawThermalImage | convert.exe - gray:- | convert.exe -depth 16 -endian msb -size 320x240 gray:- -auto-level out.png

my php script from this post
https://exiftool.org/forum/index.php/topic,4898.msg24230.html#msg24230
make all necessary steps (extract real image, IR image and color palette)

>php flir.php --pip -i FLIR_B335.jpg -o x6.jpg

Reflected Apparent Temperature: 20.0 degree Celsius
Emissivity: 0.95
Plancks values: 15076.116 0.010758856 1399.9 -6029 1

RAW Temp Range FLIR setting: 19240 21208
RAW Temp Range select      : 19240 21208
RAW reflected: 17949
RAW Temp Range from sensor : 19221 21214
wrote "x6.jpg" with Temp-Range: 26.7 / 36.2 degree Celsius


compare x6.jpg  with your image (doupled sized real and IR image)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: filippo on November 08, 2013, 09:20:24 AM
Hi Tomas and Phil,
thank you a lot for your explanation, I was just wrong using exiftool...

Now I obtained my thermal image but I would like to have it in false color. I try to explain my procedure step by step!

First I took out the full embedded visible image:

exiftool FLIR_B335.jpg -b -EmbeddedImage | convert -  -set colorspace YCbCr -colorspace RGB FLIR_B335full.jpg

Then I took out the palette (NB: I'm not sure about this step for 2 reasons: first I obtain an inverted palette, as you will see in the follow... I resolved this with a very stupid trick rotating palette but I think this is not a good idea and also the color of resulting thermal color image seem to be "compressed" in a tighter dinamic compared with the color thermal image of the original FLIR format):

exiftool FLIR_B335.jpg -b -Palette | convert -size 224X1 -depth 8 YCbCr:- -separate -swap 1,2 -set colorspace YCbCr -combine -colorspace RGB palette.png

Now I took out the raw thermal image; before I read the radiometric EXIF data to compute the temperature range:

exiftool FLIR_B335.jpg -raw*

   Raw Value Median                : 20224
   Raw Value Range                 : 1968
   ...

So:
   min temperature: 20224-1968/2=19240
   max temperature: 20224+1968/2=21208

And:

exiftool FLIR_B335.jpg -b -RawThermalImage | convert - gray:- | convert -depth 16 -endian msb -size 320x240 gray:- -level 21208,19240 rawThermal.png

Finally I applyied the palette to the thermal image:

convert rawThermal.png palette.png -clut colorThermal.png

Now, as you can see, colors in colorThermal image are inverted.
As you told before, if I just rotate the palette (it's a stupid way, I know...) and I apply new palette to raw thermal image I obtain something similar to the desired result:

convert palette.png -rotate 180 paletteRotated.png
convert rawThermal.png paletteRotated.png -clut colorThermal2.png

Resulting image is near to what I expected to obtain but, as I told before, the color dynamic seems to be not correct... can you help me to understand where I'm wrong? I think I'm doing just something stupid, I'm sorry, but I'm not an expert in image processing :( .

I attached all images  in an archive to this message, thank you all a lot!!!
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on November 08, 2013, 09:51:23 AM
hi filippo,

this not not a imagemagick forum. Phil supports only questions to exiftool ;-)

But I don't know a better forum for your problem :-(

As you can see in my post above (image x6.jpg) my php script makes all required steps for converting the RAW image to a false color image.
The result is near original flir. You can't get 100% original. Compare Camera Image, Flir Tools and Flir Quickreport - there are also differences.

read the script step by step with my comments until end !!


some hints for better results:

the Flir palette is a Video PAL with level 16 to 235 (see comment line 172 in script, try sRGB and RGB - ImageMagick was modified as of version 6.7.7-8 )
use -auto-level for better results ( jpg level is 0-255)

from this post https://exiftool.org/forum/index.php/topic,4898.msg24230.html#msg24230 you can download more palettes

use imagemagick mathematics for converting the non linear raw image to the linear temperature scale (line 234 from my script)
http://www.imagemagick.org/Usage/compose/#mathematics

if you use windows you find here text files with the color values of palettes
C:\ProgramData\FLIR Systems\Palettes
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Videogamer555 on January 17, 2014, 10:55:22 AM
Since the FLIR PNGs are in the wrong endian (compared to official PNG standard), what software do you use to decode them after you've extracted them from the FLIR JPEG files? As as I know, there is no software capable of decoding 16-bit grayscale PNG images where the image data's endianness is reversed (short of custom hacking software, built by hackers for the sole purpose of hacking FLIR pics, and these aren't publicly released by the hackers). Does ANYONE here know if there is some software I'm overlooking that COULD decode PNG files with little-endian image data?
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on January 17, 2014, 11:00:43 AM
This post (https://exiftool.org/forum/index.php/topic,4898.msg23665.html#msg23665) gives the technique that Tomas used to swap the endianness of the PNG image.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on January 17, 2014, 11:01:34 AM
it's the wrong forum

see answer here
http://www.imagemagick.org/discourse-server/viewtopic.php?f=2&t=24818
and
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg348398/#msg348398
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg342072/#msg342072
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on January 17, 2014, 11:04:02 AM
@phil
see my first link above
we talk about your work in developers forum of ImageMagick  :)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on January 17, 2014, 11:08:41 AM
Thanks Tomas,

I see this has been a hot topic recently. :)

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Videogamer555 on January 17, 2014, 11:51:21 AM
What do you mean wrong topic?
And I'm not looking for a perl script. I'm looking for an EXE file I can run (I don't have perl, and by looking at your console command lines, I can tell you are using linux, which I don't have. I have windows), one which upon loading a 16 bit grayscale PNG image asks the user (via a dialog box) if they wish to decode it the normal way (BE image data) or the FLIR way (LE image data). Then decodes the image according to the user's choice in the dialog box.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on January 17, 2014, 05:52:06 PM
sorry for misunderstanding
this forum only supports Exiftool and you ask for image manipulations
Quote from: Videogamer555 on January 17, 2014, 10:55:22 AM
... there is no software capable of decoding 16-bit grayscale PNG images where the image data's endianness is reversed
see my links above

Quote from: Videogamer555 on January 17, 2014, 11:51:21 AM
I can tell you are using linux, which I don't have. I have windows
my first link goes to a windows .exe solution
http://www.imagemagick.org/discourse-server/viewtopic.php?f=2&t=24818#p106958
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Videogamer555 on January 21, 2014, 02:08:09 PM
Seeing a lack of such software, I have made a Visual Basic 6 program that automatically looks at an FFF (raw only) or JPEG+FFF (JPEG with raw embedded, in which case it locates the start of the embedded FFF file) FLIR image file and can automatically determine if the data is PNG compressed (looks for the first four unique bytes of a PNG file). If it is, it extracts it, and simply removes any JPEG tags that may be separating the segments of data. It does not parse the JPEG tags in any way (nor does it handle any of the proprietary FFF header and FFF data chunks). It simply locates the start and end of the embedded PNG file by searching for the strings "‰PNG" and "IEND" (completely ignoring all the proprietary FLIR FFF junk). Then it uses ZLIB to decompress the PNG image data, and reverses the endianness of the now decompressed image data. It then recompresses the image data, recalculates the CRC32 and chunk size for the compressed image data (IDAT) chunk, and saves the resulting fixed IDAT chunk and along with the original header (IHDR) chunk and ending (IEND) chunk to a PNG file. This file is loadable in any software that supports PNG images, and is the correct image. Note this program does NOT handle uncompressed FFF or JPEG+FFF files that store uncompressed raw data (only PNG compressed raw data supported). Also this gives raw thermal IR sensor array values, not temperature readings. I have worked on other programs that do work with the proprietary FLIR stuff, but they only handle uncompressed raw data (not PNG compressed data). Some day I may write a program that combines these and can do "everything" regarding reading FLIR FFF images, but today isn't that day. It would take a LOT of time to combine these as they are both self contained, and don't have the ability to easily be expanded beyond their current capabilities, as my code is kind of "one task" code (would basically require completely rewriting my code in both of my programs, and the rewrite would have to be made into a single program, and that would take many many days of hours long work each day, as long as my 2 current programs took to write, and then some, as combining concepts together is harder than writing code for two different concepts separately).
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on January 21, 2014, 05:43:45 PM
Quote from: Videogamer555 on January 21, 2014, 02:08:09 PMI have made a Visual Basic 6 program that automatically looks at an FFF (raw only) or JPEG+FFF (JPEG with raw embedded

please publish your Flir informations in this Flir user thread (I posted the link above, over 3000 post):
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/
daves posts there some windows binaries for decoding flir images
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg350556/#msg350556

all php scripts here are only proof of concepts for the decoded exif tags

thanks
Title: Re: Atmosphere transmissivity
Post by: jskala on February 28, 2014, 02:49:46 AM
Hello,
I came across a description of a few more values in the CameraInfo record.

0x70: alpha1 (single)
0x74: alpha2 (single)
0x78: beta1 (single)
0x7c: beta2 (single)
0x80: X (single)

They are used to compute the atmosphere transmissivity tau. The alpha coefficients are the attenuation for atmosphere without water vapour, the beta coefficients are the attenuation for water vapour, and the X is the scaling factor for attenuation.

tAtmC = tAtm - 273.15  // in degrees Celsius

h2o = humidity * exp(1.5587 + 6.939e-2 tAtmC - 2.7816e-4 tAtmC^2 + 6.8455e-7 tAtmC^3)

tau = X * exp(-sqrt(distance) * (alpha1 + beta1 * sqrt(h2o))) + (1-X) * exp(-sqrt(distance) * (alpha2 + beta2 * sqrt(h2o)))


Source:
Minkina, Dudzik: Infrared Thermography: Errors and Uncertainities, Appendix A, page 171, http://books.google.cz/books?id=6H3HyacPxnMC&pg=PA171 (http://books.google.cz/books?id=6H3HyacPxnMC&pg=PA171)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on February 28, 2014, 05:03:33 AM
A great discovery. There are many questions for atmosphere transmissivity.

I think, it's float. Can you post a sample calculation with specific values?

save this as config.txt
# The %Image::ExifTool::UserDefined hash defines new tags to be added to existing tables.
%Image::ExifTool::UserDefined = (
    'Image::ExifTool::FLIR::CameraInfo' => {
          0x070 => { Name => 'AtmosphereTransmissivityAlpha1', Format => 'float', PrintConv => 'sprintf("%f",$val)'},
          0x074 => { Name => 'AtmosphereTransmissivityAlpha2', Format => 'float', PrintConv => 'sprintf("%f",$val)'},
          0x078 => { Name => 'AtmosphereTransmissivityBeta1', Format => 'float', PrintConv => 'sprintf("%f",$val)'},
          0x07C => { Name => 'AtmosphereTransmissivityBeta2', Format => 'float', PrintConv => 'sprintf("%f",$val)'},
          0x080 => { Name => 'AtmosphereTransmissivityX1', Format => 'float', PrintConv => 'sprintf("%f",$val)'},
    },
);   


I run this config file accross all 41 Flir cameras from https://exiftool.org/sample_images.html
Flir never changed this fixed values (this is a good sign)
>exiftool -config config.txt -AtmosphereTransmissivity* FLIR-Samples/*.jpg
======== FLIR-Samples/FLIR_B20HS.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_B335.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_b40.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_b50.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_Bertha3.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_E30.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_E30bx.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_E4.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_E40.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_E40bx.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_E50.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_E60.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_i3.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_i5.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_i50.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_i60.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_i7.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_P60.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_P60NTSC.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_P60PAL.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_P640.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_P660.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_T250_Western.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_T360_Western.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_T400.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_T400Western.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_T425.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_T620.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_T620bx.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_T640.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_ThermaCAM_A320.jpg
======== FLIR-Samples/FLIR_ThermaCAM_E65.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_ThermaCAM_EX320.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_ThermaCAM_P640.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_ThermaCAM_P660West.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_ThermaCAM_SC640.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_ThermaCAM_SC660Wes.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_ThermaCAM_T-400.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_ThermaCamP660Wes.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_ThermaCamSC660WES.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
======== FLIR-Samples/FLIR_Z-Camera.jpg
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
   41 image files read



as attachment the source
Minkina, Dudzik: Infrared Thermography: Errors and Uncertainities, Appendix A, page 171, http://books.google.com/books?id=6H3HyacPxnMC&pg=PA171
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on February 28, 2014, 11:15:07 AM
I hacked your formula in an Excel sheet
Can you please validate this sheet?

the result 0,98 looks good



In every camera manual Flir prints a sample "The measurement formula" with
tau=0,88
Tatm=20°C

I need a distance from 345 meter to get tau = 0,88
I'm unsure....

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on February 28, 2014, 11:47:07 AM
To me it looks like Alpha2 and Beta1 may be swapped.  If you exchange these, you get tau=0.88 for a distance of 1.4 m.

- Phil

Edit:  Or, with Alpha2 and Beta1 swapped, you also get tau=0.88 for a distance of 1 m and a humidity of 75% (still 20 C).
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on February 28, 2014, 08:53:41 PM
@jskala
you formula for tau is correct !!!

I extended the Excel Sheet with a complete temperature calculation (see this snip from Flir E4 camera manual).


for this purpose I created a Flir radiometric jpg with 4x4=16 Pixel and RAW values from 10000 to 25000 (step 1000)
RAW 10000 to 25000 is a good range for a Flir E4 (Temperature Range –20° to 250°C)

$ i=0; echo "P2 4 4 65535 "> 1.txt;while [ $i -lt 16 ]; do echo $((10000+$i*1000))>>1.txt; i=$(($i+1));done
$ convert pgm:1.txt 4x4.tif

//check the new image, better use "exiftool 4x4.tif" ;-)
$ identify 4x4.tif
4x4.tif TIFF 4x4 4x4+0+0 16-bit Grayscale Gray 224B 0.000u 0:00.000

// create a flir jpg with splitjpg.php from my post here
// http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg348715/#msg348715
// you need a real flir image for injection
$ ./splitjpg.php -i FLIR0008.jpg -r 4x4.tif -o 4x4.jpg

// check the new raw values
$ exiftool -b -RawThermalImage 4x4.jpg | convert - -compress none pgm:-
P2
4 4
65535
10000 11000 12000 13000 14000 15000 16000 17000 18000 19000 20000 21000 22000
23000 24000 25000


now open the 4x4.jpg with Flir Tools, change the values for atmosphere and distance and export the object temperature of every pixel in a csv file

As attachment two files with 4x4 Pixels
4x4-0m.jpg (Distance 0m, meaning no influence of air) ->  temperature 4x4-0.csv
4x4-100m.jpg (Distance 100m) -> temperature 4x4-100.csv

now compare the exported temperature of 16 Pixel from Flir Tools (°C)
$ cat 4x4-100.csv | tr ";" "\n" | tr "\n" " "
-17,98 1,64 17,56 31,233 43,372 54,383 64,521 73,962 82,828 91,211 99,18 106,79 114,085 121,1 127,865 134,403


with the result of Excel calculation for a distance of 100 meters
-17,980 1,640 17,560 31,233 43,372 54,383 64,521 73,962 82,828 91,211 99,180 106,790 114,085 121,100 127,865 134,403

PERFECT




used input values in Excel
$ exiftool -config config.txt -Atmos* -Planck* -Object* -Emis* -Reflected* -Relativ* 4x4-100m.jpg
Atmospheric Temperature         : 20.0 C
Atmosphere Transmissivity Alpha 1: 0.006569
Atmosphere Transmissivity Alpha 2: 0.012620
Atmosphere Transmissivity Beta 1: -0.002276
Atmosphere Transmissivity Beta 2: -0.006670
Atmosphere Transmissivity X1    : 1.900000
Planck R1                       : 14168.402
Planck B                        : 1386
Planck F                        : 2.5
Planck O                        : -7363
Planck R2                       : 0.026881648
Object Distance                 : 100.00 m
Emissivity                      : 0.95
Reflected Apparent Temperature  : 30.0 C
Relative Humidity               : 50.0 %


@Phil
the config.txt from https://exiftool.org/forum/index.php/topic,4898.msg27532.html#msg27532 works fine !!
you certainly find better names  ;)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 01, 2014, 09:29:43 AM
google is your friend

with informations from jskala I found a Flir document with the atmosphere transmissivity calculation and the corresponding names of constants

Toolkit IC2 Dig 16 Developers Guide 1.01; FLIR Publication number: 557 344 version B.
http://www.workswell.cz/manuals/flir/hardware/Toolkit_IC_2_Dig_16/Toolkit_IC2_Dig16_Developers_Guide_1_01_AGEMA_550_570_ThermaCAM_PM5X5_and_the_ThermoVisionFamily.pdf

as attachment the pages with the formulas and names
(ignore further calculations with K1/K2 , use formulas from excel sheet from my last post)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 01, 2014, 10:03:29 AM
Wow.  Good find.  I googled a bit too, but didn't find this.

It describes the binary format of a ".IMG" file.  Too bad it wasn't ".FFF".  However, the similarities in the data structures may be useful, and the documentation looks helpful.

I'm just about to release ExifTool 9.54, which will decode the 5 new parameters.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: jskala on March 05, 2014, 09:16:52 AM
Hi, I can confirm the values of alpha, beta, and X are constant. With one exception - the SC7650 camera. I have an AFF file from it and it has the following values:

d5 cf 9b bb (alfa1)
a8 c6 4b 3d (alfa2)
86 e3 79 3b (beta1)
c9 01 bb 3b (beta2)
9a 99 19 3f (X)

Which is approx. -0.0048; 0.0498; 0.0038; 0.0057; 0.6. For the parameters 20C, 50%, 10m, the tau results in 0.91. Perhaps the camera works on a different wavelengths and the attenuation is different?
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 05, 2014, 09:24:54 AM
I don't have an SC7650 sample image.  Would it be possible for you to post one?

I have only one .seq file from a SC4000 with an AFF header, but we are not yet able to decode it (https://exiftool.org/forum/index.php?topic=5279.0).  I'm assuming that this is the same format as your SC7650 AFF file.  It would be useful if you could provide any information about the format of this file.

Thanks.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: jskala on March 07, 2014, 04:00:43 AM
I'm able to decode two types of AFF format from different cameras/software (they differ slightly). Most of my work is based on your research of the FFF format. I thought you were not interested in AFF. I will make sure I can publish the .seq files I'm working with and I'll get back here soon.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: jskala on March 12, 2014, 12:20:20 PM
So here are my findings about the AFF format. The information about FFF in this forum helped me tremendously, thank You guys. I also got some hints from the book Infrared thermography: Errors and uncertainties (preview available at Google books). There is always a file header at the beginning of the file, and then a frame header at the beginning of each frame.

The file header is as follows (the same as FFF):

0x00: (text) AFF
0x04: (text) file creator, 16 bytes
0x14: (uint32) format (100)
0x18: (uint32) records address (0x40)
0x1c: (uint32) record count (1)
0x20: (uint32) next free record ID (2)
0x24: (uint16) swap pattern? (0)
0x26: (7 * uint16) spares (0)
0x34: (2 * uint32) reserved (0)
0x3c: (uint32) checksum (can be zero)


Apparently, the frames differ quite a bit by version. I can decode two. Please note that the file can contain data from a sensor say 327x245, and a 320x240 portion is specified to be actually used. You will see that at the addresses 0x62-0x71.

FLIR SC2000

0x40: (uint16) type (1)
0x42: (uint16) subtype (3)
0x44: (uint32) version (103)
0x48: (uint32) record ID (1)
0x4c: (uint32) record data offset (0x60)
0x50: (uint32) record length in bytes
0x54: unknown (0)
0x58: (uint32) object ID? (65)
0x5c: unknown (0)

0x60: (uint16) byte order (2)
0x62: (uint16) sensor width in pixels (327)
0x64: (uint16) sensor height in pixels (245)
0x66-0x69: unknown
0x6a: (uint16) first "proper" pixel on a scan line (4)
0x6c: (uint16) last "proper" pixel on a scan line (323)
0x6e: (uint16) first "proper" scan line (2)
0x70: (uint16) last proper scan line (241)
0x72-0x8b: unknown

0x8c: (single) emissivity
0x90: (single) distance
0x94: (single) reflected temperature (also used as window temperature?)
0x98: unknown (0)
0x9c: (single) atmospheric temperature
0xa0: (single) relative humidity

0xa4: (single) R
0xa8: (single) B
0xac: (single) F

0xb0: (single) alpha 1
0xb4: (single) alpha 2
0xb8: (single) beta 1
0xbc: (single) beta 2
0xc0: (single) X

0xc4: (single) camera range max
0xc8: (single) camera range min
... camera name, serial nr., lens, filter, calibration date
0x016c: (int32) offset (aka O)
0x0170: (single) gain (aka R2)
... unknown
0x01d8: (text) palette name, 16 bytes
0x01e8: (uint32) UNIX timestamp
0x01ec: (uint16) milliseconds
... unknown
0x0298: (uint16) start of raw data


PH Edit: fixed typo in offset
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: jskala on March 12, 2014, 12:47:09 PM
A615

0x40: (uint16) type (5)
0x42: (uint16) subtype (3)
0x44: (uint32) version (103)
0x48: (uint32) record ID (1)
0x4c: (uint32) record data offset (0x60)
0x50: (uint32) record length in bytes
0x54: unknown (0)
0x58: (uint32) object ID?
0x5c: unknown (0)

0x60: (text) FF2
... unknown (mostly zeros)
0x84: (uint16) byte order (2)
0x86: (uint16) sensor width in pixels (640)
0x88: (uint16) sensor height in pixels (485)
0x8a-0x8d: unknown
0x8e: (uint16) first "proper" pixel on a scan line (0)
0x90: (uint16) last "proper" pixel on a scan line (639)
0x92: (uint16) first "proper" scan line (0)
0x94: (uint16) last "proper" scan line (479)
... unknown (mostly zeros)

0xb4: (single) emissivity
0xb8: (single) reflected temperature
0xbc: (single) atmospheric temperature
0xc0: (single) distance
0xc4: (single) relative humidity
0xc8: (single) tau
0xcc: (single) window temperature
0xd0: (single) window transmissivity
... unknown (mostly zeros)

0xec: (single) R
0xf0: (single) B
0xf4: (single) F
... unknown (mostly zeros)
0x015c: (single) alpha 1
0x0160: (single) alpha 2
0x164: (single) beta 1
0x168: (single) beta 2
0x16c: (single) X
... unknown (zeros)
0x0188: (single) camera range max
... unknown temperatures
0x0198: (single) camera range min
... unknown
0x02ce: (single) gain (aka R2)
0x0302: (single) -offset (aka -O) negative! stored as float!
... unknown (zeros)
0x036a: (uint16) frame data min
0x036e: (uint16) frame data range
... unknown (zeros)
0x0386: (uint16) image width
0x0388: (uint16) image height
... unknown (zeros)
0x03ce: (uint64) Windows NT timestamp
... unknown (mostly zeros)
0x04ac: (uint16) start of raw data
after the raw data, there is an FFF style footer
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 15, 2014, 09:17:37 AM
Excellent, thanks!

Would it be possible to email me a couple of samples? (philharvey66 at gmail.com)  That would give me something to play with when I get a chance.

- Phil

Edit: I see you already sent me a private message with some files, thanks!!
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Videogamer555 on April 05, 2014, 04:23:49 PM
Where in an FFF file are the O, B, R1, R2, F constants stored? Can you tell me what the offsets are within the data info header? I know that in an FFF file there's the main header, then an index, and then various chunks (headers and other data) pointed to by the index. One of these is a data info chunk that has metadata about the thermal data (metadata = info about data). Some of this metadata is stuff like camera name, but other parts are the calibration constants (O, B, R1, R2, F, and possibly others) that are very important in converting the ADC data (which are values between 0x0000 and 0xFFFF) into actual usable Kelvin temperature units. I need to know within the metadata chunk offsets (relative to the start of the metadata chunk) where I will find these important constants. Please let me know.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 05, 2014, 04:52:37 PM
Did you see the ExifTool FFF tags documentation (https://exiftool.org/TagNames/FLIR.html#FFF)?  The constants you want are in the CameraInfo data, and the offsets are listed in the documentation.  The only trick is parsing the FFF format to find the starts of the various data records.  If you want example code, see the ProcessFLIR subroutine in lib/Image/ExifTool/FLIR.pm of the full ExifTool distribution.  It is well commented, and should be self-explanatory.

Also see this document on the FFF format (http://www.workswell.cz/manuals/flir/hardware/A3xx_and_A6xx_models/Streaming_format_ThermoVision.pdf), which is referenced from FLIR.pm.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Videogamer555 on April 06, 2014, 12:49:22 PM
Thanks for the info, but what do the table headers Index1 and Index2 mean on all those tables on the page you linked me to?

I would like to point out that your RawData documentation https://exiftool.org/TagNames/FLIR.html#RawData is NOT accurate.

By my own reverse engineering of the FFF format, I find that there are more than 3 header fields in a RawData chunk. There's also 4 fields in the RawData chunk's header for defining a cropping box (tells FLIR software to display only the portion of the image that is inside this region), and there's also a zoom field for telling FLIR software how much to magnify the image when it displays it.

Also, there is a field at the very start of the RawData chunk that is I think is a 16 bit integer version number, but is used to tell the endianness of the 16 bit image data which is particularly useful for PNG compressed data, as PNG does not inherently have a was of showing endianess of the image data. Also there's a field for telling the data type of the image (whether it's a 16bit integer or something else). Although the stuff in this paragraph I'm a bit less sure of, and I'd have to go through my notes to be sure about this.

Also I would like to point out something else that is missing from your documentation on the CameraInfo section https://exiftool.org/TagNames/FLIR.html#CameraInfo that is that at the very beginning of the CameraInfo section, there is a duplicate of the header from the RawData section (same image width, height, cropping, etc). In fact, if my memory serves, FLIR software will ignore the header of the RawData chunk if there is a CameraInfo section in the FFF file (I found changing values in only one of these copies of the image header actually had any effect when viewed in FLIR software).

Also, out of curiosity, just what is usSwapPattern field in the main FFF header used for? I've never figured that out.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 07, 2014, 06:58:37 AM
Quote from: Videogamer555 on April 06, 2014, 12:49:22 PM
By my own reverse engineering of the FFF format, I find that there are more than 3 header fields in a RawData chunk. There's also 4 fields in the RawData chunk's header for defining a cropping box (tells FLIR software to display only the portion of the image that is inside this region), and there's also a zoom field for telling FLIR software how much to magnify the image when it displays it.

Thanks for your advice.
I know this (and another unpublished) tags but I think it's not worth for Phil to decode all Flir informations. (For PiP calculation you can use the tag 0x002a "FLIR PiP Tags")
My intention is a work of proof for decoding the importend tags (RAW values and constants for temperature calculations).
The Flir segment in Exiftool is a hack and not a Flir documentation  ;)

see my post here with samples for using the known tags:
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg342072/#msg342072



If you need a special value you can simple extend exiftool with a config file.
Post the config file here then I can verify the informations.

see my config samples:
https://exiftool.org/forum/index.php/topic,4898.msg27532.html#msg27532
or
https://exiftool.org/forum/index.php/topic,4898.msg24156.html#msg24156

Quote from: Videogamer555 on April 06, 2014, 12:49:22 PM
Also, out of curiosity, just what is usSwapPattern field in the main FFF header used for? I've never figured that out.
see sample image data base is a good entry point
https://exiftool.org/sample_images.html
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 07, 2014, 07:25:54 AM
The Index1/Index2 meanings are explained on the main TagNames documentation page (https://exiftool.org/TagNames/index.html).

You say that the RawData documentation is not accurate.  Is any of the decoded information not correct?  I know that the decoding is not complete, but realistically there is no way that it ever could be.  However, if there are any useful tags that ExifTool is not decoding, please give me the details and I will add them.  ExifTool does use the first 2 bytes of the RawData record to determine the byte order, but this isn't extracted as a tag because it is a formatting detail and isn't useful information for the end user.

- Phil

Edit: Tomas points out that this is not FLIR documentation, which is true, but please let me know if there is any better documentation out there.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 07, 2014, 11:36:07 AM
Quote from: Phil Harvey on April 07, 2014, 07:25:54 AM
ExifTool does use the first 2 bytes of the RawData record to determine the byte order, but this isn't extracted as a tag because it is a formatting detail and isn't useful information for the end user.

Videogamer555 mean this tag in the header from the linked FFF document
Quote from: Phil Harvey on April 05, 2014, 04:52:37 PM
Also see this document on the FFF format (http://www.workswell.cz/manuals/flir/hardware/A3xx_and_A6xx_models/Streaming_format_ThermoVision.pdf), which is referenced from FLIR.pm.

Quotetypedef struct tagFLIRFILEHEAD
{
   char szFormatID[4]; /* Fileformat ID 'FFF\0' 4 4 */
   char szOrigin[16]; /* File origin 16 20 */
   unsigned long dwVersion; /* File format version 4 24 */
   unsigned long dwIndexOff; /* Pointer to indexes 4 28 */
   unsigned long dwNumUsedIndex; /* Number of indexes 4 32 */
   unsigned long dwNextID; /* Next free index ID 2 36 */
   unsigned short usSwapPattern;/* Swap pattern 2 38 */
   unsigned short Spare[7]; /* Spare 14 52 */
   unsigned long reserved[2]; /* reserved 8 60 */
   unsigned long dwChecksum; /* Head & index checksum 4 64 bytes */
} FLIRFILEHEAD;

and
http://cpansearch.perl.org/src/EXIFTOOL/Image-ExifTool-9.53/lib/Image/ExifTool/FLIR.pm
Quote# Process FLIR FFF record (ref PH/1/3)
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
# Returns: 1 if this was a valid FFF record
sub ProcessFLIR($$;$)
{
    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
    my $raf = $$dirInfo{RAF} || new File::RandomAccess($$dirInfo{DataPt});
    my $verbose = $exifTool->Options('Verbose');
    my $out = $exifTool->Options('TextOut');
    my ($i, $buff, $rec);

    # read and verify FFF header
    $raf->Read($buff, 0x40) == 0x40 and $buff =~ /^FFF\0/ or return 0;

    # set file type if reading from FFF file ($tagTablePtr will not be defined)
    $exifTool->SetFileType() unless $tagTablePtr;

    # FLIR file header (ref 3)
    # 0x00 - string[4] file format ID = "FFF\0"
    # 0x04 - string[16] file origin: seen "\0","MTX IR\0","CAMCTRL\0"
    # 0x14 - int32u file format version = 100
    # 0x18 - int32u offset to record directory
    # 0x1c - int32u number of entries in record directory
    # 0x20 - int32u next free index ID = 2
    # 0x24 - int16u swap pattern = 0 (?)
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on April 07, 2014, 11:55:41 AM
Hi Thomas,

Yes, there is that, but I was referring to this comment:

Quote from: Videogamer555 on April 06, 2014, 12:49:22 PM
there is a field at the very start of the RawData chunk that is I think is a 16 bit integer version number

in which he clearly indicates the first field of the RawData chunk.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on April 07, 2014, 12:03:46 PM
ok, let us wait for some interesting new tags  :)

for instance:
until now we can't define a color scale which is 100% identical to Flir (Tools)
Flir stretchs the color scale while no uniform temperature distribution
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: jmichael on June 26, 2014, 02:40:15 PM
Quote from: tomas123 on April 18, 2013, 05:23:46 PM

for testing I wrote a short shell script raw2tmp.sh

#!/bin/bash
echo "usage $0 flir.jpg PixelArea"
echo "see imagemagick crop for PixelArea, sample 1x1+0+0"

# get Flir values
Flir=$(exiftool -Flir:all "$1")
Type=$(echo "$Flir" | grep "Raw Thermal Image Type" | cut -d: -f2)
if [ "$Type" != " TIFF" ]
    then
        echo "only for RawThermalImage=TIFF"
        exit 1
fi

R1=$(echo "$Flir" | grep "Planck R1" | cut -d: -f2)
R2=$(echo "$Flir" | grep "Planck R2" | cut -d: -f2)
B=$(echo "$Flir" | grep "Planck B" | cut -d: -f2)
O=$(echo "$Flir" | grep "Planck O" | cut -d: -f2)
F=$(echo "$Flir" | grep "Planck F" | cut -d: -f2)

# get RAW Sensor value
RAW=$(exiftool -b -RawThermalImage "$1" 2>/dev/zero | convert - -crop $2 -colorspace gray -format "%[mean]" info: )

# calc spectral range of used Flir camera
echo -n "spectral range [micrometer]: "
echo "scale=2;14387.6515/$B"| bc -l

# calc Temperature of PixelArea with Emissivity = 1.0
degree=$(echo "scale = 8;$B/l($R1/($R2*($RAW+$O))+$F)-273.15" | bc -l )
echo "$RAW RAW => $degree degree Celsius at Emissivity=1.0"

# calc Temperature of PixelArea with saved Emissivity
Emissivity=$(echo "$Flir" | grep "Emissivity" | cut -d: -f2)
Refl_Temp=$(echo "$Flir" | grep "Reflected Apparent Temperature" | sed 's/[^0-9.-]*//g')

RAWrefl=$(echo "scale = 8;$R1/($R2*(e($B/($Refl_Temp+273.15))-$F))-$O" | bc -l )
RAWobj=$(echo "scale = 8;($RAW-(1-$Emissivity)*$RAWrefl)/$Emissivity" | bc -l )
echo $Emissivity $Refl_Temp $RAW $RAWrefl $RAWobj
degree=$(echo "scale = 8;$B/l($R1/($R2*($RAWobj+$O))+$F)-273.15" | bc -l )
echo "$RAWobj RAW => $degree °C at Emissivity=$Emissivity and $Refl_Temp °C reflected temp."


usage ./raw2tmp.sh flir.jpg PixelArea
see imagemagick crop for PixelArea, sample 1x1+0+0

here a sample with a area of 1x1 Pixel and the first pixel on top right (x,y => 0,0)
$ ./raw2tmp.sh IR_1546.jpg  1x1+0+0
spectral range [micrometer]: 10.30
12626 RAW => -9.51770751 degree Celsius at Emissivity=1.0
12373.04334215 RAW => -11.39208744 °C at Emissivity= 0.95 and 20.0 °C reflected temp.


With this values I also calculated the spectral range of camera
it's simple
B = h*c/(k*λ) goes to
λ[μm]=14387.6515/Planck_B
There are two sort of cams on market SW and LW cameras.
see Short Wave and Long Wave
http://en.wikipedia.org/wiki/Infrared

sample of spectral range with Flir E40:
calculated from Exif: 10.30 μm (Peak)
datasheet: 7.5–13 μm (Range)




script works only for Tiff Images
if you use "Raw Thermal Image Type"=PNG you must change upper/lower byte
$ convert cat1.png gray:- | convert -depth 16 -endian msb -size 120x120 gray:- -auto-level cat2.png


PH Edit: Fixed typo in a formula


Hi there,
I'm attempting to extract the temperature data from a jpeg generated by an FLIR E60. I tried using the shell script raw2tmp.sh that Tomas123 wrote (quoted above) and I'm having some trouble.
I have the script saved as a .sh file and I'm calling it in the cygwin64 terminal with the command, "bash raw2tmp.sh FLIR1248.jpg  1x1+0+0". The script seems to run but I got this as an output:

raw2tmp.sh: line 1: $'\r': command not found
usage raw2tmp.sh flir.jpg PixelArea
see imagemagick crop for PixelArea, sample 1x1+0+0
raw2tmp.sh: line 5: $'\r': command not found
raw2tmp.sh: line 41: syntax error: unexpected end of file

Lines 1 and 5 were empty lines so I removed them and resaved the file. It got rid of the 'command not found' issue but I'm now getting this;

$ bash raw2tmp.sh FLIR1248.jpg  1x1+0+0
usage raw2tmp.sh flir.jpg PixelArea
see imagemagick crop for PixelArea, sample 1x1+0+0
raw2tmp.sh: line 33: syntax error: unexpected end of file

Meaning that cygwin doesn't seem to like how the file ends (line 33 is the first blank line at the end of the script). I've not worked much with shell scripts before so I'm a little out of my element. Any suggestions?
Thanks in advance!!!
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on June 26, 2014, 03:46:20 PM
the shell script is a early version for testing, don't use it

Quote from: jmichael on June 26, 2014, 02:40:15 PM
Meaning that cygwin...
see here for current scripts for windows (with php):
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg342072/#msg342072

for windows binary software use the first link in the post above
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg350556/#msg350556
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: jmichael on June 26, 2014, 05:50:45 PM
Woops!
Okay perfect, thanks a bunch!!
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: jjmmss00 on July 03, 2014, 07:15:11 AM
Hi All,

I have been searching for a way to extract the raw data from my new Flir e4, and tried the "Batch Flir Image Converter" (mentioned above) which so far  works really well.

My one concern is that that my Norton virus software reports a security risk based on reputation (i.e. there was no actual issue found, but they didn't trust the source). Has anyone found any sort of problem with this download?

Also, the output raw image is 150k (320*240*2 width*height*2 bytes per pixel). However, my input file is not large enough to contain this much raw data (only about 140k total (but varies) which also includes significant other stuff). Is the E4 a lower bits/pixel camera, or is the raw image somehow compressed, or is there another explanation? Flir claims 14 bits per pixel on their web page. I went through a file with a binary editor and found it pretty much consistent with the file discussed in the first post of this blog, except my file is just not big enough.

thanks jjmmss00
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on July 03, 2014, 07:35:06 AM
see my links two posts above

there is a long thread for all things around the Flir E4
please ask there (I think, you have a hacked E4 and you know the thread)
www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown

hint: see exiftool RawThermalImageType -> PNG (compression)

read my tutorial "exiftool and Imagemagick step-by-step"
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg348398/#msg348398

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: jjmmss00 on July 03, 2014, 07:50:30 AM
Thanks Thomas123,

Yes the camera is hacked, and I do know the blog you referenced.

Will also study the other links.

jjmmss00
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Armen on July 09, 2014, 08:30:44 AM
Hello to all.
I am doing research on the energy balance of the earth. I started using FLIR A305sc to determine the temperature of the surface of plant at long range. Information that I found unto your conversation really helped me perform analysis and corrections. Thanck you much...
I have a question about Planck R canstant.
With ExiftoolGUI I get:

Planck R1                       : 16314.8828125
Planck B                        : 1423.59997558594
Planck F                        : 1
Planck O                        : -6199
Planck R2                       : 0.0109910489991307
Peack of spactral range 10.11 mkm

For have a proof, I calculated:
B = h*c/(k*λ)=(6.626068*10^-34*2.9979*10^8)/(1.38066*10^-23*10.11*10^-6) = 1423 (Planck B)
R=R1/R2=1.484*10^6, so...
R = 2*h*c^2/λ^5=(2* 6.626068*10^-34*(2.9979*10^8)^2)/(10.11*10^-6) = 1.423*10^3 ???? why not 1.484*10^6

And another question.
If spectral range is a constant (10.11 mkm) then Wien law of displacement (lambda=2898/T) is not provided in FLIR???

Thank you in advance for your reply and sorry for my english.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on July 17, 2014, 04:42:52 AM
this is not the right forum for this question  :)
- better ask here (there are the flir experts):
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/

the flir part of exiftool is only the reverse engeneering of paramaters you find in flir documents
read this long thread (and see the attachments)

use this excel sheet for proofing the values
https://exiftool.org/forum/index.php/topic,4898.msg27546.html#msg27546
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Armen on July 17, 2014, 07:37:19 PM
Thank you Tomas.
I have studied these documents. All calculated and corrected for several matrices and DEM model. Demanded an explanation from me about these constants. You talked about these constants a lot, so I thought that I am in the right forum.
Thanks for the tip.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: klarakos on August 01, 2014, 05:52:03 AM
These numbers just give the location and the number of entries in what I call the record directory (the FLIR equivalent of the EXIF IFD).  You aren't guaranteed that the camera data comes immediately after this, but in practice it is likely that it does.  Instead, the offsets in the record directory should be used to determine the location of the camera data records.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on October 15, 2015, 07:30:26 AM
Tomas has done some more decoding of the FLIR header in this thread (https://exiftool.org/forum/index.php/topic,6763.0.html).

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: universeblue on January 05, 2016, 06:21:23 PM
Hello,

I am looking at the reply from tomas123 to convert Flir image to texts:

$ exiftool -b -RawThermalImage test1.jpg | convert - gray:- | convert -depth 16 -endian msb -size 60x60 gray:- raw.png

It is very useful. However, I only have the raw output from FLIR, saying a.seq file, inside which there are more than 1 images. It works for me to get the information from the first image in a.seq. Would there be a way to extract the information from any of the images in a.seq file? Thank you for your help.

Jay
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on January 06, 2016, 03:04:34 AM
Which Flir camera do you use with 60x60?

Quote from: universeblue on January 05, 2016, 06:21:23 PM
Would there be a way to extract the information from any of the images in a.seq file?

see here:
https://exiftool.org/forum/index.php/topic,5279.msg25567.html#msg25567
different magic bytes:
https://exiftool.org/forum/index.php/topic,5279.msg25593.html#msg25593

more informations about Flir formats you find in my link list:
http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg342072/#msg342072

http://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg348398/#msg348398
Quoteor since IM 6.8.8 with switch png:swap-bytes:
convert -define png:swap-bytes=on t1.png t2.png
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: universeblue on January 06, 2016, 12:04:27 PM
Hi Thomas,

Thank you for your reply.
> Which Flir camera do you use with 60x60?

It is A655SC camera, which happens to be the same as you had in the link. It's not 60x60, but 640x480, which is fixed though.

I have:
----------------------------------
hexdump -n16 -C A655SC.seq
00000000  46 46 46 00 45 78 61 6d  69 6e 49 52 00 00 00 00  |FFF.ExaminIR....|
00000010
----------------------------------
Looks reasonable?

And the time stamp:
Date/Time Original              : 2015:11:04 00:26:31.196+01:00

However, using your code: FFF.CAMCTRL
in https://exiftool.org/forum/index.php/topic,5279.msg25593.html#msg25593
I get only 1 split file: seq101.fff, while A655SC.seq contains a lot.

Do you have any idea why?

Best, Jay
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: universeblue on January 06, 2016, 12:32:49 PM
Hi,

Ah, I realized a typo when modifying the magic bytes in the split.pl code. When it is fixed, I can split images with time stamp in the .seq file.

Thank you very much for the kind help here.

Best, Jay
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Arkana on February 05, 2016, 07:51:23 AM
Hello,
I'm new in this forum.
I came across ExifTool, by my attempt to manipulate radiometric jpg-files from my Flir T-360.
First of all let me thank you all very much. The work you have done here is amazing and profound!

I'm looking for a tool, that manipulates flir-images (post from May 2013) via batch mode.
I want to set a specific settings (scale-temp.min., scale-temp.max, Trefl., Emission, Atmospheric-Temp. and Distance).

I tested the flir.php-skript of Thomas123 and I'm really impressed.
It actually does most of the thigs I'm looking for.
So I wanted to ask, if there are any updates so far? For example a gui + batch-mode would be fantastic!
Is the output actually still radiometric and if not, is there a way to do that?

Something about the backround of this whole issue:
I tested a couple of apps from flir. I actually just know one software what does more or less what I want. This was ThermaCAM QuickView 1.3.
It removes all disturbing elements from the image and also changes the appearance of the color-scale in a certain way (to give some "in-between-values" on the scale is important for a better quality of analyzing these images) You can see the before and after in the attached files.
IR_45707.jpg is the direct camera-output
IR_001_2016.01.28_01.32.jpg is the output after simply opening and saving the image in ThermaCAM QuickView 1.3
There is also the possibility to change the scaling and actually all the parameters including color-pallets.

The big problem with ThermaCAM QuickView is, that it only runs under WindowsXP and it can't do batch-mode. This is particularly a problem, when I need to rescale hundreds of imagines by hand...
Also I'm a Linux-user. I run a virtual machine only for this purpose - this really sucks!!!

So I got some hope, when I started to read this forum and tested some of the suggested skripts. And as I said, the flir.php-skript of thomas123 seems to be the closest to what I'm looking for.
So, is there any chance, that you guys would continue on this track and to build in the end a powerful tool with a nice gui, opensource(!), which will beat the proprietary solutions from flir itself?

There is another link to this issue:
I'm member of the board in the association for applied Thermography in Switzerland ( www.thech.ch (http://www.thech.ch) ).
Since a long time, we are looking for a way to unify the appearance of Thermal images, no matter which brand the cam is. In this way, the images would be directly comparable.
To solve this problem is for sure a much bigger hack, but you see where I'm going.

I'm very curious about your responses.

Best regards,
Arkana
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on February 05, 2016, 12:18:04 PM
Hi Arkana,

Phil's exiftool forum is not the suitable forum for your question.
I wrote here some additional informations for decoding Flir images:
http://www.eevblog.com/forum/thermal-imaging/flir-e4-thermal-imaging-camera-teardown/msg342072/#msg342072


Quote from: Arkana on February 05, 2016, 07:51:23 AM
I tested the flir.php-skript of Thomas123 and I'm really impressed.
It actually does most of the thigs I'm looking for.
So I wanted to ask, if there are any updates so far? For example a gui + batch-mode would be fantastic!

All my php scripts are only "proof of concepts" for Flir/exiftool/imagemagick workflows.
The php syntax is easy. Therefore everybody can make necessary adjustments for own purpose.

Thomas
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Arkana on February 05, 2016, 02:48:25 PM
Hello Thomas,

thanks for the hints! I will check it out the recommended forum.

The php-adjustments would be manageable, but some parts of my request demand some deeper knowledge about the math behind these images as well. Therefore I thought to ask you directly. Actually I would love to discuss some ugrade-ideas with you directly, if you are interested.

But thanks a lot, for all the work, time and sweat you've put so far into this project - it's amazing!

Stefan
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: edgar_eacg on June 29, 2016, 12:25:27 PM
Greetings, first of all: Congratulations for your great work in this forum.

Following the discussion on this thread
Quote from: tomas123 on April 07, 2013, 12:29:49 PM
(sample 1) Extract Color Table and Raw Image from Flir radiometric JPG and generate a new Image

I'm interested in handling the color palette of some .seq files generated with a SC640 FLIR camera. I use exiftool file.seq -Palette -b > rawData.dat to get the binary data into a .dat file. Indeed as with your sample 1 it's a 672-bytes file. I know that the used color palette is Rainbow (exiftool file.seq -PaletteName and because the camera was configured in this way).
Below is a portion of the generated file rawData.dat

19 7A 9F 19 7A 9F 19 7A A0 19 7A A0 19 7A A0 19 7A A0 19 79 A1 19 79 A1 1A 79 A3 1A 79 A3 1C 77 A5 1C 77 A5 20 74 A5
20 74 A5 27 6F A6 2B 6C A7 ...

Then according to your comment
QuoteSize is here 224x1 Pixel (=672/3)
I assume that each 3-byte group represents one pixel of this pallete (241x1) with one byte as one color channel. Thus, for example, (19 7A 9F) should be the color of the first pixel but how can I interpret these values? How can I get the RGB values for each pixel of this palette?

Thanks in advance.

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on June 29, 2016, 01:40:07 PM
I don't understand your question.
In your link above the color table format is explained.
The colorspace is a interchanged YCbCr.

Do you know my newer post here?
http://www.eevblog.com/forum/thermal-imaging/flir-e4-thermal-imaging-camera-teardown/msg352778/#msg352778

Quoteafter understanding the BT.601 offset, I found a simple solution:

The colors are right, but the brightness is limited (16..238?).
With 16 Bit convert (Q16) we can simple stretch the brightness from 16*256=4096 to 238*256=60928

check your IM colorspace (switch between RGB or sRGB )
$ exiftool -b -Palette FLIR0074.jpg | convert -size 224X1 -depth 8 RGB:- -separate -swap 1,2 -set colorspace YCbCr -combine -colorspace sRGB -level 4096,60928 -resize 448x30! iron16.png
perfect:


compare with a screenshot from FlirTools GUI
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: edgar_eacg on June 29, 2016, 04:44:52 PM
Ok. Got it. I finally got the color palette I need. I lost the detail about interchanging CrCb
One last thing. Could you please give me some guidelines on the algorithm used to convert one pixel's temperature to color using the color palette?
Assuming I already have the pixel temperatures from the raw data,

I took a view on this thread looking for this process and you provide the flir.php file.

Quote from: tomas123 on May 14, 2013, 04:03:02 PM

flir.php
#!/usr/bin/php
<?php
//------------- set necessary paramters -------------------------------------

if (strtoupper(substr(PHP_OS03)) === 'WIN') {
    
//WINDOWS user: set path to tools
    
$convert='"C:\Program Files\ImageMagick-6.8.5-Q16\convert.exe"';
    
$exiftool='"C:\Program Files\exiftool\exiftool.exe"';
    
//set font variable as needed (Mac/Win) for color scale
    
$font='-font c:\windows\Fonts\arialbd.ttf';

} else {
    
//Unix/Mac: set path to tools here 
    
$convert='/opt/ImageMagick/bin/convert';
    
$exiftool='/usr/bin/exiftool';
    
//set font variable as needed (Mac/Win) for color scale
    
$font='-font /Library/Fonts/Arial\ Bold.ttf';
}

//color scale
$font_color='white';
$frame_color='black';

//extract embedded palette to
$embpal='palette.png';

//--------------------------------------------------------------------------

$shortopts  "";
$shortopts .= "i:";  // Required value
$shortopts .= "o:";  
$shortopts .= "h";  

$longopts  = array(
    
"resize:",     // Required value
    
"rmin:",     
    
"rmax:",    
    
"pal:",
    
"tref:",
    
"emis:",
    
"pip::",       // opt. value
    
"clut",        // No value
    
"scale",      
    
"help",       
);
$options getopt($shortopts$longopts);
#var_dump($options);

function help()
{
global 
$argv;
echo <<<EOT

usage: 
$argv[0] [options] -i ir_file.jpg -o outputimage

Settings:
-i ir_file.jpg      flir radiometric image
-o output.jpg       save  8 Bit image jpg
-o output.png       save 16 Bit image png

Options Summary:
--resize val        scale sensor size with "convert -resize val" (val i.e. 600x or 100%, default is 200%)
--tref temp         overwrite embedded Reflected Apparent Temperature (degree Celsius) 
--emis val          overwrite embedded Emissivity (val i.e. 0.95)
--rmin raw_min      set min RAW value instead embedded value (set scale min temp)
--rmax raw_ma       set max RAW value instead embedded value (set scale max temp)
--pal iron.png      use own palette (instead of embedded palette.png)
--clut              disable "Color LookUp Table" and color scale (save a grayscale image)
--scale             disable color scale on the right edge
--pip[=AxB]         input image is a flir PiP radiometric image
                    overlay embedded "real image" with "ir image"
                    [optional] crop ir image to size AxB (i.e. --pip=90x90 )
--help              print this help
  
# source: 
# [1] https://exiftool.org/forum/index.php/topic,4898.0.html

EOT;
}

if (isset(
$options['help']) || isset($options['h']))
{
 
help();
};

if (isset(
$options['i']))
{
    
$flirimg="\"".$options['i']."\"";
    if (isset(
$options['o']))
    {
        
$destimg="\"".$options['o']."\"";    
    } else {
      print 
'Error: No output file specified! "-o filename"'."\n";
      exit(
1);
    }
} else {     
    
help();
    exit(
1);
};

if (isset(
$options['pal']))
{
    
$pal="\"".$options['pal']."\"";  
} else {
    
$pal=$embpal;
}

if (isset(
$options['resize']))
{
    
$resize='-resize '.$options['resize'];    
} else {
    
// default
    
$resize="-resize 200%";
}

//get Exif values (syntax for Unix and Windows)
eval('$exif='.shell_exec($exiftool.' -php -flir:all -q '.$flirimg));
//var_dump($exif);

if (isset($options['tref']))
{
    
$Temp_ref=$options['tref'];  
} else {
    
$tmp=explode(" ",$exif[0]['ReflectedApparentTemperature']);
    
$Temp_ref $tmp[0];
}
if (isset(
$options['emis']))
{
    
$Emissivity=$options['emis'];  
} else {
    
$Emissivity=$exif[0]['Emissivity'];
}
print(
"\nReflected Apparent Temperature: ".$Temp_ref." degree Celsius\nEmissivity: ".$Emissivity."\n");

// save Flir values for Plancks Law for better reading in short variables
$R1=$exif[0]['PlanckR1'];
$R2=$exif[0]['PlanckR2'];
$B$exif[0]['PlanckB'];
$O$exif[0]['PlanckO'];
$F$exif[0]['PlanckF'];

print(
'Plancks values: '.$R1.' '.$R2.' '.$B.' '.$O.' '.$F."\n\n");

// get displayed temp range in RAW values
$RAWmax=$exif[0]['RawValueMedian']+$exif[0]['RawValueRange']/2;
$RAWmin=$RAWmax-$exif[0]['RawValueRange'];

print(
'RAW Temp Range from sensor : '.exec($convert.' raw.png -format "%[min] %[max]" info:')."\n");
printf("RAW Temp Range FLIR setting: %d %d\n",$RAWmin,$RAWmax);

//overwrite with settings
if (isset($options['rmin'])) $RAWmin=$options['rmin'];
if (isset(
$options['rmax'])) $RAWmax=$options['rmax'];

printf("RAW Temp Range select      : %d %d\n",$RAWmin,$RAWmax);

// calc amount of radiance of reflected objects ( Emissivity < 1 )
$RAWrefl=$R1/($R2*(exp($B/($Temp_ref+273.15))-$F))-$O;
printf("RAW reflected: %d\n",$RAWrefl); 

// get displayed object temp max/min and convert to "%.1f" for printing
$RAWmaxobj=($RAWmax-(1-$Emissivity)*$RAWrefl)/$Emissivity;
$RAWminobj=($RAWmin-(1-$Emissivity)*$RAWrefl)/$Emissivity;
$Temp_min=sprintf("%.1f"$B/log($R1/($R2*($RAWminobj+$O))+$F)-273.15);
$Temp_max=sprintf("%.1f"$B/log($R1/($R2*($RAWmaxobj+$O))+$F)-273.15);

// extract color table, swap Cb Cr and expand video pal color table from [16,235] to [0,255]
// best results: Windows -colorspace sRGB | MAC -colorspace RGB
exec($exiftool.' '.$flirimg.' -b -Palette | '.$convert.' -size "'.$exif[0]['PaletteColors'].'X1" -depth 8 YCbCr:- -separate -swap 1,2 -set colorspace YCbCr -combine -colorspace RGB -auto-level '.$embpal);

// draw color scale
exec($convert." -size 30x256 gradient: $pal -clut -mattecolor ".$frame_color.' -frame 5x5 -set colorspace rgb gradient.png');

// if your imagemagick have no freetype library remove the next line
exec($convert." gradient.png -background ".$frame_color." ".$font." -fill ".$font_color." -pointsize 15 label:\"$Temp_max C\" +swap -gravity Center -append  label:\"$Temp_min\" -append gradient.png");

if (
$exif[0]['RawThermalImageType'] != "TIFF")
{
  
//16 bit PNG: change byte order
   
$size=$exif[0]['RawThermalImageWidth']."x".$exif[0]['RawThermalImageHeight'];
   
exec($exiftool." -b -RawThermalImage $flirimg | ".$convert." - gray:- | ".$convert." -depth 16 -endian msb -size ".$size." gray:- raw.png");   
}else{
   
exec($exiftool." -b -RawThermalImage $flirimg | ".$convert." - raw.png");      
}

// convert every RAW-16-Bit Pixel with Planck's Law to a Temperature Grayscale value and append temp scale
$Smax=$B/log($R1/($R2*($RAWmax+$O))+$F);
$Smin=$B/log($R1/($R2*($RAWmin+$O))+$F);
$Sdelta=$Smax-$Smin;
exec($convert." raw.png -fx \"($B/ln($R1/($R2*(65535*u+$O))+$F)-$Smin)/$Sdelta\" ir.png");

if ( !isset(
$options['pip']) )
{    
    if ( !isset(
$options['clut']) )
    {
        if ( !isset(
$options['scale']) )
            {
            
// with color scale
            
exec($convert." ir.png ".$resize.$pal -clut -background ".$frame_color." -flatten +matte gradient.png -gravity East +append $destimg");
        }else{
            
exec($convert." ir.png ".$resize.$pal -clut ".$destimg);
        }
    }else{
        
// only gray picture
            
exec($convert." ir.png ".$resize." ".$destimg);
    }    
}else{
//make PiP
    //read embedded image
    
exec($exiftool." -b -EmbeddedImage $flirimg | ".$convert." - -set colorspace YCbCr -colorspace RGB embedded.png");
    
$geometrie=$exif[0]['OffsetX'].$exif[0]['OffsetY'];
    if ( 
is_string($options['pip']) )
    {
        
$crop="-gravity Center -crop ".$options['pip']."+0+0";
    }  
    
$resize=100*$exif[0]['EmbeddedImageWidth']/$exif[0]['Real2IR']/$exif[0]['RawThermalImageWidth'];
    
$resize="-resize ".$resize.'%';
    
exec($convert." ir.png $crop +repage ".$resize.$pal -clut embedded.png +swap -gravity Center -geometry $geometrie -compose over -composite -background ".$frame_color." -flatten +matte gradient.png -gravity East +append ".$destimg);
}

print(
"wrote $destimg with Temp-Range: $Temp_min / $Temp_max degree Celsius\n");

?>


But when I checked the source code I realized that the algorithm is wrapped in the use of convert.exe through the command line exec.
I'm interested in the mapping algorithm from temperatures to color (using the color Palette) so that I could conceive an inverse algorithm for mapping from color to pixel temperature.

Thanks
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on June 29, 2016, 04:51:22 PM
This is not a exiftool question.
Please use this forum for your questions:
http://www.eevblog.com/forum/thermal-imaging/

There are many ImageMagick samples and software tools (like Thermovision_JoeC) for converting Flir images with the knowledge of exiftools reverse engineering.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: casonar on June 09, 2017, 11:23:22 AM
Hi,

Sorry to resurrect this post, but it seemed the best fit considering what I was

I have an image here from a FLIR T420. ExifTool says that it's a PNG for the RawThermalImage and I can extract it. The problem is that the image is very distorted and I'm not sure what to do with it. I want to be able to translate the raw thermal image information to temperature values. I can do this with a raw TIFF, but the PNG seems to be much different.

I have tried the flir.php conversion script and it gives me the same information.

I have attached the image as well as what I receive when I extract the "RawThermalImage" from ExifTool.

Thanks for your thoughts.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on June 09, 2017, 12:01:35 PM
simply swap the byte order in your 16 bit png:

http://www.eevblog.com/forum/thermal-imaging/flir-e4-thermal-imaging-camera-teardown/msg348398/#msg348398

Quote// swap byte order (here you have trouble)
convert t1.png pgm:- | convert -endian lsb pgm:- t2.png
or
convert t1.png gray:- | convert -depth 16 -endian msb -size 320x240 gray:- t2.png
or since IM 6.8.8 with switch png:swap-bytes
convert -define png:swap-bytes=on t1.png t2.png

your image
$ convert -define png:swap-bytes=on FLIR0055.jpg.png  -auto-level swap.png
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: casonar on June 09, 2017, 12:39:14 PM
Ah, that's great! I've been searching and trying to figure this out for a couple of days now.

Should ExifTool do the byte swapping (or at least have an explanation that this could/should be necessary)?
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on June 09, 2017, 02:53:18 PM
Quote from: casonar on June 09, 2017, 12:39:14 PM
Should ExifTool do the byte swapping (or at least have an explanation that this could/should be necessary)?

This would stray into the realm of image editing, which I try to avoid doing with ExifTool.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: siddhantmodi on August 10, 2017, 04:18:33 PM
Hello,

Thanks a lot Phil and Tomas for all the work you guys have done!

I've gone through this thread extensively and have understood most of what I need to be doing to get temperature information out of my FLIR camera images. I have a FLIR Vue Pro R (640 x 512) that I am using for some ground testing, with the idea being that this camera will eventually be mounted on a drone. Using exiftool and the raw2temp.sh script, as well as the atmosphere.xls spreadsheet, I have been able to successfully calculate pixel temperatures and found that they match the data I get from FLIR Tools.

Simultaneously, I have been trying to do the same for a friend, who has a DJI Zenmuse XTR camera mounted on his DJI drone. The camera is a FLIR camera and I believe it is also a Vue Pro R (640 x 512) but has been rebranded a bit. He took some images and passed them onto me for analysis. FLIR Tools is able to decode those images and give me a csv file with temperatures. The problem arises when I try to use exiftool + atmosphere.xls. The results I get from this method do not match the output from FLIR Tools. I have checked all the parameters I am entering to the calculation spreadsheet multiple times and all seems to be correct so I am a bit lost at the moment.

I am unable to attach files to this post due to some error, so the DJI image, as well as the output from FLIR Tools, and the spreadsheet for calculations can all be found on this link. I hope that someone will be able to assist me! Please let me know if there are any questions that you may have for me.

https://www.dropbox.com/sh/e7fc6vv9wh6nby4/AABSQICe6LArWakWgRvQ0QYda?dl=0

Thank you for all your help and time.

Kind regards,
Sid
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on August 15, 2017, 07:31:46 AM
Hi Sid,

Have you tried posting this question here?:  http://www.eevblog.com/forum/thermal-imaging/

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: edgar_eacg on October 02, 2017, 05:44:37 PM
Hello.

First of all, Congratulations for your great application!!
I've been working with a Flir T630sc camera and exiftool works great. I'm specially interested in the way you decode the Date Time Original TAG directly from the binary jpg file. In the attached file the timestamp is 2017:09:15 10:58:36.162-06:00. Using the -H option with the exiftool command I get the  0x0384 address tag for the date time but I have no data in this address. In the following thread you mention that the address is 0x038c but is the same issue. I thought that the address was camera model dependant but I've tried a P640 model and the exiftool app retrieves it correct.

Quote from: Phil Harvey on April 12, 2013, 07:27:54 AM
OK, I am now able to decode the time zone from the FFF information (it was located at offset 0x38c in the CameraInfo):

> exiftool ~/Desktop/{fpf,jpg}/*1* -datetimeoriginal -G1
======== /Users/phil/Desktop/fpf/Ir_2517_dst-1.fpf
[FLIR]          Date/Time Original              : 2013:04:12 09:24:01.131
======== /Users/phil/Desktop/fpf/Ir_2519_dst+0.fpf
[FLIR]          Date/Time Original              : 2013:04:12 09:24:44.292
======== /Users/phil/Desktop/fpf/Ir_2521_dst+1.fpf
[FLIR]          Date/Time Original              : 2013:04:12 09:25:14.279
======== /Users/phil/Desktop/jpg/IR_2517_DST-1.jpg
[ExifIFD]       Date/Time Original              : 2013:04:12 09:24:01
[FLIR]          Date/Time Original              : 2013:04:12 09:24:01.131-01:00
======== /Users/phil/Desktop/jpg/IR_2519_DST+0.jpg
[ExifIFD]       Date/Time Original              : 2013:04:12 09:24:44
[FLIR]          Date/Time Original              : 2013:04:12 09:24:44.292+00:00
======== /Users/phil/Desktop/jpg/IR_2521_DST+1.jpg
[ExifIFD]       Date/Time Original              : 2013:04:12 09:25:14
[FLIR]          Date/Time Original              : 2013:04:12 09:25:14.279+01:00
    6 image files read


And the times in all of my samples are now consistent.  Thanks!

- Phil

Please, could you give me some guidelines on how to locate the date time address tag and how do you decode it?
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on October 03, 2017, 07:47:34 AM
See here (https://sourceforge.net/p/exiftool/code/ci/master/tree/lib/Image/ExifTool/FLIR.pm#l448) for the decoding of the FLIR DateTimeOriginal.  The address is 0x0384 in the CameraInfo (type 0x20) record.  You must parse the FLIR metadata to locate this record.  Further down in the source code you will find the ProcessFLIR procedure which shows you how to do this.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: bobdebaumeister on February 02, 2018, 01:00:07 PM
Hello everyone
I'm new to this topic and therefore read and learned a lot in this forum, thank you for your hard work! Sorry for posting in this old topic but I think my question matches good here.

I work with a radiometric DJI Zenmuse XT which is based on the Flir Tau 2 I guess. My goal is to convert radiometric JPG files to RAW data and then calculate the temperature for every pixel (in the end I think with a python software).

I managed to calculate the temperatures according to posts:
Quotehttps://exiftool.org/forum/index.php?quote=27546;topic=4898.105;last_msg=44144
and
Quotehttps://exiftool.org/forum/index.php?quote=23972;topic=4898.60;last_msg=44144
from the raw values (counts exported as csv with ResearchIR Software) in excel and I get the same temperatures as the ResearchIR software shows.

My problem is that I could not export the raw values with exiftool according to post
Quotehttps://exiftool.org/forum/index.php?quote=24992;topic=4898.90;last_msg=44144
I tried:
.\exiftool -b -RawThermalImage DJI_0040.jpg | .\convert - gray:- | .\convert -depth 16 -endian lsb -size 640x512 gray:- raw40.png
where I get the following warnings but the file raw40.png is generated:
convert.exe: Unknown field with tag 63 (0x3f) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/994.
convert.exe: Unknown field with tag 6656 (0x1a00) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/994.
convert.exe: Unknown field with tag 6912 (0x1b00) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/994.
convert.exe: Unknown field with tag 7168 (0x1c00) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/994.
convert.exe: Unknown field with tag 10240 (0x2800) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/994.
convert.exe: Bogus "StripByteCounts" field, ignoring and calculating from imagelength. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/994.

and then:
.\convert raw40.png  -compress none raw40.pgm
But the raw40.png has some errors and therefore also the raw40.pgm file has wrong values compared to the count export from the ResearchIR Software.

I also tried to export the png directly with exiftool according to post
Quotehttps://exiftool.org/forum/index.php?quote=26101;topic=4898.90;last_msg=44144
.\exiftool DJI_0040.jpg -rawthermalimage -b > out.png
But then I'm not able to open the PNG or convert it.

It would be great if someone could help me with exporting the raw values. I used exiftool-10.75 and ImageMagick-7.0.7-22-portable-Q16-x64. The files are in the attachment.

Thank you.

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on February 02, 2018, 01:16:07 PM
Your attached version of out.png is corrupted somehow (did you use PowerShell? -- it can not be used for piping binary files).

But when I extract the RawThermalImage from DJI_0040.jpg I get a tiff file, not a png:

> exiftool ~/Desktop/DJI_0040.jpg -rawthermalimage -b | exiftool - -filetype
File Type                       : TIFF


The TIFF file does contain a thermal image that looks reasonable in GraphicConverter, but very dark in other utilities, and probably needs to be converted using a different technique.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: bobdebaumeister on February 02, 2018, 06:56:57 PM
Thank you very much for your fast answer.
Yes I used PowerShell which was the problem. With cmd it works like it should and I get exactly the same raw data (out2.png and out2.pgm) as I can export from ResearchIR.

The image is directly out of the camera (set to rjpg) without any change. When I read all metadata exiftool -k DJI_0040.jpg I get the following output:

...
File Name                       : DJI_0040.jpg
...
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
...
Raw Thermal Image Type          : TIFF

and if I do the same as you exiftool -filetype DJI_0040.jpg
I get File Type                       : JPEG
so I don't know why you get TIFF for this. But the raw data export works perfect, thanks again.

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on February 02, 2018, 09:18:01 PM
Quote from: bobdebaumeister on February 02, 2018, 06:56:57 PM
When I read all metadata exiftool -k DJI_0040.jpg I get the following output:

Yes, but I was reading the metadata of the RawThermalImage, not the original JPEG (notice that I piped the output of one exiftool to another in my command).  So RawThermalImage is TIFF, not PNG, but it seems that it works for you even if you give it the wrong extension.

Run ExifTool on out2.png and you will see what I mean.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Jaime_Garcia on March 21, 2018, 08:41:45 PM
Hello, I am new to the group, I have a Flir Vue Pro camera, I would like to choose the temperature value in .TIFF format. What equation or method do you recommend to convert digital numbers to temperature values?
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on March 21, 2018, 09:16:39 PM
I would have to read through this long thread to answer your question.  I'm sure your answer is here somewhere, but I don't have time to find it for you.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: tomas123 on March 22, 2018, 05:14:39 AM
Quote from: Jaime_Garcia on March 21, 2018, 08:41:45 PM
I have a Flir Vue Pro camera, I would like to choose the temperature value in .TIFF format.

This is not the right forum for your question.
Ask here: http://www.eevblog.com/forum/thermal-imaging/

You might find a solution in my old link list
http://www.eevblog.com/forum/thermal-imaging/flir-e4-thermal-imaging-camera-teardown/msg342072/#msg342072

Also joe-c posts are good entry points:
http://www.eevblog.com/forum/thermal-imaging/freeware-software-for-thermal-analysis-thermovision_joec/
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hebazxcv on April 30, 2018, 01:38:44 PM
Hello everyone
I have learned a lot so far from this forum, thank you for the hard work!. I am using FLIR T620 camera and my problem so far that the temperature obtained from converting the jpg image obtained from flir (downloaded from the sd-card) into tiff file using exiftool and then read it in matlab as a matrix and use all the mentioned equations in the forum with the calibration constants to convert it into temperature doesn't 100% matches the temperature obtained directly from reseachIr for the same image ( it has a deviation of less 0.2 degrees), I thought fist that the reason was from FLIR logo but I guess now it is not since the counts obtained from researchIR matches 100% the counts obtained from the tiff file.

And one last question, the only format that FLIR give for T620 camera is .jpg is it lossy?!

Again I would like to thank you for your time to read my question :).
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hebazxcv on May 09, 2018, 05:03:46 PM
Hello everyone
Sorry for re-posting the question, please if I am in a wrong forum please direct me where I should post it. Thank you again.

I have learned a lot so far from this forum, thank you for the hard work!. I am using FLIR T620 camera and my problem so far that the temperature obtained from converting the jpg image obtained from flir (downloaded from the sd-card) into tiff file using exiftool and then read it in matlab as a matrix and use all the mentioned equations in the forum with the calibration constants to convert it into temperature doesn't 100% matches the temperature obtained directly from reseachIr for the same image ( it has a deviation of less 0.2 degrees), I thought fist that the reason was from FLIR logo but I guess now it is not since the counts obtained from researchIR matches 100% the counts obtained from the tiff file.

And one last question, the only format that FLIR give for T620 camera is .jpg is it lossy?!

Again I would like to thank you for your time to read my question.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: StarGeek on May 09, 2018, 05:11:55 PM
I can't provide any information about your camera, but Jpegs are lossy.  There are some image manipulations you can do to a jpeg which are lossless (rotation in 90 degree increments, horizontal/vertical flips) and newer formats (JPEG 2000) which can be lossless, but otherwise, it will be a lossy format.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on May 09, 2018, 09:42:41 PM
If you are extracting the RawThermalImage as a TIFF then it could be lossless.  Honestly I can't help with a difference of 0.2 degrees since that seems much better than the accuracy of the device.  Approximations such as the amount of humidity in the air will change the calculation by more than that.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hebazxcv on May 10, 2018, 05:57:58 PM
Thank you very much for your reply, yes 0.2 is very small compared to the accuracy of the camera, I will keep searching and if I find something I will post it here.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hebazxcv on May 16, 2018, 10:45:09 AM
Hello Again,
I have a question regarding the FLIR logo in thermal images. If the image is opened through FLIR software as ResearchIR the logo disappear, so how to check if they are using some kind of masking the logo pixels with the around pixels. In addition, when the image is converted to tiff using exiftool using RawThermalImage commend it has the same 16 bit data as from ResearchIR is that mean the logo pixels is masked with the around pixels as well. And would that be applicable for the color scale in the image or it will be different.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on May 16, 2018, 10:47:42 AM
I think this question is better asked in the eevblog forum that tomas linked.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hebazxcv on May 16, 2018, 12:16:18 PM
Thank you.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hectorb79 on September 20, 2018, 11:50:36 PM
Hello tomas123 / Phil, how are you

Sorry for the next question, I am not sure if this is the right forum... here we go: When I try to run the pipe suggested by tomas, I receive the  error messages shown below:

Code:
$ exiftool C:/Users/Bastidas/Documents/fotos_pruebas/DJI_0866.jpg -b -RawThermalImage | convert.exe - gray:- | convert.exe -depth 16 -endian msb -size 320x240 gray:- -auto-level C:/Users/Bastidas/Documents/fotos_pruebas/DJI_0866_outraw.png

Errors:
convert.exe: unexpected end-of-file '-': No such file or directory @ error/gray.c/ReadGRAYImage/241.
convert.exe: no images defined `C:/Users/Bastidas/Documents/fotos_pruebas/DJI_0866_outraw.png' @ error/convert.c/ConvertImageCommand/3288.


Do you know what is the problem?

I am attentive to your commentes
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: StarGeek on September 21, 2018, 12:07:39 AM
What is the result when you run
exiftool C:/Users/Bastidas/Documents/fotos_pruebas/DJI_0866.jpg -RawThermalImage

You should get back something like
RawThermalImage: (Binary data ##### bytes, use -b option to extract)

If you don't get something like that, then there isn't a RawThermalImage to extract.

Also, make sure you're using CMD, not Powershell.  Powershell doesn't play nice with piping binary data.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hectorb79 on September 21, 2018, 08:57:53 AM
Hello StarGeek, good day!

Thanks for you feedback! This is the result

$ exiftool C:/Users/Bastidas/Documents/fotos_pruebas/DJI_0866.jpg -RawThermalImage
Raw Thermal Image               : (Binary data 655564 bytes, use -b option to extract)

Software which I'm using:
- Windows 10 and CMD
- Exiftool 11.1.0.0
- ImageMagick-7.0.8-11-Q16-x64-dll

The picture DJI_0866.jpg was taken with a cam Flir Zenmuse XT-R. I can read this picture in Flir Tools without problems, edit variables as emissivity and reflected temperature, then, return the temperatures absolutes.

I am attentive if you have other suggestions to my problem!

Thanks!!
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on September 21, 2018, 09:42:00 AM
Try each step in the chain separately, taking a look at the image produced by each step, starting with the raw thermal image:

exiftool -rawthermalimage -b C:/Users/Bastidas/Documents/fotos_pruebas/DJI_0866.jpg -W raw_image.%s

This command will produce a file called "raw_image" in the current directory with an appropriate extension.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hectorb79 on September 21, 2018, 10:31:24 AM
Quote from: Phil Harvey on September 21, 2018, 09:42:00 AM
Try each step in the chain separately, taking a look at the image produced by each step, starting with the raw thermal image:

exiftool -rawthermalimage -b C:/Users/Bastidas/Documents/fotos_pruebas/DJI_0866.jpg -W raw_image.%s

This command will produce a file called "raw_image" in the current directory with an appropriate extension.

- Phil

Hello Phil ! Thanks for your comments!

The command produce the .TIFF correctly (see attachment). I think that exiftool works perfect. Then I guess my problem is with ImageMagick when I try to do the next steps in the pipe to produce the .png.

What do you recommend me?

I am attentive to your comments.
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on September 21, 2018, 10:45:04 AM
Now try the "convert" commands one at a time.  To see which one fails.   You will probably have to read the "convert" documentation to figure this out.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Lawdefined on December 06, 2019, 04:02:47 AM
Hi Phil, Hectorb79,

Even I am facing the same issue.

When I execute the command

exiftool  DJI_0014.jpg -b -RawThermalImage | convert.exe -size 640x512 gray:- C114.png

It gives me following error

convert.exe: Unknown field with tag 63 (0x3f) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/1029.
convert.exe: Unknown field with tag 6656 (0x1a00) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/1029.
convert.exe: Unknown field with tag 6912 (0x1b00) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/1029.
convert.exe: Unknown field with tag 7168 (0x1c00) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/1029.
convert.exe: Unknown field with tag 10240 (0x2800) encountered. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/1029.
convert.exe: Bogus "StripByteCounts" field, ignoring and calculating from imagelength. `TIFFReadDirectory' @ warning/tiff.c/TIFFWarnings/1029.
convert.exe: must specify image size `-' @ error/gray.c/ReadGRAYImage/147.

I could make sense out of the last error "convert.exe: must specify image size `-' @ error/gray.c/ReadGRAYImage/147."

and executed the rectified command

exiftool  DJI_0014.jpg -b -RawThermalImage | convert.exe -size 640x512 gray:- C114.png

and then error pops up saying

convert.exe: unexpected end-of-file '-': No such file or directory @ error/gray.c/Read
convert.exe: no images defined `C114.png' @ error/convert.c/ConvertImageCommand/3273.

I am a newbie to this field and would like to learn about it in more depth.


Thanks
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on December 06, 2019, 07:01:49 AM
Can you attach the jpg file or email it to me so I can take a look?  My email is philharvey66 at gmail.com

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Lawdefined on December 11, 2019, 01:45:27 AM
Hi Phil,

I have mailed you the image as an attachment to the email id you provided.

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on December 11, 2019, 07:10:43 AM
I got the sample, thanks.  The extracted RawThermalImage looks perfectly formed.  My guess is that you are executing this in PowerShell, which is known to mess with piped binary files.  Try using cmd.exe instead.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Lawdefined on December 13, 2019, 05:27:13 AM
Hi Phill,

You were right, cmd.exe  solved my problem.

Thanks
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: zarg404 on November 04, 2020, 09:24:08 AM
Hi,

How can I copy all the Exiff tags while extracting the IR layer of a RJPG file ?

exiftool -b -RawThermalImage  test.jpg > a.jpg
With this command, I just copy few EXIF tags to the a.jpg file.

Thank you
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on November 04, 2020, 08:51:10 PM
Run this command after extracting the thermal image:

exiftool -tagsfromfile test.jpg a.jpg

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: zarg404 on November 06, 2020, 06:05:08 AM
Quote from: Phil Harvey on November 04, 2020, 08:51:10 PM
Run this command after extracting the thermal image:

exiftool -tagsfromfile test.jpg a.jpg

- Phil

Thanks
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hmargera on August 14, 2021, 04:58:17 PM
Hi,

I know that the FLIR EmbeddedImage tag is not writable.

I am wondering if there is a way to replace an embedded image by another one in a FLIR file.

Same for replacement of the raw thermal image.

Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: Phil Harvey on August 18, 2021, 08:57:57 AM
I don't know of any software that will do this.

- Phil
Title: Re: enhancement: extract binary data from FLIR radiometric jpg
Post by: hmargera on September 04, 2021, 05:15:05 PM
I was afraid of that answer.

Anyway, thank you for your reply.