How can I use low-level functions (not imread) to read a grayscale image? - 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.

Related

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

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.

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.

Saving RGB Images in CUDA

I have an rgb image data in the first 3 channels of a uchar4 array. Is there a function that I can utilize in CUDA libraries in order to save this uchar4 format as an RGB image, or is there another way for saving RGB images in CUDA?
Saving RGB image data to a file does not involve CUDA. You use CUDA to process your data in whichever way you desire.
Once that is done and you have achieved a result, copy your RGB data back to the host and save it. You can basically pick whatever your favorite routine/library is to save RGB data to a file. Boost.GIL as recommended by Roger Dahl does seem to be a nice option indeed.
As such, there is no particular functionality within CUDA that allows you to save your image data to a file.

Can I edit the thumbnail image inside JFIF files?

Can I edit the thumbnail image inside JPG/JFIF files?
If this is possible--how so (using what utility)?
The end result needs to be that the thumbnail image "can" be a wholly different image than the jpeg.
Thank you much,
Michael
Typically, thumbnails are uncompressed RGB data. You locate the marker, see where the thumbnail's width/height are marked, then modify the byte stream following it. the stream is of length width*height*3 bytes.
If it's indexed, you'd have to overwrite the palette and the index entries. Just look for the APP0 marker, start modifying it.
A compliant EXIF thumbnail image must fit in the 64K APP1 marker and is usually compressed as JPEG (unlike what #Karthik says). The thumbnail image is independent of the main image and can easily be changed since it is inside a marker segment that doesn't affect the main image. The JPEG marker segments are basically a linked list of independent binary blobs with 2-byte identifiers (e.g. FFE1 in this case) and 2-byte lengths. You can swap out one for another and you won't "break" the file. There is no checksum or other mechanism that verifies the entire file data integrity. I'm not familiar with libraries to edit this information, but you can do it in a small amount of code that only has to parse the marker blobs type and length without knowing their contents. You can also do it the "quick and dirty" way by ensuring that your new thumbnail is no larger than the original and then you can just write it in it's place without moving the other parts of the file around. The marker length is not checked against its contents, so unused space is ignored.

Resources