reading binary files in matlab
32 views (last 30 days)
Show older comments
I have to read some Binary files in matlab , I have used following codes to open file
fid=fopen('stagc_ps_fg.b','r')
[data,count]=fread(fid 'int16')
fclose(fid)
I can see only some data values , but I do not know how to see meta data information.
is there any other way to check metadata or data information?
0 Comments
Answers (3)
Image Analyst
on 5 Oct 2011
You have to know the format. For example, usually the first two bytes are two letters that represent the file format, like BM or something. You'd be getting 'B' into data(1) and 'M' into data(2) and you'd have to reconstruct it. If you knew the format in advance, you could write a bunch of freads, each with the proper format string to get you the metadata right away.
2 Comments
Walter Roberson
on 5 Oct 2011
You first need to determine exactly how many bytes are occupied by scalar INTEGER and REAL(kc) variables; what byte ordering convention is being used by the writing system; and you would need external information about what values im, jm, lm, and ntrace have as those are not written in to the file.
The code appears to be Fortran, and I believe REAL(kc) in Fortran means "REAL variables of width kc bytes". If that is correct, then you would also need to know what kc is before you could decode. If kc happens to be 4, then you would additionally need to know _which_ Single Precision Floating Point representation was being used -- certainly it might be IEEE-754 but it is not safe to assume that as there have been a number of different single-precision semi-standards in practical use. If kc is 8, it is very likely that IEEE 754 Double Precision is intended, as that was standardized early on. If kc is 10 or 12, we could guess Intel 80 bit double precision floating point format (which is not _supposed_ to be written to file, but it happens.) If kc is 16, then it is "quad precision", which a number of fortran compilers implement but which there is no standard for, but the internal format is at least likely to be documented on the source machine. If kc is any other value, you are going to have a nasty time trying to interpret the files.
Do you have control over the file format? Could you edit the statements that write the file out? Because if you can, then we could come up with a better file format.
Walter Roberson
on 5 Oct 2011
Binary files do not inherently have metadata information.
Binary files written for a particular purpose might include data that can be interpreted as metadata for the purpose of the program. There is no standard or commonly-used metadata format. You have to know what the file is for and hope that whatever metadata might exist is in a well-documented format.
Are you perchance working with one of the standard image formats such as JPEG or TIFF ? Those do have a well defined and documented metadata format.
You should adopt the working premise that a "binary file" is completely unstructured nonsense until proven otherwise.
0 Comments
Image Analyst
on 5 Oct 2011
Perhaps this code might help you. It reads in a particular type of raw file format that we use. It should be easy for you to adapt to your format. You should put in "try catch" for robustness - sorry I didn't have it in this m-file since I assumed that it will always be guaranteed to work for us. After you read in the header, you just suck up all the bytes after that into a 2D array directly (it doesn't have to be a 1D array that you then have to reshape).
% Read_RAW_Header
% Returns the image header information and some extra information
% for any "raw" image files.
% Usage: stHeader = Read_RAW_Header(filename)
% Input
% filename - RAW format file name
% Output
% stHeader - header structure containing information on the data
% Header is 44 bytes.
% The header of an RAW file will look something like this:
% stHeader.TotalVoxels: Array size - total size of the array (not the whole file) - number of voxels.
% stHeader.NumberOfDimensions: Number of dimensions - 3 for a 3D image.
% stHeader.x_size: Size (number of voxels) in the X direction.
% stHeader.y_size: Size (number of voxels) in the Y direction.
% stHeader.z_size: Size (number of voxels) in the Z direction.
% stHeader.XStart: Position of the center of the first pixel in the X direction - it's 0.
% stHeader.YStart: Position of the center of the first pixel in the Y direction - it's 0.
% stHeader.ZStart: Position of the center of the first pixel in the Z direction - it's 0.
% stHeader.XEnd: Position of the center of the last pixel in the X direction - it's voxelWidth * (sizeX - 1).
% stHeader.Yend: Position of the center of the last pixel in the Y direction - it's voxelWidth * (sizeY - 1).
% stHeader.ZEnd: Position of the center of the last pixel in the Z direction - it's voxelWidth * (sizeZ - 1).
% Following the header in the data file, are the voxel values, but of course we do not return these in the header.
%
% I also add these fields to the returned header argument:
% stHeader.HeaderSize = 44;
% stHeader.BytesPerVoxel
% stHeader.FileSizeInBytes
% stHeader.DataSizeInBytes
% stHeader.Endian
% stHeader.EndianArg
%
% Example usage:
% fullFileName_RAW = fullfile(cd, 'SimulatedData_Distance.RAW')
% stHeader = Read_RAW_Header(fullFileName_RAW)
%
%------------------------------------------------------------------------------
function stHeader = Read_RAW_Header(fullFilename)
% Check syntax. Must have at least one input argument, the full filename.
if (nargin ~= 1)
error('Usage: stHeader = Read_RAW_Header(fullFilename)');
end
if (ischar(fullFilename)~=1)
error('Requires a string filename as an argument.');
end
% These aren't in the header specification for this type of file,
% but other formats use it and it's a useful thing to add to the header.
stHeader.Endian = 'Big';
stHeader.EndianArg = 'ieee-be';
% Open the file for reading.
fileHandleID = fopen(fullFilename, 'rb', stHeader.EndianArg);
if (fileHandleID == -1)
error(['Error opening ', fullFilename, ' for input.']);
end
% Go to the beginning of the file.
% Shouldn't be necessary, but can't hurt.
fseek(fileHandleID, 0, 'bof');
% Read the total number of voxels in the image.
% Read bytes 1-4.
stHeader.TotalVoxels = fread(fileHandleID, 1, '*int32');
% Note: this may be unreliable, and can be zero!
% Better to take the x, y, and z sizes and multiply them together.
% The next 4 bytes are the number of dimensions - 2 or 3.
% Read bytes 5-8.
stHeader.NumberOfDimensions = fread(fileHandleID, 1, 'int32');
% Read in the dimensions for the different directions.
% They'll be in bytes 9-20.
stHeader.x_size = fread(fileHandleID, 1, '*int32');
stHeader.y_size = fread(fileHandleID, 1, '*int32');
stHeader.z_size = fread(fileHandleID, 1, '*int32');
stHeader.TotalVoxels = stHeader.x_size * stHeader.y_size * stHeader.z_size;
% Read in the position of the center of the first pixel.
% They'll be in bytes 21-32.
stHeader.XStart = fread(fileHandleID, 1, '*float');
stHeader.YStart = fread(fileHandleID, 1, '*float');
stHeader.ZStart = fread(fileHandleID, 1, '*float');
% Read in the position of the center of the last pixel.
% They'll be in bytes 33-44.
stHeader.XFieldOfView = fread(fileHandleID, 1, '*float');
stHeader.YFieldOfView = fread(fileHandleID, 1, '*float');
stHeader.ZFieldOfView = fread(fileHandleID, 1, '*float');
% Note: the fields of view are based on (pixel center) - to - (pixel center).
% Calculate the voxel width.
stHeader.VoxelWidth = stHeader.XFieldOfView / single(stHeader.x_size - 1);
% Assign some other useful information.
% It's not in the header but may come in useful anyway.
% Assign the bytes per voxel.
%fileInfo = imfinfo(fullFilename); % Note: doesn't work!
% fileSizeInBytes = fileInfo.FileSize;
% This works:
fileInfo = dir(fullFilename);
% MATLAB returns the information in a structure with fields:
% name
% date
% bytes
% isdir
% datenum
stHeader.HeaderSize = 44;
fileSizeInBytes = fileInfo.bytes;
dataSizeInBytes = double(fileSizeInBytes) - double(stHeader.HeaderSize);
stHeader.BytesPerVoxel = int32(round(dataSizeInBytes / double(stHeader.TotalVoxels)));
stHeader.FileSizeInBytes = fileSizeInBytes;
stHeader.DataSizeInBytes = dataSizeInBytes;
% Close the file.
fclose(fileHandleID); % Close the file.
5 Comments
Betty
on 19 Dec 2011
I am dealing with satellite imagery can read have a binary file of image data. I can read the file correctly using fread, so have it in a 2d array called a. How do I display the image. I tried
imshow(a)
but I got the following:
Warning: Image is too big to fit on screen; displaying at
33%
> In imuitools/private/initSize at 72
In imshow at 259
A new window came up, but no image was displayed.
I then tried:
imshow(a(1:100,1:100))
and a smaller window popped up, but still nothing in it. No warning that time though.
I think my fundamental question as a newbie to image processing in matlab is: do I have to convert my array to some sort of "image" format for matlab to understand how to display it and perform other image processing functions on it?
Thanks!
Walter Roberson
on 19 Dec 2011
imshow(a(1:100,1:100), [])
or,
imagesc(a(1:100,1:100))
You do NOT need to convert your array to any kind of "image" format: a plain array of values is fine. You do need to be aware, though, that if the values are close together, then by default imshow() will show it as a single color or a narrow range of colors. imagesc() by itself, or imshow() with [] as a second parameter, will determine the minimum and maximum values in the array and will rescale the data so that it uses the entire current color map.
See Also
Categories
Find more on Data Type Conversion in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!