MATLAB Answers


Reading raw image file of unknown size

Asked by Nour Aburaed on 27 Aug 2018
Latest activity Commented on by Nour Aburaed on 30 Aug 2018
I have the following code for reading a raw image file
if true
[filename, pathname] = uigetfile( ...
{'*.raw'}, ...
'Pick a Satellite Image ');
row=6000; col=9872;
However, this reads only a fixed image size of 6000 x 9872, and not all of my images are of this size. Is there a way to make the code size-independent?


Sign in to comment.

2 Answers

Answer by Walter Roberson
on 27 Aug 2018
 Accepted Answer

No. You cannot read raw image files unless you have some information about either all of the dimensions of the image, or else of all except one of the dimensions (with the remaining being calculated based upon the file size.)
In the particular case where the file size factors into exactly two prime numbers, you can deduce that the two primes are the height and the width, but you cannot tell which is the height and which is the width.
Another issue with raw image files is that they do not give you information about whether the data is stored "down" the columns (MATLAB stores arrays that way) or "across" the rows (very common for images.) For color images, it is also important to know the order of color components, and whether all of the components of each pixel are stored together in the file, or if instead the color panes are separated (MATLAB stores color images with separated color panes in memory.)

  1 Comment

I see. Thank you for the reply.

Sign in to comment.

Answer by Friedrich on 28 Aug 2018
Edited by Friedrich on 29 Aug 2018

If you make some assumptions about the image, there is a way to find the height and width.
1. Image is all grayscale uint8
2. Image has no header, just pure pixel info
3. Image isn't all stripes going up-down or left-right
If these are met, your can get the width by finding the first peak in the self correlation:
[filename, pathname] = uigetfile({'*.raw'},'Pick an Image ');
fid=fopen([pathname filename],'r');
% do a self correlation to find length of lines
fftData = fft(Data);
selfcorr = ifft(fftData .*conj(fftData ));
selfcorr = selfcorr -mean(selfcorr);
% find first peak in self correlation as indicator for length of line
peaks = selfcorr([2:end 1]) - selfcorr;
peaks = peaks([2:end 1]) - peaks;
ispeak = peaks < peaks([2:end 1]) & peaks < peaks([end 1:end-1]) & peaks < peaks(end)/10;
% length of line is considered width
k = numel(Data);
w = find(ispeak,1);
h = k / w;
IMG = reshape(Data,[w h]);
These assumptions don't apply to all *.raw files, as it is a jungle of formats, most including a header. I just deduced these assupmtions from the code you provided. If you have any kind of header, the code won't work.
Edit: two typos in that code, hope it works now. Data is indeed the image data. k should be numel(Data) or length(Data)


Show 1 older comment
I am not sure what k is? Looks like it should be length(I) ?
I edited the code and it should work now.
The error "To RESHAPE the number of elements must not change." probably comes from the peak detection not working properly on that image. If you attach a sample I could check that.
To check yourself you can looks for the first peak manually with
s(1) = subplot(2,1,1);
s(2) = subplot(2,1,2);
You have to zoom in on the left side of the graph and look for the first spike at around the width of the image. You should see a distinctive positive spike in the top plot and a negative spike in the bottom plot.
To improve robustness you can replace the line
w = find(ispeak,1);
with this:
w = find(ispeak,1);
% look for max withing 10 pixels
[~,index] = max(selfcorr(w+(-10:10)));
% use the index as best match
w = w + index - 12;
Thanks for the update. The code shows a blank figure (I cannot attach the sample raw figure, unfortunately)... I am guessing that this means the assumptions do not apply as smoothly as I thought they would, or maybe my images do not meet all the conditions.

Sign in to comment.