Difference visualizing image ImageJ (Bio-Format) and Matlab

7 views (last 30 days)
I have a problem visualizing a stack/multipage tiff file with both ImageJ (Bio-Format plug-in) and MATLAB. In the MATLAB file there seems to be more noise or higher background values compared to the ImageJ image. This is not in the visualization, but the ratio between signal (circles) and background differs between the two images. However, I cannot find if there is something wrong with my MATLAB script in visualizing the images. As I thought it can simply be done with imread (see code below).
Image = '0000127_01_800.TIF';
info = imfinfo('0000127_01_800.TIF');
num_images = numel(info);
for k = 1:num_images
A = imread(Image,k,'Info', info);
B{k} = A
end
Does someone has experience with both ImageJ and MATLAB who can maybe help me to understand this difference?
Thanks!
  8 Comments
Jan
Jan on 16 Mar 2018
Edited: Jan on 16 Mar 2018
@Ihiertje: Please do not let us search your "previous post", but provide a link to it.
The code I have posted does not use any indexing, therefore I cannot guess, where the error message 'index exceeds matrix dimensions' is coming from. Please post the relevant part of your code and the complete error message.
Guillaume
Guillaume on 16 Mar 2018
@Jan, I think lhiertje meant his/her previous comment, the one with the zip file. I too don't see where the error could be coming from.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 15 Mar 2018
Your file is a multipage tiff file (with what looks like 3 levels of magnification of the same image). When you use matlab to open the file, you load the raw pixel data, which renders as you've seen.
On the other hand, the bio-format plugin that you use in ImageJ knows how to use that raw pixel data and the associated metadata (which you can see in matlab by using imfinfo) to convert these raw pixels into the image you see in ImageJ. Without knowing what that process is, it's difficult to reproduce the image in matlab.
However, it would appear that Bio-Formats can also be used directly in matlab. So, follow the instruction and use the plugin in matlab.
  2 Comments
Guillaume
Guillaume on 20 Mar 2018
For information, I got intrigued by this and dug a bit more into it. The image is a standard TIFF file with a fairly rare pixel type of 16-bit float (aka half-precision IEE 754). The bio-format plugin reads that correctly but since matlab does not support half-precision float converts the image to single precision.
Matlab's imread reads that 16-bit float as 16-bit unsigned integer and never warns you that it's the wrong pixel type. In my opinion, that's a matlab bug.
Interestingly, matlab's Tiff class refuses to open the image, telling you (in an obscure way) that 16-bit float is not supported.
If using matlab imread to read the image, the pixels can be correctly decoded and converted to single with the following function:
function halffloatassingle = halffloatdecode(bits)
%halffloatdecode: Decode an array of half-precision floating point numbers encoded as 16-bit unsigned integer into single precision numbers
%author: G.de Sercey
%license: BSD
validateattributes(bits, {'uint16'}, {}, 1);
exponent = single(bitshift(bitand(bits, 31744), -10)); %31744 is 0x7c00, keeps bits 11 to 15
significand = single(bitand(bits, 1023)); %1023 is 0x3ff, keeps bits 1 to 10
signbit = (-1) .^ single(bitget(bits, 16)); %bit 16. sign is applied at the end
halffloatassingle = 2 .^ (exponent - 15) .* (1 + significand ./ 1024); %normalised number decoding
%now deal with inf/nan/denorms
%NaN and Inf both have all bits set on the exponent. Inf has signicand == 0, NaN hasn't. Inf is signed
isnaninf = exponent == 31;
maybeinf = ~significand;
isnan = isnaninf & ~maybeinf;
isinf = isnaninf & maybeinf;
halffloatassingle(isinf) = single(Inf);
halffloatassingle(isnan) = single(NaN);
%denorms have an exponent of 0. In this case the exponent is 2^-14, and the significand does not have the implicit 1 leading bit.
isdenorm = exponent == 0;
halffloatassingle(isdenorm) = single(2^-14) * significand(isdenorm) ./ 1024;
halffloatassingle = signbit .* halffloatassingle; %apply sign in all cases
end
This function is not particularly optimised and only mildly tested.

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!