Login  Register

ImageJ reads reversed bits from unsigned 16-bit TIFF saved by imwrite() from GNU Octave.

Posted by Pariksheet Nanda on Nov 03, 2014; 11:05am
URL: http://imagej.273.s1.nabble.com/ImageJ-reads-reversed-bits-from-unsigned-16-bit-TIFF-saved-by-imwrite-from-GNU-Octave-tp5010285.html

Hi all,

ImageJ shows pixel values different from those saved by GNU Octave.
The byte positions are the same, the bits within each byte are
reversed, so I'm not sure if this is a traditional problem of
endianness?  For example the value 274 saved from the Octave matrix
appears as 32480 in ImageJ; the binary representations of which are
below:

Number saved by Octave (decimal 274):  01001000 10000000
Number read by ImageJ (decimal 32840): 00010010 00000001

1) Can anyone else reproduce this problem?  At the end of this e-mail
is the code for Octave to generate the image stacks, and an ImageJ
macro that reads the value of each slice (or frame), and shows the
binary and expected values in the results window.  Also the image
stacks from Octave are uploaded here and compressed to 7 kb; password
is imagej
https://filelocker.uconn.edu/public_download?shareId=2c8c0c3141741de36547a9db46b1f06c

2) Can you help me identify where the problem might be coming from?
GNU Octave has a wrapper for ImageMagick C++ interface, which in turn
uses libtiff.  Perhaps the next logical thing would be to inspect the
binary values from the TIFF file or check the TIFF file headers, etc
but I'm not sure how to approach those investigations.  My application
and library versions are:

- ImageJ 1.49i (bundled with FIJI linux-32)
- Octave 3.8.2
- ImageMagick 6.8.8.10
- libtiff 4.0.3

3) Are there any Octave + ImageJ users out there?  How do you export
images from Octave for ImageJ?  Also do you interface Octave data with
ImageJ / FIJI using the Java Octave Forge package?

Best wishes,
Pariksheet



%%%%%%%%%%
%% ImageJ does not open TIFF images saved by GNU Octave
%% properly. While the endianness is the same, the bits are reversed.So
%% within each byte one has to reverse the bits to view the image in
%% ImageJ correctly. E.g.:
%%
%% Saved by Octave (decimal 274):  01001000 10000000
%%
%% Read by ImageJ (decimal 32840): 00010010 00000001
%%
%% This program demonstrates the problem and workaround.

%% Create image frames with each frame containing uniform values of 0,
%% 1, 2, etc.
im = 0:2^9-1;

function im_save (x, path)
  %% Reshape to Multi-TIFF image.
  w = 1;
  h = 1;
  %% Multi-tiff needs a special third dimension.
  [GREY, RGB, RGBA] = {1, 3, 4}{:};
  im = reshape (x, w, h, GREY, numel(x));
  imwrite (uint16 (im), path, 'Quality', 100);
endfunction

function y = reverse_uint16 (x)
  %% Reverse bits for ImageJ.  Algorithm from:
  %% http://eshare.stust.edu.tw/EshareFile/2012_5/2012_5_516c9900.pdf
  bits = 16;
  b = uint32 (2^(bits-1));
  y = uint32 (zeros (size (x)));
  for i = 1:bits
    y = bitget (x, i) * b + y;
    b = b / 2;
  end
  y = uint16(y);
endfunction

%% Bad image.
im_save (im, '/tmp/bad.tif');

%% Workaround.
im_rev = reverse_uint16 (im);
im_rev = swapbytes (im_rev);
im_save (im_rev, '/tmp/good.tif');


//////////
// Compare the image values intended to be saved by GNU Octave
// against values read by ImageJ.

for (i = 0; i < nSlices; i++) {
    setSlice(i + 1);
    setResult("Octave Value", i, i);
    getStatistics(area, mean, min, max, std, histogram);
    setResult("ImageJ Value", i, mean);
    setResult("Octave Binary Value", i, toBinary(i));
    setResult("ImageJ Binary Value", i, toBinary(mean));
}

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html