LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to use fread and reshape of MATLAB in LabVIEW properly

Hi all: I got a problem to use 2 MATLAB commands in LabVIEW properly: fread and reshape. The example code is as follows:

fi = fopen('c:\temp\test.spe','r');
header = fread(fi,2050,'uint16=>uint16');
Xdim = header(22);
Ydim = header(329);
Zdim = header(724);
Im = fread(fi,inf,'int16=>int16');
fclose(fi);
wh = reshape(double(Im),Xdim,Ydim,Zdim);

You see that the file is binary one. There are many headlines in this file, following by a 3-D array data. I need to get the dimensions for this data (in variable "header"), then read the data (in variable "Im"), and re-arrage the data according to its size (in variable "wh").

I wish someone can give me a direction how to do this in LabVIEW. By the way, I close the file using fclose because of the limit of computer memory. How can I do it in LabVIEW?

Thank you for any of your suggestions.
0 Kudos
Message 1 of 10
(6,217 Views)
If you're asking how to perform the equivalent operation in LabVIEW, you just need to use the "Read Binary File" function in place of the "fread" function. That function accepts how many bytes you want to read, and the data type. You can then use the Array functions "Array Subset" and "Reshape Array" to do the same thing you're doing in the Matlab script. Check the examples that ship with LabVIEW (Help->Find Examples). They show you how to read binary files.

If you're asking about running the script directly in LabVIEW, then I'm not sure what you're specifically asking. Are you using the Matlab Script node? Is it generating an error?
0 Kudos
Message 2 of 10
(6,192 Views)
Dear smercurio_fc:

Thank you very much for your suggestion. I must convert the code to LabVIEW, so I can not use MATHScript.

I used Read from Binary File to replace fread command. However, I got some questions, which is why I post the problem. For the line: fread(fi,2050,'uint16=>uint16'), 2050 uint16 = 4100 bytes = 32800 bits, so should I set 4100 to input of count? I tried, but then I search the output of data, I never get dimentions for X, Y, and Z, like what I got from these lines: Xdim = header(22); Ydim = header(329); Zdim = header(724); Would you please give me more detailed suggestion and see where I am wrong? Thank you again, and thanks to all who come to view my questions.
0 Kudos
Message 3 of 10
(6,179 Views)
The "count" input of the "Read from Binary File" function specifies the number of elements to read, so in your case it should be 2050. You need to wire a constant that is of data type U16 to the "data type" input so you're basically telling the function to read 2050 unsigned 16-bit integers. The output of the function will be an array of U16 values which you can index to get your Xdim, Ydim, and Zdim. The other fread is just reading to the end of the file, but this time it's using signed 16-bit integers (I16).

The number of values it's reading initially doesn't seem to make much sense. Why would you need to read 2050 elements to get to the dimensions? Is there a bunch of other stuff in the file? Seems like an awful lot of wasted space. Can you post an example file that we can take a look at? Please include a description of the data and what to expect.
0 Kudos
Message 4 of 10
(6,169 Views)
Dear smercurio_fc:
 
Thank you very much for your points, and thanks to all who viewed my post. I tried your suggestions, but still got a wrong "image". I attached my code, test.vi, and an example image file, ruler.txt, to show you what I meant. Please notice that to satisfy the rules from the NI website, I changed the file extension name to TXT. The original name should be SPE. So please don't treat it as a real text file.
 
In the block of the code, I also write down the MATLAB code to read and show the image extracted from the image file. The attached image file, test.jpg, is supposed to obtain from the code. I hope you or anyone who can help me figure out what I did incorrectly.
 
Thank you again, and thank you all who come to my post.
Download All
0 Kudos
Message 5 of 10
(6,136 Views)
Your VI was almost right. Based on the data file you needed to specify the byte order to be "little-endian". The default is "big-endian". Also, the datatype for the floating-point read needs to be SGL, not DBL. Since the "Read from Binary File" will read the entire file if you just feed in a path, when you read in the floating points you are actually converting the first 2050 bytes. In Matlab the file pointer stays at the 2050 mark so it only reads the remainder of the file. To do the same thing in LabVIEW you need to perform an "Open File" and then feed the refnum to the "Read from Binary File". You need to make sure that the two read happen one after the other. The easiest way is through the error cluster. I modified your VI and attached it. See if it works for you. Wasn't sure what to expect. Running it on the datafile that you provided I got this:



Message Edited by smercurio_fc on 10-19-2007 05:59 PM

Download All
0 Kudos
Message 6 of 10
(6,134 Views)
Thank you so much! I believe that we are almost there. I tried your suggestion to fix my code as attached, and test it with an image data. The original data is 55MB, too large to upload here. I ran my labview and matlab codes, then received 2 images as attached. The image obtained by matlab is correct one, which should contain some chickens. However, in the labview one, I obtain a very fuzzy one. Can you compare them and see what I did wrong? If possible, tell me how and I can upload or send you the original data. Thank you very much again for your essential help.
Download All
0 Kudos
Message 7 of 10
(6,105 Views)
You have to enforce execution order. This means you have to make sure that the read that gets the index values occurs before the read that gets the data. My version of the VI does that by using the error clusters. In your VI you don't have the error clusters wired, so you don't know which read will occur first.

Also, I had not looked at the actual data in detail so I had overlooked the order that you must use in the Reshape function. You basically have to reverse the order, and you also have to add a Transpose 2D Array to get the same data that Matlab generates. That's because in LabVIEW for a 3D array the first index refers to the "page", which is the third index in Matlab matrices. The Transpose is required because the X and Y are being fed into the Reshape in reverse order.

Attached is an updated VI. The "w2" and "w2 2" indicators on the front panel correspond to the "w2" and the normalized "w2" matrices that are being created in Matlab. Curiously, the "./" function does not work in my version of Matlab (6.5.1). It gives me an error "Error using ==> ./   Function './' is not defined for values of class 'single'.". I just changed the second fread statement to "Im = fread(fi,inf,'float32');" to create "double" arrays rather than "single" in order for the script to not generate an error at that line. Probably just a Matlab version issue.

It's true that you can't upload a file that big to this forum. There are numerous web-based services that will let you upload large files on a temporary basis for those cases when you can't send large files by email. Haven't used any myself, so I don't know what issues are involved with that. See what the updated VI gives you first.

Message 8 of 10
(6,094 Views)
Thank you a lot! It solves my problem. Just for your information: I removed the transpose 2D array function in your code, unclick the transpose array option in the graph format, and click inverse option for Y axis in the graph, then I got the exact image I want. Thank you again for your important help!
0 Kudos
Message 9 of 10
(6,069 Views)
That will work just as well.

Glad you got it working.
0 Kudos
Message 10 of 10
(6,066 Views)