saving a very large image in MATLAB - image

I know that this question has been asked before. But, I could not find a clear answer for it. I have data for a very high resolution colorful image with the size of 50,000 by 60,000 with the data type unit8. I cannot save the entire image by using imwrite. I have gotten the error that says:
"Images must contain fewer than 2^32 - 1 bytes of data"
Is there a way to save the entire image in MATLAB?
right now, I have to break the data into smaller pieces (sub-images) and then use imwrite to write each piece to a png file. The output format of the file is not important.

Your image occupies 8*50000*60000*3 = 7.2000e+10 bytes of data that is 16.7638 times more than MATLAB image size limit. Why no to split it in 20 pieces, save them and then merge them manually? If you split your image into 6 8x50000x3000x3 pieces, they would all fit into 2^32 limit.
I am sure OP has enough aptitude to do this, but I'll explain the procedure anyway. Convert your image into 50000x60000x3 array and do the following:
x = 0:3000:60000;
for i = 1:length(x)-1
imwrite(A(:,x(i)+1:x(i+1),:),strcat('image',num2str(i),'.png'),'png');
end
This would create 20 images for you with names 'image1.png', 'image2.png' and so on. Then, you can merge these images manually using this first google search result. Perhaps, there is some fancier way to do this, but I think this is the easiest one.

Another question has an answer which worked for me: if your image is stored as a double matrix, convert to uint8 with im2uint8(img), then save.

Related

What extra information is stored in a photograph taken by a digital camera?

When I take pictures with my camera the file sizes seem exceedingly large. In this example the original is 5186kb. I wrote a java program to just read the image and then write it again, removing any information except the pixel values.
The first time it is rewritten, the file size goes down to 1005kb, over a 500% reduction! To make sure I wasn't losing data to compression I iterated the program 100 times on the resulting images and the file size stayed at exactly 1005kb with no loss in image quality.
My question is, what is the camera storing in the other 4181kb? Some sort of metadata I know, but it seems like a lot. I would like to know what I am losing by resizing my images like this.
Assuming the file format you are using is .jpg, the original file was saved in a higher value of jpg compression say 95%, while when you resave the file, you probably were using say 85% jpg compression value.
The size doesn't change in consequent saves as the compression value stays the same

Reading voxel values from binary file into matlab

