From d6125e8941314414d5082e1936e632fcf83a552b Mon Sep 17 00:00:00 2001 From: Yoann Guilhem <yoann.guilhem@esrf.fr> Date: Thu, 25 Apr 2013 11:13:24 +0200 Subject: [PATCH] Update TIF IO functions. Signed-off-by: Yoann Guilhem <yoann.guilhem@esrf.fr> --- zUtil_TIFF/gtTIFInfoReader.m | 44 ++++++++++++++++++++ zUtil_TIFF/gtTIFVolReader.m | 54 ++++++++++++++++--------- zUtil_TIFF/gtTIFVolReaderWithInfo.m | 41 +++++++++++++++++++ zUtil_TIFF/gtTIFVolWriter.m | 63 ++++++++++++++++++----------- 4 files changed, 159 insertions(+), 43 deletions(-) create mode 100644 zUtil_TIFF/gtTIFInfoReader.m create mode 100644 zUtil_TIFF/gtTIFVolReaderWithInfo.m diff --git a/zUtil_TIFF/gtTIFInfoReader.m b/zUtil_TIFF/gtTIFInfoReader.m new file mode 100644 index 00000000..599096bb --- /dev/null +++ b/zUtil_TIFF/gtTIFInfoReader.m @@ -0,0 +1,44 @@ +function info = gtTIFInfoReader(filename, info) +% GTTIFINFOREADER Read TIFF info file (BBox, voxelsize and origin). +% +% info = gtTIFInfoReader(filename, info) +% ------------------------------------------------------------------------- +% +% INPUT: +% filename = <string> Path to info file +% +% OPTIONAL INPUT +% info = <struct> TIFF info strsture to complete +% +% OUTPUT: +% info = <struct> Information about volume +% +% Note: +% info file should be formatted as the following: +% +% [bboxMinX, bboxMinY, bboxMinZ] [bboxMaxX, bboxMaxY, bboxMaxZ] +% voxelsize +% +% Version 001 24-04-2013 by YGuilhem, yoann.guilhem@esrf.fr + +% Check existence of file +if ~exist(filename, 'file') + gtError('gtTIFInfoReader:wrong_file_name', ... + ['File ''' filename ''' does not exist!']); +end + +% Read info file +fid = fopen(filename, 'r'); +bbox = fscanf(fid, '[%d, %d, %d] [%d, %d, %d]', 6).'; +vSize = fscanf(fid, '%f', 1); +fclose(fid); + +% Store bbox, voxel size and origin +info.boundingBoxMin = bbox(1:3) + 1; +info.boundingBoxMax = bbox(4:6); +info.voxelSize = vSize; +info.origin = bbox(1:3) .* info.voxelSize; +info.infoFile = filename; + +end % end of function + diff --git a/zUtil_TIFF/gtTIFVolReader.m b/zUtil_TIFF/gtTIFVolReader.m index 50d807c1..96e99512 100644 --- a/zUtil_TIFF/gtTIFVolReader.m +++ b/zUtil_TIFF/gtTIFVolReader.m @@ -10,23 +10,22 @@ function [vol, info] = gtTIFVolReader(filename, varargin) % if extension is missing, '.tif' is append % % OPTIONAL INPUT (varargin as a list of pairs, see parse_pv_pairs.m): -% 'xrange' = <range> Index range of output in X direction -% 'yrange' = <range> " Y " -% 'zrange' = <range> " Z " -% 'mode' = <string> Input type which is either 'single' or 'stack' -% default is a single TIFF file -% 'digits' = <int> Number of digits in stack filenames -% 'startindex' = <int> Starting index for stack filenames -% 'endindex' = <int> Ending " -% 'filext' = <string> Input TIFF file extension ('tif' or 'tiff') -% default is 'tif' -% 'newMethod' = <bool> Use new reading method (faster) +% 'xrange' = <range> Index range of output in X direction {'all'} +% 'yrange' = <range> " Y " {'all'} +% 'zrange' = <range> " Z " {'all'} +% 'bbox' = <int> Index range as bbox [Xi Yi Zi Xf Yf Zf] +% 'mode' = <string> Input type which is {'single'} or 'stack' +% 'digits' = <int> Number of digits in stack filenames {4} +% 'startindex' = <int> Starting index for stack filenames {1} +% 'endindex' = <int> Ending " {1} +% 'filext' = <string> Input TIFF file extension {'tif'} +% 'newMethod' = <bool> Use new reading method (faster) {'true'} % % OUTPUT: -% vol = <3Dimage> Output 3D volume -% info = <struct> Information about volume +% vol = <3Dimage> Output 3D volume +% info = <struct> Information about volume % -% Version 003 30-10-2012 +% Version 003 30-10-2012 by YGuilhem, yoann.guilhem@esrf.fr % Use tifflib for fast reading % Some bugfixes % @@ -37,9 +36,10 @@ function [vol, info] = gtTIFVolReader(filename, varargin) % Set default parameters and parse optional arguments params.newMethod = true; -params.xrange = 'all'; -params.yrange = 'all'; -params.zrange = 'all'; +params.xrange = []; +params.yrange = []; +params.zrange = []; +params.bbox = []; params.mode = 'single'; params.filext = 'tif'; params.digits = 4; @@ -73,7 +73,6 @@ if ~exist('filename', 'var') end end - % Get file parts and store the proper extension [fpath, fname, fext] = fileparts(filename); if any(strcmp(fext, {'.tif', '.tiff'})) @@ -94,7 +93,7 @@ else fullFilenameFormat = fullfile(fpath, filenameFormat); % Check existence of input stack files - for idx=params.startindex:params.endindex + for idx = params.startindex:params.endindex sfilename = sprintf(fullFilenameFormat, idx); if ~exist(sfilename, 'file') gtError('gtTIFVolReader:wrong_file_name', ... @@ -135,6 +134,20 @@ tifSizeZ = length(fileIndex); [fpath, fname, ~] = fileparts(fullFilename); fullFilenameFormat = fullfile(fpath, filenameFormat); +% Check if we use ranges or bbox input +if isempty(params.bbox) + if isempty(params.xrange), params.xrange = 'all'; end; + if isempty(params.yrange), params.yrange = 'all'; end; + if isempty(params.zrange), params.zrange = 'all'; end; +elseif isempty([params.xrange params.yrange params.zrange]) + params.xrange = params.bbox(1):params.bbox(4); + params.yrange = params.bbox(2):params.bbox(5); + params.zrange = params.bbox(3):params.bbox(6); +else + gtError('gtTIFVolReader:wrong_range_input', ... + 'You cannot use both bbox and [xyz]range options!'); +end + % Check each dimension range fullRangeXY = true; if strcmp(params.xrange, 'all') @@ -183,6 +196,9 @@ end info.volSizeX = volSizeX; info.volSizeY = volSizeY; info.volSizeZ = volSizeZ; +info.tifSizeX = tifSizeX; +info.tifSizeY = tifSizeY; +info.tifSizeZ = tifSizeZ; info.bytespervoxel = tifInfo(1).SamplesPerPixel * tifInfo(1).BitsPerSample / 8; info.fpath = fpath; info.byteorder = tifInfo(1).ByteOrder(1); diff --git a/zUtil_TIFF/gtTIFVolReaderWithInfo.m b/zUtil_TIFF/gtTIFVolReaderWithInfo.m new file mode 100644 index 00000000..29f251fc --- /dev/null +++ b/zUtil_TIFF/gtTIFVolReaderWithInfo.m @@ -0,0 +1,41 @@ +function [vol, info] = gtTIFVolReaderWithInfo(filename, varargin) +% GTTIFVOLREADERWITHINFO Read TIFF volume with the info (BBox and voxelsize). +% +% [vol, info] = gtTIFVolReaderWithInfo(filename, varargin) +% ------------------------------------------------------------------------- +% +% INPUT: +% filename = <string> Path to TIFF file to write +% it may be relative or absolute +% if extension is missing, '.tif' is append +% +% OPTIONAL INPUT -> see gtTIFVolReader +% +% OUTPUT: +% vol = <3Dimage> Output 3D volume +% info = <struct> Information about volume +% +% Note: +% info file should be formatted as the following: +% +% [bboxMinX, bboxMinY, bboxMinZ] [bboxMaxX, bboxMaxY, bboxMaxZ] +% voxelsize +% +% Version 001 24-04-2013 by YGuilhem, yoann.guilhem@esrf.fr + +% Read TIFF file +if isempty(varargin) + [vol, info] = gtTIFVolReader(filename); +else + [vol, info] = gtTIFVolReader(filename, varargin); +end + +% Extract path, basename and extension from file name +[fpath, fname, fext] = fileparts(info.fname_final); + +% Read info from file +infoFile = fullfile(fpath, [fname '.info']); +info = gtTIFInfoReader(infoFile, info); + +end % end of function + diff --git a/zUtil_TIFF/gtTIFVolWriter.m b/zUtil_TIFF/gtTIFVolWriter.m index 6cdc8590..f3fc2189 100644 --- a/zUtil_TIFF/gtTIFVolWriter.m +++ b/zUtil_TIFF/gtTIFVolWriter.m @@ -15,28 +15,27 @@ function gtTIFVolWriter(vol, filename, varargin) % number and the extension will be append. % % OPTIONAL INPUT (varargin as a list of pairs, see parse_pv_pairs.m): -% 'xrange' = <range> Index range of output in X direction -% 'yrange' = <range> " Y " -% 'zrange' = <range> " Z " +% 'xrange' = <int> Index range of output in X direction {'all'} +% 'yrange' = <int> " Y " {'all'} +% 'zrange' = <int> " Z " {'all'} +% 'bbox' = <int> Index range as bbox [Xi Yi Zi Xf Yf Zf] % % 'type' = <string> Force type of data written in the TIFF file % it can be 'uint8', 'uint16' or 'logical' -% default is 'uint8' +% default is detected from input volume class % -% 'compress' = <string> Compression mode, by default 'none', can be -% 'packbits', 'lzm', 'deflate', 'ccitt', 'fax3' -% or 'fax4' +% 'compress' = <string> Compression mode can be {'none'}, 'packbits', +% 'lzm', 'deflate', 'ccitt', 'fax3' or 'fax4' % -% 'mode' = <string> Output type which is 'single' or 'stack' -% default is a single TIFF file -% 'digits' = <int> Number of digits in stack filenames -% 'startindex' = <int> Starting index for stack filenames -% 'filext' = <string> Output TIFF file extension ('tif' or 'tiff') -% default is 'tif' -% 'newMethod' = <bool> Use new TIFF writing method (faster) +% 'mode' = <string> Output type which is {'single'} or 'stack' +% 'digits' = <int> Number of digits in stack filenames {4} +% 'startindex' = <int> Starting index for stack filenames {1} +% 'filext' = <string> Output TIFF file extension {'tif'} +% 'newMethod' = <bool> Use new TIFF writing method (faster) {true} % -% TODO : -% - RGB data output +% TODO: +% - RGB data output +% - float output % % Version 003 30-10-2012 by YGuilhem, yoann.guilhem@esrf.fr % Use tifflib for fast reading @@ -50,9 +49,10 @@ function gtTIFVolWriter(vol, filename, varargin) % Set default parameters and parse optional arguments params.newMethod = true; -params.xrange = 'all'; -params.yrange = 'all'; -params.zrange = 'all'; +params.xrange = []; +params.yrange = []; +params.zrange = []; +params.bbox = []; params.type = ''; params.compress = 'none'; params.mode = 'single'; @@ -67,6 +67,20 @@ if params.newMethod && ~exist('tifflib', 'file') params.newMethod = false; end +% Check if we use ranges or bbox input +if isempty(params.bbox) + if isempty(params.xrange), params.xrange = 'all'; end; + if isempty(params.yrange), params.yrange = 'all'; end; + if isempty(params.zrange), params.zrange = 'all'; end; +elseif isempty([params.xrange params.yrange params.zrange]) + params.xrange = params.bbox(1):params.bbox(4); + params.yrange = params.bbox(2):params.bbox(5); + params.zrange = params.bbox(3):params.bbox(6); +else + gtError('gtTIFVolWriter:wrong_range_input', ... + 'You cannot use both bbox and [xyz]range options!'); +end + % Translating range parameters if strcmp(params.xrange, 'all') rangeX = 1:size(vol, 1); @@ -111,7 +125,7 @@ else rescale = 0; case 'uint8' rescale = 255; - otherwise + case 'uint16' rescale = 65535; end end @@ -211,7 +225,7 @@ if strcmpi(params.mode, 'single') % Writing volume in TIFF file if params.newMethod tif = Tiff(filename, 'a'); - for iz=1:length(rangeZ) + for iz = 1:length(rangeZ) tif.setTag(tifTag); tif.write(outVol(rangeX, rangeY, rangeZ(iz))'); tif.writeDirectory(); @@ -219,7 +233,7 @@ if strcmpi(params.mode, 'single') tif.close(); else % Old method - for iz=1:length(rangeZ) + for iz = 1:length(rangeZ) imwrite(outVol(rangeX(1):rangeX(end), rangeY(1):rangeY(end), ... rangeZ(iz))', ... filename, 'tif', 'Compression', params.compress, ... @@ -266,7 +280,7 @@ elseif strcmpi(params.mode, 'stack') % Writing volume in TIFF stack files if params.newMethod - for iz=1:length(rangeZ) + for iz = 1:length(rangeZ) outFile = sprintf(filenameFMT, iz+offset); tif = Tiff(outFile, 'w'); tif.setTag(tifTag); @@ -275,7 +289,7 @@ elseif strcmpi(params.mode, 'stack') end else % Old method - for iz=1:length(rangeZ) + for iz = 1:length(rangeZ) outFile = sprintf(filenameFMT, iz+offset); imwrite(outVol(rangeX, rangeY, rangeZ(iz))', outFile, 'tif', ... 'Compression', params.compress, 'writemode', 'overwrite'); @@ -284,3 +298,4 @@ elseif strcmpi(params.mode, 'stack') end end % end of function + -- GitLab