LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Help moving from 5.1 to 2016 to graph binary file

Solved!
Go to solution

Hi! Back in 2009 I learned a tiny little bit of LV 5.1 and wrote a simple VI to read an array of ints from a binary file and display it on an intensity graph:

GraphBinaryDTAFile

 

I now need to re-create this functionality in LV 2016, but so much has changed that I don't even know where to begin. The basic functionality I need is this:

  1. Display a file dialog to choose a .DTA file.
  2. Read bytes 9-12 ("x") and bytes 13-16 ("y") to set the array size
    1. (hardcoded to 256 x 256 in the 5.1 example)
    2. Bytes 17-20 "nFrames" would be nice to have for the Z, but that's not essential
  3. Read bytes 65-68 ("dwDataStart") to set the file offset
    1. (hardcoded to 80 in the 5.1 example)
    2. Future file versions may add data between dwDataStart and the actual pixel data, which is why we include dwDataStart
  4. Read in a 2D array of data, starting at dwDataStart
    1. If nType == 1, read int16 data (hardcoded this way in the 5.1 example)
    2. If nType == 0, read float32 data
    3. Should I use Read Binary File or Preallocated Read if I want to run this in a loop where another VI is repeatedly writing new data to a file (w/o a dialog)?
  5. Perform byte swaps or array transpositions if necessary.
  6. Graph!

Can someone help me get started? Thanks!

 

C++-style file format follows, below:

 

 

Spoiler

struct IMGSTRUCT

{

     char Title[8];

     long x;

     long y;

     long nFrames;

     long nType; //0 = float, 1 = word

     long version;

     long lPixelSkip;

     long lLineSkip;

     long numOfBits;

     long lChannels;

     float fPixelPeriod; //in nanoseconds

     float fGain;

     float fOffset;

     long lMTFInfo;

     float fPixelPitch;

     //new items for version 4

     DWORD dwDataStart;//starting offset to the data = IMGSTRUCT

     float fVmin; //minimum input voltage to AD

     float fVmax; //maximum input voltage to AD

     BOOL bCDSenabled; //TRUE if CDS was enabled;

};

 

0 Kudos
Message 1 of 9
(3,311 Views)
Solution
Accepted by topic author TheWaterbug

Hi Waterbug,

 

use the ReadFromBinaryFile function, it supports all you need!

- you can select the datatype you want to read

- you can select how many items to read…

 

Just to give an idea:

check.png

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
Message 2 of 9
(3,260 Views)

Thanks! I was trying to read it in as an array, instead of reading it in as a stream of Singles or U16s and then resizing the array as you've shown. I have it working now!

FloatFileGraphed.jpgIntFileGraphed.jpg

After much trial and error I also figured out how to read the header and use the X, Y, and dwDataStart data to set up the file read and array parameters successfully.

 

There are just 2 features that I'd like to add, but that I can't figure out:

  1. Can I use the File Type parameter to set the Data Type for the 2nd Read Binary File? 
    1. If the type is 0 then I want to read them in as Singles
    2. If the type is 1 then I want to read them in as Int16
    3. Right now I'm manually changing the Representation of the "0" that I'm using for the Data Type input to Read Binary File.
  2. I also have multi-frame image files.
    1. I've read nFrames from the header, but how do pass only the Nth frame to the Intensity graph?
    2. I tried Array Subset to reduce to only 1 frame, but it's still a 3D array, and the Intensity Graph wants a 2D array.
    3. Ideally I'd like to have a slider that goes from 0 to nFrames, with the selected frame being displayed

Thanks!

0 Kudos
Message 3 of 9
(3,232 Views)

Hi waterbug,

 

- use a case structure and have a ReadBinary function in each case

- use IndexArray when you want to index an array element...

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
Message 4 of 9
(3,223 Views)

Partial success! The Case structure worked as expected, and I can now choose either Type 1 or Type 0 files, and both graph properly.

 

