I am trying to write a single multipage tiff file which is 128 pixels x 128 pixels x 122000 frames of 16-bit unsigned integers. ImageJ or a short Python script can do this in less than one minute on a fast machine. On the same machine, MATLAB would likely take days to do so using any method I have tried. Here is what I have tried so far:
Use imwrite to write IMG to test.tif (recommended by MATLAB documentation)
tic
numframes=size(IMG,3);
divider=10^(floor(log10(numframes))-1);
imwrite(IMG(:,:,1),'test.tif');
for i=2:numframes;
imwrite(IMG(:,:,i),'test.tif','WriteMode','append');
if (round(i/divider)==i/divider)
fprintf('Frame %d written in %.0f seconds, %2d percent complete, time left=%.0f seconds \n', ...
i, toc, i/numframes*100, (numframes - i)/(i/toc));
end
end
which results in the following output:
Frame 10000 written in 104 seconds, 8.196721e+00 percent complete, time left=1163 seconds Frame 20000 written in 296 seconds, 1.639344e+01 percent complete, time left=1509 seconds Frame 30000 written in 590 seconds, 2.459016e+01 percent complete, time left=1809 seconds Frame 40000 written in 1035 seconds, 3.278689e+01 percent complete, time left=2121 seconds Frame 50000 written in 1682 seconds, 4.098361e+01 percent complete, time left=2421 seconds
Notice the exponential increase in time as more frames are written.
Use the Tiff class directly
if bigtiff
t = Tiff(fname,'w8');
else
t = Tiff(fname,'w');
end
tagstruct.ImageLength = size(image,1);
tagstruct.ImageWidth = size(image,2);
tagstruct.Photometric = Tiff.Photometric.MinIsBlack;
if bitspersamp==16
tagstruct.BitsPerSample = 16;
end
if bitspersamp==32
tagstruct.BitsPerSample = 32;
end
tagstruct.SamplesPerPixel = 1;
tagstruct.RowsPerStrip = 256;
tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
tagstruct.Software = 'MATLAB';
t.setTag(tagstruct);
t.write(image(:,:,1));
numframes = size(image,3);
divider = 10^(floor(log10(numframes))-1);
tic
for i=2:numframes
t.writeDirectory();
t.setTag(tagstruct);
t.write(image(:,:,i));
if (round(i/divider)==i/divider)
fprintf('Frame %d written in %.0f seconds, %2d percent complete, time left=%.0f seconds \n', ...
i, toc, i/numframes*100, (numframes - i)/(i/toc));
end
end
t.close();
which results in the following output:
Frame 10000 written in 66 seconds, 8.196721e+00 percent complete, time left=743 seconds
Frame 20000 written in 225 seconds, 1.639344e+01 percent complete, time left=1145 seconds
Frame 30000 written in 481 seconds, 2.459016e+01 percent complete, time left=1474 seconds
Frame 40000 written in 915 seconds, 3.278689e+01 percent complete, time left=1877 seconds
Frame 50000 written in 1512 seconds, 4.098361e+01 percent complete, time left=2177 seconds
Attempting to make use of the BigTIFF library does not work
Following the discussion here: http://blogs.mathworks.com/steve/2013/08/07/tiff-bigtiff-and-blockproc/
I attempted to convert the code to work with uint16 data by changing line 73 to:
obj.TiffObject.setTag('BitsPerSample', 16);
but after writing with
outFileWriter = bigTiffWriter('test.tif', inFileInfo(1).Height, inFileInfo(1).Width, tileSize(1), tileSize(2));
for i=1:122000
blockproc(IMG(:,:,i),tileSize,@(b) b.data,'Destination',outFileWriter);
if rem(i,10000)==0
fprintf('Frame %d done\n',i)
end
end
I get the following error when trying to read back in:
Unexpected Standard exception from MEX file.
What() is:std::bad_alloc
..
Error in imtifinfo (line 27)
raw_tags = tifftagsread(filename,0,0,0);
Error in imfinfo (line 183)
info = feval(fmt_s.info, filename);
Error in TiffReader (line 11)
InfoImage=imfinfo(fname);
On a related note, preallocating the file with the correct size on the disk makes no difference
I thought there was a slim chance this was a file I/O problem, in which case preallocating the space on disk might be relevant, so I tried what was mentioned here: http://www.mathworks.co.uk/matlabcentral/newsreader/view_thread/241072, namely:
% Create the file
fh = javaObject('java.io.RandomAccessFile', 'test.dat', 'rw');
% Allocate the right amount of space
fh.setLength(1024);
% Close the file
fh.close();
but it made no difference.
Any help would be greatly appreciated.