LJMUAstroecology / flirpy

Python library to interact with FLIR camera cores
Other
191 stars 54 forks source link

Convert sequence to raw failling #28

Closed MuriloHMoreira closed 3 years ago

MuriloHMoreira commented 3 years ago

Dear all, Congrats for the great software! I was trying to use the split_sec.py file to convert a sequence made by a Flir T640. I am facing the following problem:

  File "split_seq.py", line 111, in <module>
    folders = splitter.process(files)
  File "/home/murilo/anaconda3/lib/python3.7/site-packages/flirpy/io/seq.py", line 79, in process
    self._process_seq(seq, folder)
  File "/home/murilo/anaconda3/lib/python3.7/site-packages/flirpy/io/seq.py", line 200, in _process_seq
    image = frame.get_radiometric_image(meta)
  File "/home/murilo/anaconda3/lib/python3.7/site-packages/flirpy/io/fff.py", line 49, in get_radiometric_image
    image = raw2temp(self.get_image(), meta)
  File "/home/murilo/anaconda3/lib/python3.7/site-packages/flirpy/io/fff.py", line 56, in get_image
    offset = self._find_data_offset(self.data)
  File "/home/murilo/anaconda3/lib/python3.7/site-packages/flirpy/io/fff.py", line 46, in _find_data_offset
    return res.end()+14
AttributeError: 'NoneType' object has no attribute 'end'

I could not find many information of what could be wrong. It even converts the first frame correctly to .fff and .txt. I would love to have any tip, such as what is this offset and if I can find it in any other way. Thank you very much! Murilo

jveitchmichaelis commented 3 years ago

It's possible that there's some difference between the FLIR Duo and the T640 that's causing trouble (I've never used one of those before). Can you upload the first frame, if it's not sensitive? (or capture a dummy image with the lens cap on or something)

https://github.com/LJMUAstroecology/flirpy/blob/9be3ee71d04fc309b0b7ebff70204c165526409a/flirpy/io/fff.py#L37

EDIT: Being daft here, flirpy actually looks for two magic numbers which are: (height-1) and (width-1)

MuriloHMoreira commented 3 years ago

Wow, thank you very much for the fast response! That makes sense, if I manage to find the magic number I will comment on this issue! And sure I can upload the first frame fff. You can find it in this link. Thank you very much! Murilo

MuriloHMoreira commented 3 years ago

And sorry bothering you again, but how could I search manually for this bit? Thanks, Murilo

jveitchmichaelis commented 3 years ago

Ok so there's a massive header and what looks like some telemetry at the bottom:

image

That's just from loading the file as a 16-bit array and thjen plotting it as a 640-wide image.

MuriloHMoreira commented 3 years ago

Great, that is the image indeed!

jveitchmichaelis commented 3 years ago

The trick then is to figure out what bytes just precede the image, and search for those. Usually there's something that will indicate the frame start.

Here you can see probably the frame size:

image

Those highlighted bytes are "480" and the adjacent ones are "640". The difficulty is making this work for all FFF files and not just my or your camera. I might see if there's a bug somewhere in the FFF reader.

jveitchmichaelis commented 3 years ago

Oh sorry, this is a really simple solution. You need to specify the frame size when you load the image.

Python 3.7.7 (default, Mar 26 2020, 15:48:22) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from flirpy.io.fff import Fff
>>> a = Fff("frame_000000.fff"),
KeyboardInterrupt
>>> a = Fff("frame_000000.fff", height=480, width=640)
>>> a.
a.data                    a.exiftool                a.filename                a.get_gps(                a.get_image(              a.get_radiometric_image(  a.height                  a.image                   a.width                   a.write(
>>> a.get_image()
array([[6209, 6220, 6213, ..., 6213, 6213, 6186],
       [6209, 6219, 6222, ..., 6214, 6211, 6205],
       [6216, 6209, 6201, ..., 6224, 6211, 6212],
       ...,
       [6211, 6191, 6211, ..., 6201, 6193, 6199],
       [6211, 6201, 6205, ..., 6192, 6193, 6201],
       [6210, 6207, 6205, ..., 6192, 6193, 6199]], dtype=uint16)
>>> 
MuriloHMoreira commented 3 years ago

Ok! So if I understand it right, somewhere after or before the bytes that define the frame size, is the offset that the FFF reader could not find. And for my own case I should search for it and I can harcode to the FFF module on my local system. However, this would not solve the problem for users of different cameras. Hum, if I am able to find this offset byte I can share within this issue and maybe a comment in the readme could help people with different cameras on how to fix this. Did I get it right? Thanks! Murilo

jveitchmichaelis commented 3 years ago

See above :)

MuriloHMoreira commented 3 years ago

You are right! Thanks!

jveitchmichaelis commented 3 years ago

But at least now you know how Flirpy does it - we search for two numbers that are the image width-1 and height-1, then the image starts at some offset from there. That should work with split_seqs if you pass in --width and --height!

Hope that helps, it's been a long day haha :)

MuriloHMoreira commented 3 years ago

Great, Nice software, nice help, very didactic and willing to help, I wish you a lot of success! All the best, Murilo

jveitchmichaelis commented 3 years ago

No problem - best of luck with your research!

I've updated the readme: https://github.com/LJMUAstroecology/flirpy/commit/94ac632fe3654814be49719264bb2a6524188f2c and defaults are highlighted https://github.com/LJMUAstroecology/flirpy/commit/dfc0cc903b9218de90bbfc8663a553ab79d65839

Ikhwansong commented 3 years ago

Really! thanks!

This is simple example code to run in the folder (scripts) python split_seqs -o ../results -i ../seq/test_vid.seq --width 640 --height 480

It works!

Ikhwansong commented 3 years ago

In my case, below code caused an TypeError: a = Fff("frame_000000.fff", height=480, width=640)

TypeError: init() got an unexpected keyword argument 'height'

What is the problem?

jveitchmichaelis commented 3 years ago

@lkhwansong In the newer versions of the code height/width were removed, so just try a = Fff("frame_000000.fff") - flirpy should be able to determine the image shape directly now.

(Copied this to your issue)