I tried using an IndexArray to pick the Nth frame/page from a multi-frame file, but I'm getting garbage. Even a single-frame file displays incorrectly. This is supposed to look like the "Brother holding cat" photo, from above.

GraphNthFrame_Diagram.pngGraphNthFrame.png

The VI is attached, and the binary data file is uploaded, here

0 Kudos
Message 5 of 9
(3,207 Views)

Hi Waterbug,

 

the error is in the ReshapeArray to a 3D array.

Using the known approach to reshape to a 2D array works fine on your example data:

check.png

(Note the subtle changes I made to your VI… 😄 What's the purpose of a single frame flat sequence here?)

 

Do some debugging: try to load a multi-frame file and to find the correct conversion settings…

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
Message 6 of 9
(3,190 Views)

Thanks! Yes, the multiple outputs from the IndexArray really cleans things up.

 

I'm still struggling with the reduction to a single frame. If I read in a multi-frame data file, don't I need to read it in as a 3D array and then extract the Nth page from that? 

 

My goal is to be able to allow the user to page through the frames by fiddling with the Frame # control, without having to reload the file every time. Someday I'd like to actually be able to play them back in a loop, just like a video.

 

I'd put the whole thing in a frame because when I hook this up to the data acquisition system later I'll want to run this continuously in a loop, with another frame triggering the acquisition system to read 1 page of data from hardware and write new data to a file. Someday^2 I'll figure out to pass the data by pointer with a callback (instead of with a file), but that's for much later. 

 

For now I just have to demonstrate rudimentary control and import. And, as you can tell, I know very little about LabVIEW!

0 Kudos
Message 7 of 9
(3,175 Views)
Solution
Accepted by topic author TheWaterbug

Fixed!

 

I had the dimensions wired in the wrong order. Frame, Y, X works:

MultiFrameWorking.png

I'd tried this once before, but I also had the Frame index wrong; it's zero-based, so when I left the default at 1, it didn't work on my single-frame files, which led me to believe that the problem _wasn't_ the index ordering.

 

So I had to fix both errors simultaneously, which took a lot of trial and error.

0 Kudos
Message 8 of 9
(3,152 Views)

Making more progress, here!

 

 MultiFrameWorking3.png

 

I've wired a horizontal Scrollbar to the IndexArray to choose the frame number, and I've put that in an Event structure to update any time the Scrollbar changes value. If you scroll through a 500 frame file (220 MB), the performance is quite reasonable. 

 

But I still have some things I haven't figured out:

  1. The graph updates only when the scrollbar value changes. Is there a way to also trigger a re-draw when the VI is first run, or when a new file (440 kB) is loaded? 
    1. I tried adding the event Select file: Value Change to the handler, but it's one iteration behind (e.g. it triggers display of the previously-selected file; try alternating the file selection while it's running to see what I mean.)
    2. I tried putting the whole display group in a While loop, but that killed the performance.
  2. Is there a way to tie the Scrollbar max value to the Frames output from the first IndexArray? I have it hard-coded at 500 right now, so it wouldn't work for a file containing > 500 frames.
  3. Is there a way to have the Scrollbar synchronized to an editable numeric control, such that the user can either type a Frame number or use the Scrollbar, and they'll both update to show the same value (and both be coerced to the same 0 - Max value)?
  4. Is there a way to make the file browser Pattern case insensitive? I currently have it matching both .dta and .DTA, but in theory someone might have .dTa or .DtA, both of which are perfectly valid. Or do I have to put in all 8 possible CaSe CoMbInAtIoNs?
  5. I'm guessing IntensityGraph isn't really the best type of graph for what is essentially a black-and-white image in a different format. Any recommendations on a better option for displaying this data?
  6. What's the best way to make a "playback" function where the Scrollbar (and therefore the selected frame) will automatically increment from 0 to Max and then start over again?

Many thanks to all who have contributed. It's been a great learning experience!

0 Kudos
Message 9 of 9
(3,082 Views)