I have a 16bit voxel data set from which I need to extract the integer values for each voxel. The data set can be downloaded from here, it is the 'Head Aneuyrism 16Bits' data set (You need to click on the blood vessels image to download the 16bit version). Its size is 512x512x512, but I don't know whether it is greyscale or color, nor if that matters. Looking at the image on the website I'd guess that it is color, but I am not sure whether the image should be taken literally.
A related question on SO is the following: How can I read in a RAW image in MATLAB?
and the following on mathworks: http://www.mathworks.com/matlabcentral/answers/63311-how-to-read-an-n-dimensioned-matrix-from-a-binary-file
Thanks to the information in the answers to these questions I managed to extract some information from the file with matlab as follows:
fileID=fopen('vertebra16.raw','r');
A=fread(fileID,512*512*512,'int16');
B=reshape(A,[512 512 512]);
I don't need to visualise the image, I only need to have the integer values for each voxel, but I am not sure whether I am reading the information in the correct way with my script.
The only way I found to try and check whether I have the correct voxel values is to visualise B using the following:
implay(B)
Now, with the code above, and then using implay(B) I get a black and white movie with a white disc in the center and black background and some black pixels moving in the disc (I tried to upload a frame of the movie, but it didn't work). Looking at the image on the website from which I downloaded the file, the movie frames I get seem quite different from that image, so I'd conclude that I do not have the correct voxel values.
Here are some questions related to my problem:
Do I need to know whether the image is in grey scale or color to read the voxel values correctly?
On the data set website there is only written that the data set is in 16bit format, so how do I know whether I am dealing with signed or unsigned integers?
In the SO question linked to above they use 'uint8=>uint8'. I could not find this in the matlab manual, so I wonder whether 'uint8=>uint8' is an obsolete matlab notation for 'uint8' or if it does something different. I suspect that it does something different since if I use 'int16=>int16' instead of 'int16' in my code above I get a completely black movie with implay.
It looks like you read the data correctly.
The problem when displaying it is the scale of the values. implay seems to assume the values to be in [0,1] and therefore clamps all values to be in that range, where are your data range is [0,3000].
Simply doing
B = B / max(B(:))
will rescale your data to [0,1] and looking at the data again with
implay(B)
shows you something much more sensible.

Decode image to bitmap ok, but why?

I would like to know why we need to decode let's say a png to a bitmap in order to show the image.
Why not just show the png like that (encoded).
I'm asking here a moron type of question on purpose. It's clear to me it's impossible to show an encoded image just like that but I want to know why, and how an image is shown on a screen because it's easy just to do :
canvas.drawBitmap(((AndroidImage)Image).bitmap, x, y, null);
I want to understand the full of it. I'm guessing we need to show every pixels one by one, but I want more details.
It's easy to know how to do, it's a bit harder to understand why.
If someone has a course/tuto/article/explanation that explains it... I would appreciate
Thanks in advance
PS : Please don't respond "you need to decode/convert png to bitmap" I know that... And that's not my question
There are lots of reasons. There is not really a direct relation between 'a value in a file' and 'a pixel on a screen'.
You need to know the width and height of the bitmap. You cannot infer this from the image size -- it has to be stored somewhere inside the image file. (Or anywhere else. Point is, you have to know its size.)
You need to know the bit depth and color model of the bitmap. You cannot meaningfully copy an 8-bit indexed image directly onto a screen that accepts 32-bit BGR ordering with an unused byte, for example.
Your example, the PNG file format, specifies that all image data is compressed. This is for a sane reason: the PNG format was designed for use on web pages, in a time period where every byte still counted. But even the lowly simple BMP file format uses a very specific form of 'encoding': in its 24-bit format, every line consists of sets of BGR values for each pixel and is padded at the end with enough bytes to make its total length evenly divisible by 4.
JPEG uses an even more advanced encoding scheme (which is too difficult to explain in a few short words) so it can compress images even more. The advanced encoding scheme allows far more compression than regular methods (which in turn means there is only the tiniest relation between 'values in the file' and 'pixels on the screen').

Can pdfbox extract vector images?

As per my understanding,
1. .eps format images are vector images.
2. When we draw something in word (like a flowchart) that is stored
as a vector image.
I am almost sure about the first, not sure about the second. Please correct me if I am wrong.
Assuming this two things, when a latex file (where .eps images are inserted) or a word file (that contains vector images) is converted into pdf, do the images get converted into raster images?
Also, I think PDFBox/xpdf can only extract raster images from the pdf (as they are embedded as XObjects), not vector images. Is that understanding correct? This question in stackoverflow is related, but have not been answered yet.
Your point 1 is incorrect, eps files are PostScript programs, they may contain vector information, or text or image data, or all of the above.
point 2 In PDF there isn't a 'vector image', an image means a bitmap and therefore cannot be vector.
If you convert a PostScript program to a PDF file, then the result depends entirely on the conversion program you use. In general vectors will be retained as vectors, and text as text. However it is entirely possible that an application might render the entire PostScript program and insert the result as an image in the PDF.
So the answer to your first question ("do the images get converted into raster images") is 'maybe, but probably not'.
I'm afraid I have no idea about the capabilities of PDFBox/xpdf, but since collections of vectors may not be arranged as 'images' (they could be held as Form XObjects, or Patterns) in any atomic fashion, there isn't any obvious way to know when to stop extracting. And what format would you store the result in anyway ?

matlab: read subsection of an image

I have a sequence of large images I would like to load into matlab and then apply some processing too. Due to the images size, reading them in takes a long time, and fills the computer memory very fast.
However, I am only interested in the middle section of the images, a region of about 100 by 100 pixels or so.
Is there a way to only read in that section of the image, therefore saving time, and memory?
Currently I am using:
ROIx = 450:550;
ROIy = 650:750;
image = double( imread( filename ) );
image = image(ROIx, ROIy);
However, imread() loads the whole image, and this takes a long time. Is there a way only to read the part I am interested in?
(One procedure would be to go through and crop each image into a smaller one and resave it. But I would prefer not to crop the images).
Thanks,
labjunky
Matlab 2012a indicates that you can read parts of images from JPEG2000 and TIFF images. Look at the documentation for imread, inspect the option 'PixelRegion' for reading TIFFs.
You will need to use something like fopen to open the file and read the contents in parts manually. You will need to take care of lot of encoding/decoding of course. Or the other way round a little more would be to increase your system's swap space. If you are getting out of memory errors.

Resources