Read a single image to Matlab from a Tiffstack without loading the entire stack - image

I need to read images from a large stack of Tiff files while the stack is being updated with additional images. I don't wanna load the stack multiple times for performance issues. Is there a trick do read a single image at a time in Matlab?

You can use the Tiff class in Matlab to manipulate a multi-tiff file, i.e. a single tiff file containing many tiff images. Please note that I'm no expert in this regard, but when I first encountered this I was completely lost and after some fooling around with it I could get it to work so I hope it will help you. This should hopefully get you started; and you can easily put this in a loop to select multiple frames form your stack.
In the following code, TiffName refers to the name of your multi-tiff file.
%// Set up Tiff object in 'read' mode
Stack_TiffObject = Tiff(TiffName,'r');
%// Frame you wish to read
FrameToRead = 4;
%// Use setDirectory method to access the image in the stack
Stack_TiffObject.setDirectory(FrameToRead)
%// Read image data
YourImage = Stack_TiffObject.read();
%// Close the Tiff object when you're done
Stack_TiffObject().close
Unless I missed something completely obvious that should load only selected frames from your stack.

Related

Octave, display image received by socket connection does't show

I have an octave script in which i open a socket server an receive some commands from connected clients. This already works. Now i need to send data to Octave, mostly images and process them. To test this i wanted to receive and display a grayscale test image.
bufflen = 4096;
[data,count]=recv(b,bufflen);
imshow (data)
the image window opens but it is empty. The size of data is exactly the size of the image file i am sending. I also tried saving the image with
imwrite (data, "test.jpg");
this produced a file but every line of the image was in one long line. When i open the image with
imshow test.jpg
everything works as it should, the image window appears and shows the image.
I am sending the data via netcat with
>ncat.exe 127.0.0.1 12346 < test.jpg
this seems to work, i was able to transfer the image to another pc and view it there.
Every hint or tip is greatly appreciated, thank you.
You are sending your jpeg as byte stream (ncat.exe 127.0.0.1 12346 < test.jpg) but you are trying to show is with imshow as it would be an uncompressed RGB, grayscale or index image. You can receive it and save it to a tempfile and then load it with imread. In this case graphics/image-magick will do the uncompression from JPE to RGB to you.
Guessing here since you didn't provide much information, but it sounds like you're data is coming as a vector and you need to reshape it into an array for imshow
>> newdata = reshape(data, 64, 64)
You haven't shown us an example of the input data, so it is also possible that your data is a string of characters, while image arrays need to be numerical values. To verify before reshaping you could run:
>> class(data)
If so you will need to convert it to an array of numerical values. You can use str2num for that, but exactly how to do so will depend on what the string looks like, are there value separators, etc.
See:
https://www.gnu.org/software/octave/doc/interpreter/String-Conversions.html

How can I use low-level functions (not imread) to read a grayscale image?

I'm trying to use low-level functions (fopen and fread) to read a grayscale image of type uint16 in TIFF format as follows:
fid = fopen(filepath,'r');
img = fread(fid,[ncolms, nrows], 'uint16=>uint16')';
The obtained image matrix is different from that obtained by simply using imread:
img = imread(filepath);
The resulting images are shown below (the left is by fread and the right is by imread):
In addition to the obvious intensity difference, one may also note that fread image has some artifacts in the top edge of image. I think this must be due to their different mechanisms of reading images.
I want to know how to use such low-level functions as fopen and fread to read images (grayscale, not binary), equivalently to using imread, if they can.
Those "artifacts" you're seeing are likely the header and tag data stored in the file before the image data. I would suggest taking a look at this TIFF File Format Summary. It will tell you exactly how to read all this extra information, if you really want to do it yourself. Note that some of this extra tag information (i.e. ImageHeight, ImageWidth, BitsPerSample, SamplesPerPixel, etc.) will be useful in determining exactly how to read the image data correctly, and thus match the image you get from the imread function.

EXIF and thumbnails

I'm working on a photo viewer. In this context, I wrote a small class to be able to read and use some EXIF data, as e.g. image orientation. This class works well for reading.
However, I would add a new option to rotate photos. I want to rotate and write the photo data itself, not just rewrite the orientation tag. I already wrote the code to rotate and save the primary JPEG image, and it works well. But I also need to rotate the thumbnail contained in the EXIF data, if any, to keep the image coherent. For this reason I need to write in the EXIF data, to replace the existing thumbnail.
But this raises some questions, that I've some trouble answering, namely:
Can the EXIF data contains more than 1 thumbnail, and if yes, what is the maximum thumbnail count that an image can contain?
What are the supported formats for thumbnails? (I found JPEG and TIFF, are there other?)
Is there any guarantee in the EXIF standards that the thumbnails are always written in the late EXIF data, just before the primary image?
If not, then each tags containing an offset that points to a location beyond the thumbnail to replace should be updated. So, is there a standard way to iterate through all tags and sub-directories, to recognize which EXIF tags contain offsets, and to update them if needed? Or the only way is to read a maximum of tags and rewrite only that are known?
Or is there a way to guarantee that the size of the newly rotated thumbnail will be smaller or equal to previous thumbnail size to replace with?
Regards
Here are some answers for your questions:
1) The EXIF data is laid out like a TIFF file with 2 pages. The first page is the camera information and the second page is the thumbnail. If you add more pages (with thumbnails), 99.99% of the applications probably won't notice since you'll be doing it differently than the "standard" way. As far as "maximum count", you have 64k of data that can be stored in any JFIF tag. You can put what you want in that 64k.
2) There is only 1 supported EXIF thumbnail format: TIFF. Inside the TIFF there can be compressed (JPEG) or uncompressed data. Again, you're welcome to stick LZW-compressed data in there, but most apps probably won't be prepared to display it properly.
3) The JFIF container format allows for tags with metadata to appear before the main image. The APPx tags contain metadata that can follow the standard or not. You're welcome to stick multiple EXIF APP1 tags into your files, but again, most apps won't be able to properly handle that situation. So the simple answer is that the EXIF data (including thumbnail) must come before the main image and if you put more than 1 thumbnail it will most likely be ignored.
4) If you are modifying a JFIF (including the metadata), you must rewrite the metadata. It's actually quite simple because each tag is independent and has a simple length value instead of relative offsets.
5) You can do anything you want with the size/orientation of your thumbnail as long as you make the EXIF APP1 tag data total size fit within 64k.
Here's what you need to do...
1) Read the source image (and thumbnail if present).
2) Prepare your rotated image (and thumbnail).
3) Write the new metadata with the new thumbnail image.
4) Write the new main image.
If you want to preserve the original metadata along with your new thumbnail, it's pretty easy. Just read the original tags and hold on to them, then write them in the new image. Each JFIF tag is just a 2 byte identifier (FFxx) followed by a 2 byte length and then the data. They can be packed in almost any order and there's no hard limit on how many total tags can appear before the main image.

Save uint16 tiff image as truecolor with Matlab

I am processing microscopy images (in Matlab) in the tiff format, normally uint8 or uint16. Basically I read them, put them in a cell array for processing and then export them in the tiff format either as an image sequence or a stack (using imwrite and either the 'overwrite' or 'append' writemode property of imwrite, respectively). Up to now everything works very well.
The problem I'm having is the following:
When I open the images with ImageJ, they are not in truecolor "RGB" color mode, but rather in composite mode. For example ImageJ reads the data as 8 bit, which it is, but does not open the image as a truecolor (Sorry for the bad choice of words I don't know the right terminology). Hence I have to manually combine the 3 channels together, which is bothersome for large datasets.
Here is a screen shot explaining. On the left is what I would like,i.e. what I obtain if I open the image directly with ImageJ, and on the right is what I currently have after saving images with Matlab and opening them with ImageJ, which I don't want.
The code I'm using to export the image sequence is the following. "FinalSequenceToExport" is the cell array containing the images.
for i = 1:SliceNumber
ExportedName = sprintf('%s%s%d.tiff',fileName,'Z',i);
imwrite(FinalSequenceToExport{i},ExportedName,'tif','WriteMode','overwrite','Compression','none');
end
If I ask Matlab the size of FinalSequenceToExport{1}, for instance, it gives 512 x 512 x 3.
If I open a given image in the command window and then save it with the same code as above, it does what I want and the resulting image opens as I want in ImageJ. Hence my guess would be that the problem arises from the use of the cell array but I don't understand how.
I hope I've been clear enough. If not please ask for more details.
Thanks for the help!
You need to specify the the 'ColorSpace'
Try this
imwrite(FinalSequenceToExport{i},ExportedName,...
'tif','WriteMode','overwrite','Compression','none', ...
'ColorSpace', 'rgb');
After revisiting this question I found the following to work, thanks to the hint from #Ashish:
imwrite(uint8(FinalSequenceToExport{i}/255),...);
I just needed to divide by 255 after converting to uint8.

gray levels are changed after using imsave function

I used these codes to produce an RGB image with gray levels between 50 and 170.
a='C:\Users\sepideh\Desktop\IP_abadpour\S45C-113050518040.jpg';
b=imread(a);
b=b+50;
b(b>170)=170;
and you'll see when I call functions max and min, it is proved that the gray levels are between 50 and 170.
max(max(max(b)))
ans =
170
min(min(min(b)))
ans =
50
then I used imshow and imsave functions to save the image with the name "50to170"
c=imshow(b);
d=imsave(c);
Now I read the written image in this way:
a='C:\Users\sepideh\Desktop\IP_abadpour\50to170.jpg';
b=imread(a);
This time when I call max and min functions,I see:
max(max(max(b)))
ans =
235
min(min(min(b)))
ans =
16
I mean it seems that gray levels have been changed after using imshow and imsave functions!
Why does it happen?
Is it because of the format (.jpg) that I'm using when employing imsave function?
Instead of using imsave, use imwrite
b=imread(a);
b=b+50;
b(b>170)=170;
imwrite(b,'50to170.png','png')
Notice that I am saving it as a png file instead of a jpg to prevent compression. Bitmap also saves it without compression.
This method is a more direct way to save raw image matrices than using imshow and imsave.
If you want the same functionality of imsave (selecting where the file goes) check out "uiputfile" to get file name and location.
I tested it.
1.First of all you can't use imsave(b) because the function imsave expects its first input argument to be a valid handle to a single graphics object.So first you should show the image in form c=imshow(b) and then use c as an input for function imsave.
2.If you want to save the image without showing it first use function "imwrite" and pass b as the first input argument to it.
Note that if you don't want gray levels be changed after saving, you should use 'bmp' as the save format not 'jpg'.
Because 'jpg' does not support indexed images and "imwrite" converts indexed images to RGB before writing data to JPEG files so the gray levels might be changed.It's not related to the contrast stretching when showing the image in matlab.It's related to the format used to save the image.

Resources