mirror of
https://github.com/c-sooyoung/fold_slice.git
synced 2026-09-17 17:29:09 +09:00
729 lines
28 KiB
Matlab
729 lines
28 KiB
Matlab
% Call function without arguments for instructions on how to use it
|
||
|
||
% Filename: $RCSfile: image_read.m,v $
|
||
%
|
||
% $Revision: 1.17 $ $Date: 2013/01/25 10:23:23 $
|
||
% $Author: $
|
||
% $Tag: $
|
||
%
|
||
% Description:
|
||
% Macro for reading image data formats used at the SLS / cSAXS beamline.
|
||
% The data are returned in double precision floating point format.
|
||
%
|
||
% Note:
|
||
% Call without arguments for a brief help text.
|
||
%
|
||
% Dependencies:
|
||
% - edfread
|
||
% - cbfread
|
||
% - hdf5read
|
||
% - fliread
|
||
% - speread
|
||
% - char_to_cellstr
|
||
%
|
||
% history:
|
||
%
|
||
% September 30th 2010:
|
||
% add a call to hdf5read_main
|
||
%
|
||
% June 5th 2009:
|
||
% disable UhandledParError before calling sub-macros
|
||
%
|
||
% January 16th 2009:
|
||
% adapt to image_orient returning the complete structure rather than just
|
||
% the data array
|
||
%
|
||
% November 19th 2008:
|
||
% add reading of Matlab files
|
||
%
|
||
% September 5th 2008:
|
||
% skip further processing for a frame if it was not possible to read it
|
||
%
|
||
% September 4th 2008:
|
||
% add the rowcol-from field to the frames structure as origin information
|
||
%
|
||
% June 19th 2008: adapt call to image_orient
|
||
%
|
||
% May 16th 2008: send variable arguments through find files
|
||
%
|
||
% May 9th 2008: 1st version
|
||
|
||
%*-----------------------------------------------------------------------*
|
||
%| |
|
||
%| Except where otherwise noted, this work is licensed under a |
|
||
%| Creative Commons Attribution-NonCommercial-ShareAlike 4.0 |
|
||
%| International (CC BY-NC-SA 4.0) license. |
|
||
%| |
|
||
%| Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch) |
|
||
%| |
|
||
%| Author: CXS group, PSI |
|
||
%*-----------------------------------------------------------------------*
|
||
% You may use this code with the following provisions:
|
||
%
|
||
% If the code is fully or partially redistributed, or rewritten in another
|
||
% computing language this notice should be included in the redistribution.
|
||
%
|
||
% If this code, or subfunctions or parts of it, is used for research in a
|
||
% publication or if it is fully or partially rewritten for another
|
||
% computing language the authors and institution should be acknowledged
|
||
% in written form in the publication: “Data processing was carried out
|
||
% using the “cSAXS matlab package” developed by the CXS group
|
||
% and Computing Department, Paul Scherrer Institut, Switzerland.”
|
||
% Variations on the latter text can be incorporated upon discussion with
|
||
% the CXS group if needed to more specifically reflect the use of the package
|
||
% for the published work.
|
||
%
|
||
% A publication that focuses on describing features, or parameters, that
|
||
% are already existing in the code should be first discussed with the
|
||
% authors.
|
||
%
|
||
% This code and subroutines are part of a continuous development, they
|
||
% are provided “as they are” without guarantees or liability on part
|
||
% of PSI or the authors. It is the user responsibility to ensure its
|
||
% proper use and the correctness of the results.
|
||
|
||
function [frames,vararg_remain] = image_read(filenames,varargin)
|
||
import io.*
|
||
import io.HDF.*
|
||
import io.CBF.*
|
||
import plotting.*
|
||
import utils.char_to_cellstr
|
||
import utils.default_parameter_value
|
||
import utils.find_files
|
||
import utils.fopen_until_exists
|
||
|
||
% initialize return arguments
|
||
frames = struct('data',[], ...
|
||
'img_full_size',[], 'rowcol_from',[], ...
|
||
'no_of_el_read', [], ...
|
||
'header',[], 'filename',[], 'extension', []);
|
||
|
||
% check minimum number of input arguments
|
||
if (nargin < 1)
|
||
image_read_help('ext',mfilename);
|
||
error('At least the filename has to be specified as input parameter.');
|
||
end
|
||
|
||
% accept cell array with name/value pairs as well
|
||
no_of_in_arg = nargin;
|
||
if (nargin == 2)
|
||
if (isempty(varargin))
|
||
% ignore empty cell array
|
||
no_of_in_arg = no_of_in_arg -1;
|
||
else
|
||
if (iscell(varargin{1}))
|
||
% use a filled one given as first and only variable parameter
|
||
varargin = varargin{1};
|
||
no_of_in_arg = 1 + length(varargin);
|
||
end
|
||
end
|
||
end
|
||
|
||
% check number of input arguments
|
||
if (rem(no_of_in_arg,2) ~= 1)
|
||
error('The optional parameters have to be specified as ''name'',''value'' pairs');
|
||
end
|
||
|
||
% convert the filename to a cell array to use the same loop for single and
|
||
% multiple file names
|
||
if (~iscell(filenames))
|
||
filenames = { filenames };
|
||
end
|
||
|
||
% hdf5 files are read via a separate sub-routine
|
||
% if length(filenames) == 1 % accept only one file name
|
||
filename = filenames{1};
|
||
[~, ~, ext] = fileparts(filename);
|
||
|
||
if any(strcmp(ext, {'.h5', '.hdf5', '.nxs', '.cxs'}))
|
||
if length(filenames) == 1
|
||
frames = hdf5read(filename, varargin);
|
||
else
|
||
frames = hdf5read(filenames, varargin);
|
||
end
|
||
vararg_remain = [];
|
||
|
||
return % image_read ends here for hdf5 image files
|
||
end
|
||
% end
|
||
|
||
% set default values for the variable input arguments:
|
||
% default data type for the returned frames
|
||
data_type = default_parameter_value(mfilename,'DataType');
|
||
% recognize file type by file name extension
|
||
force_file_type = default_parameter_value(mfilename,'ForceFileType');
|
||
% from/to row 0 means all rows
|
||
row_from = default_parameter_value(mfilename,'RowFrom');
|
||
row_to = default_parameter_value(mfilename,'RowTo');
|
||
% from/to column 0 means all lines
|
||
column_from = default_parameter_value(mfilename,'ColumnFrom');
|
||
column_to = default_parameter_value(mfilename,'ColumnTo');
|
||
% determine default orientation based on the file name extension
|
||
orient_by_extension = default_parameter_value(mfilename,'OrientByExtension');
|
||
% filename is actually a mask that may include wildcards
|
||
filename_is_fmask = default_parameter_value(mfilename,'IsFmask');
|
||
% display file name of the file to be loaded
|
||
display_filename = default_parameter_value(mfilename,'DisplayFilename');
|
||
% variable to load from Matlab files
|
||
matlab_var = default_parameter_value(mfilename,'MatlabVar');
|
||
|
||
% exit with an error message if unhandled named parameters are left at the
|
||
% end of this macro
|
||
unhandled_par_error = 1;
|
||
|
||
% parse the variable input arguments
|
||
vararg = cell(0,0);
|
||
for ind = 1:2:length(varargin)
|
||
name = varargin{ind};
|
||
value = varargin{ind+1};
|
||
switch name
|
||
case 'DataType'
|
||
if (~ischar(value))
|
||
error('The DataType must be string defining a valid Matlab data type.');
|
||
end
|
||
data_type = value;
|
||
case 'ForceFileType'
|
||
force_file_type = lower(value);
|
||
case 'MatlabVar'
|
||
matlab_var = value;
|
||
case 'RowFrom'
|
||
row_from = value;
|
||
case 'ROI'
|
||
if (length(value) ~= 4)
|
||
error('The ROI parameter needs a vector of length four as argument.');
|
||
end
|
||
column_from = value(1);
|
||
row_from = value(2);
|
||
column_to = value(3);
|
||
row_to = value(4);
|
||
case 'RowTo'
|
||
row_to = value;
|
||
case 'ColumnFrom'
|
||
column_from = value;
|
||
case 'ColumnTo'
|
||
column_to = value;
|
||
case 'OrientByExtension'
|
||
orient_by_extension = value;
|
||
case 'UnhandledParError'
|
||
unhandled_par_error = value;
|
||
case 'IsFmask'
|
||
filename_is_fmask = value;
|
||
case 'DisplayFilename'
|
||
display_filename = value;
|
||
otherwise
|
||
vararg{end+1} = name; %#ok<AGROW>
|
||
vararg{end+1} = value; %#ok<AGROW>
|
||
end
|
||
end
|
||
|
||
|
||
% initialize the list of unhandled parameters
|
||
vararg_remain = cell(0,0);
|
||
|
||
% loop over all specified file names
|
||
file_ind_max = length(filenames);
|
||
store_ind = 1;
|
||
for (file_ind=1:file_ind_max)
|
||
filename = filenames{file_ind};
|
||
vararg_remain = vararg;
|
||
|
||
% in case of file name mask get a list of all matching file names
|
||
data_dir = '';
|
||
if (filename_is_fmask)
|
||
% sub macros must not complain about unknown arguments
|
||
vararg_remain{end+1} = 'UnhandledParError';
|
||
vararg_remain{end+1} = 0;
|
||
|
||
[data_dir, fnames, vararg_remain] = ...
|
||
find_files( filename, vararg_remain );
|
||
else
|
||
fnames = struct('name',filename);
|
||
end
|
||
|
||
for (sub_file_ind = 1:length(fnames))
|
||
% pick out the current filename
|
||
filename = [ data_dir fnames(sub_file_ind).name ];
|
||
|
||
% check for minimum filename length
|
||
if (length(filename) < 5)
|
||
error([ mfilename ': invalid filename ' filename ]);
|
||
end
|
||
|
||
if (isempty(force_file_type))
|
||
% get the extension from the last three to four characters
|
||
extension = lower(filename((end-4):end));
|
||
pos = strfind(extension,'.');
|
||
if (length(pos) < 1)
|
||
error([ mfilename ': invalid extension in ' filename ]);
|
||
end
|
||
extension = extension(pos(end)+1:end);
|
||
else
|
||
% the file name extension is ignored since the file type is
|
||
% forced to a specific one
|
||
extension = force_file_type;
|
||
end
|
||
|
||
if (display_filename)
|
||
fprintf('loading %s\n',filename);
|
||
end
|
||
|
||
if ((strcmp(extension,'dat')) || ...
|
||
(strcmp(extension,'tif')) || (strcmp(extension,'tiff')) || ...
|
||
(strcmp(extension,'mat')))
|
||
% open the file to support functionality like
|
||
% wait-until-exists
|
||
[fid,vararg_remain] = fopen_until_exists(filename,vararg);
|
||
if (fid >= 0)
|
||
fclose(fid);
|
||
end
|
||
end
|
||
|
||
% interprete file in the format indicated by the filename extension
|
||
switch extension
|
||
case 'cbf'
|
||
[frame,vararg_remain] = cbfread(filename,vararg_remain);
|
||
case {'hdf5', 'h5', 'nxs', 'cxs'}
|
||
[frame,vararg_remain] = hdf5read_main(filename,vararg_remain);
|
||
case 'dat'
|
||
[frame,vararg_remain] = datread(filename,vararg_remain);
|
||
case 'edf'
|
||
[frame,vararg_remain] = edfread(filename,vararg_remain);
|
||
case {'mar', 'mccd'}
|
||
[frame,vararg_remain] = marread(filename,vararg_remain);
|
||
case 'mat'
|
||
tmp_data = load(filename);
|
||
frame.data = tmp_data.(matlab_var);
|
||
frame.header = {};
|
||
% No header information are available.
|
||
% Fake exposure time information to avoid problems in other
|
||
% macros.
|
||
frame.header{end+1} = 'Exposure_time 1.0';
|
||
% add the file modification date to the header
|
||
dir_entry = dir(filename);
|
||
frame.header{end+1} = [ 'DateTime ' dir_entry.date ];
|
||
case 'raw'
|
||
[frame,vararg_remain] = fliread(filename,vararg_remain);
|
||
case 'spe'
|
||
[frame,vararg_remain] = speread(filename,vararg_remain);
|
||
case {'tif', 'tiff'}
|
||
% reading higher bit depths than 16bit needs a sufficiently
|
||
% up-to-date Matlab version
|
||
frame.data = imread(filename,'tif');
|
||
hdr = imfinfo(filename);
|
||
frame.header = {};
|
||
if (isfield(hdr,'ImageDescription'))
|
||
frame.header = char_to_cellstr(hdr.ImageDescription);
|
||
end
|
||
if ((isfield(hdr,'Model')) && ...
|
||
(strcmp(hdr.Model(1:7),'PILATUS')))
|
||
frame.header{end+1} = [ 'DateTime ' hdr.DateTime ];
|
||
frame.header{end+1} = [ 'Software ' hdr.Software ];
|
||
frame.header{end+1} = [ 'Model ' hdr.Model ];
|
||
else
|
||
% the exposure time is not available
|
||
if (isfield(hdr,'exptimesec'))
|
||
frame.header{end+1} = [ 'Exposure_time' hdr.exptimesec ];
|
||
else
|
||
frame.header{end+1} = 'Exposure_time 1.0';
|
||
end
|
||
if (isfield(hdr,'DateTime'))
|
||
frame.header{end+1} = [ 'DateTime ' hdr.DateTime ];
|
||
else
|
||
if (isfield(hdr,'FileModDate'))
|
||
frame.header{end+1} = [ 'DateTime ' hdr.FileModDate ];
|
||
else
|
||
% add the file modification date to the header
|
||
dir_entry = dir(filename);
|
||
frame.header{end+1} = ...
|
||
[ 'DateTime ' dir_entry.date ];
|
||
end
|
||
end
|
||
end
|
||
otherwise
|
||
error([ 'unknown extension of ' filename ]);
|
||
end
|
||
|
||
% the remaining code is not needed if no file was read
|
||
if (isempty(frame.data))
|
||
continue;
|
||
end
|
||
% determine the orientation from the filename extension
|
||
vararg_remain_prev = vararg_remain;
|
||
vararg_remain = cell(1,length(vararg_remain)+2);
|
||
vararg_remain(3:end) = vararg_remain_prev;
|
||
vararg_remain{1} = 'OrientByExtension';
|
||
vararg_remain{2} = orient_by_extension;
|
||
% set the extension since image_orient is called prior
|
||
% to defining the return variables frames
|
||
frame.extension = cell(1,1);
|
||
frame.extension{1} = extension;
|
||
|
||
% orient image
|
||
[frame,vararg_remain] = image_orient(frame,vararg_remain);
|
||
|
||
% cut out region of interest
|
||
full_size = size(frame.data);
|
||
if ((row_from > 0) || (row_to > 0) ||...
|
||
(column_from > 0) || (column_to > 0))
|
||
if (row_from <= 0)
|
||
row_from = 1;
|
||
end
|
||
if (row_from > size(frame.data,1))
|
||
error('The RowFrom specification is beyond the maximum value of %d',...
|
||
size(frame.data,1));
|
||
end
|
||
if (row_to <= row_from)
|
||
row_to = full_size(1);
|
||
end
|
||
if (row_to > full_size(1))
|
||
error('The RowTo specification is beyond the maximum value of %d',...
|
||
full_size(1));
|
||
end
|
||
|
||
if (column_from <= 0)
|
||
column_from = 1;
|
||
end
|
||
if (column_from > full_size(2))
|
||
error('The ColumnFrom specification is beyond the maximum value of %d',...
|
||
full_size(2));
|
||
end
|
||
if (column_to <= column_from)
|
||
column_to = full_size(2);
|
||
end
|
||
if (column_to > size(frame.data,2))
|
||
error('The ColumnTo specification is beyond the maximum value of %d',...
|
||
full_size(2));
|
||
end
|
||
frame.data = frame.data(row_from:row_to,column_from:column_to,:);
|
||
end
|
||
|
||
% initialize the return array with the now known dimensions
|
||
if (store_ind == 1)
|
||
% in case of file name masks or multiple images in one data
|
||
% file the final array dimensions can only be estimated
|
||
init_guess = file_ind_max -1 + length(fnames);
|
||
frames.data = zeros( [ size(frame.data) init_guess ], data_type );
|
||
frames.rowcol_from = cell(1,init_guess);
|
||
frames.no_of_el_read = cell(1,init_guess);
|
||
frames.img_full_size = cell(1,init_guess);
|
||
frames.filename = cell(1,init_guess);
|
||
frames.extension = cell(1,init_guess);
|
||
frames.header = cell(1,init_guess);
|
||
end
|
||
|
||
|
||
% store the frame(s)
|
||
if ((size(frame.data,1) ~= size(frames.data,1)) || ...
|
||
(size(frame.data,2) ~= size(frames.data,2)))
|
||
error('Expected frame dimension is %d x %d, frame read has %d x %d',...
|
||
size(frames.data,2),size(frames.data,1),...
|
||
size(frame.data,2),size(frame.data,1));
|
||
end
|
||
|
||
% in some cases multiple frames are stored in a single file
|
||
if (ndims(frame.data) == 4)
|
||
store_ind_to = (store_ind+size(frame.data,4)-1);
|
||
frames.data(:,:,:,store_ind:store_ind_to) = cast(frame.data,data_type);
|
||
else
|
||
store_ind_to = (store_ind+size(frame.data,3)-1);
|
||
frames.data(:,:,store_ind:store_ind_to) = cast(frame.data,data_type);
|
||
end
|
||
|
||
% store the filename, extension and the header in the return argument
|
||
for (ind=store_ind:store_ind_to)
|
||
frames.img_full_size{ind} = full_size;
|
||
frames.rowcol_from{ind} = [ row_from column_from ];
|
||
if (isfield(frame,'no_of_el_read'))
|
||
frames.no_of_el_read{ind} = frame.no_of_el_read;
|
||
else
|
||
frames.no_of_el_read{ind} = size(frame.data,3);
|
||
end
|
||
% zero means no ROI, i.e., starting at point (1,1)
|
||
if (frames.rowcol_from{ind}(1) < 1)
|
||
frames.rowcol_from{ind}(1) = 1;
|
||
end
|
||
if (frames.rowcol_from{ind}(2) < 1)
|
||
frames.rowcol_from{ind}(2) = 1;
|
||
end
|
||
frames.filename{ind} = filename;
|
||
frames.extension{ind} = extension;
|
||
frames.header{ind} = frame.header;
|
||
end
|
||
|
||
% update index to free space in the output arrays
|
||
store_ind = store_ind_to + 1;
|
||
|
||
% exit in case of unhandled named parameters, if this has not been switched
|
||
% off
|
||
if ((unhandled_par_error) && (~isempty(vararg_remain)))
|
||
vararg_remain
|
||
error('Not all named parameters have been handled.');
|
||
end
|
||
% restore parameters for next iteration
|
||
vararg_remain = vararg_remain_prev;
|
||
end
|
||
end
|
||
|
||
% resize the output arrays in case the initial size is too large
|
||
store_ind = store_ind -1;
|
||
if (size(frames.data,3) > store_ind)
|
||
frames.data = frames.data(:,:,1:store_ind);
|
||
frames.img_full_size = frames.img_full_size(1:store_ind);
|
||
frames.rowcol_from = frames.rowcol_from(1:store_ind);
|
||
frames.filename = frames.filename(1:store_ind);
|
||
frames.extension = frames.extension(1:store_ind);
|
||
frames.header = frames.header(1:store_ind);
|
||
end
|
||
|
||
function frames = hdf5read(filename, params)
|
||
import utils.fopen_until_exists
|
||
import io.image_default_orientation
|
||
import io.HDF.hdf5_load
|
||
import io.image_orient
|
||
import utils.find_files
|
||
|
||
frames = struct('data', [], 'img_full_size', [], 'rowcol_from', [], ...
|
||
'no_of_el_read', [], 'header',[], 'filename',[], 'extension', []);
|
||
|
||
|
||
|
||
p = inputParser;
|
||
p.KeepUnmatched = true;
|
||
p.FunctionName = 'image_read';
|
||
|
||
addParameter(p, 'H5Location', '/');
|
||
addParameter(p, 'ReadAttr', false);
|
||
|
||
addParameter(p, 'FrameRange', [1, Inf], @(x) isvector(x) && numel(x) <= 2 && isnumeric(x));
|
||
addParameter(p, 'RowFrom', 1, @(x) isscalar(x) && isnumeric(x));
|
||
addParameter(p, 'RowTo', Inf, @(x) isscalar(x) && isnumeric(x));
|
||
addParameter(p, 'ColumnFrom', 1, @(x) isscalar(x) && isnumeric(x));
|
||
addParameter(p, 'ColumnTo', Inf, @(x) isscalar(x) && isnumeric(x));
|
||
|
||
addParameter(p, 'OrientByExtension', 1, @(x) isscalar(x) && (isnumeric(x) || islogical(x)));
|
||
addParameter(p, 'Orientation', [0, 0, 0], @(x) isvector(x) && numel(x) == 3 && isnumeric(x));
|
||
addParameter(p, 'InvertOrientation', 0, @(x) isscalar(x) && isnumeric(x));
|
||
addParameter(p, 'Transpose', 0, @(x) isscalar(x) && isnumeric(x));
|
||
addParameter(p, 'FlipLR', 0, @(x) isscalar(x) && isnumeric(x));
|
||
addParameter(p, 'FlipUD', 0, @(x) isscalar(x) && isnumeric(x));
|
||
addParameter(p, 'CatDim', -1, @(x) isscalar(x) && isnumeric(x));
|
||
|
||
addParameter(p, 'DisplayFilename', 1, @(x) isscalar(x) && isnumeric(x));
|
||
|
||
% No support for filename wildcards, i.e. ('IsMask', 1)
|
||
addParameter(p, 'IsFmask', true, ...
|
||
@islogical);%@(x) assert(~x, 'Filename wildcards, i.e. (''IsFmask'', 1), are not supported for hdf5 files'));
|
||
|
||
parse(p, params{:});
|
||
r = p.Results;
|
||
vararg_remain = [fieldnames(p.Unmatched)'; struct2cell(p.Unmatched)'];
|
||
|
||
if (r.IsFmask)
|
||
[data_dir, fnames, vararg_remain] = ...
|
||
find_files( filename, vararg_remain );
|
||
filename = [];
|
||
for ii=1:length(fnames)
|
||
filename{ii} = fullfile(data_dir, fnames(ii).name);
|
||
end
|
||
end
|
||
|
||
|
||
if iscell(filename)
|
||
dir_entry = dir(filename{1});
|
||
frames.header{1} = {['DateTime ' dir_entry.date], 'Exposure_time 0.0'};
|
||
[~, ~, frames.extension{1}] = fileparts(filename{1});
|
||
frames.extension{1} = frames.extension{1}(2:end); % truncate a leading dot
|
||
frames.filename{1} = '*multiple_frames*';
|
||
else
|
||
dir_entry = dir(filename);
|
||
frames.header{1} = {['DateTime ' dir_entry.date], 'Exposure_time 0.0'};
|
||
[~, frames.filename{1}, frames.extension{1}] = fileparts(filename);
|
||
frames.extension{1} = frames.extension{1}(2:end); % truncate a leading dot
|
||
end
|
||
|
||
|
||
inputs_orient = {'OrientByExtension', r.OrientByExtension, 'InvertOrientation', r.InvertOrientation};
|
||
|
||
if r.OrientByExtension
|
||
orient_vec = image_default_orientation(frames.header{1}, frames.extension{1});
|
||
do_transpose = orient_vec(1);
|
||
do_fliplr = orient_vec(2);
|
||
do_flipud = orient_vec(3);
|
||
|
||
% Warn user if they also provided either of 'Orientation', 'Transpose', 'FlipLR' or 'FlipUD'
|
||
if ~all(ismember({'Orientation', 'Transpose', 'FlipLR', 'FlipUD'}, p.UsingDefaults))
|
||
warning(['Default hdf5 image orientation is potentially modified by either ' ...
|
||
'''Orientation'', or any of ''Transpose'', ''FlipLR'', or ''FlipUD'' parameters. ' ...
|
||
'To supress this warning set ''OrientByExtension'' to 0.']);
|
||
end
|
||
|
||
else
|
||
do_transpose = 0;
|
||
do_fliplr = 0;
|
||
do_flipud = 0;
|
||
end
|
||
|
||
if ~ismember({'Orientation'}, p.UsingDefaults)
|
||
do_transpose = r.Orientation(1);
|
||
do_fliplr = r.Orientation(2);
|
||
do_flipud = r.Orientation(3);
|
||
|
||
inputs_orient = [inputs_orient, {'Orientation', r.Orientation}];
|
||
|
||
% Warn user if they also provided either of 'Transpose', 'FlipLR' or 'FlipUD'
|
||
if ~all(ismember({'Transpose', 'FlipLR', 'FlipUD'}, p.UsingDefaults))
|
||
warning(['Image orientation specified via ''Orientation'' parameter is potentially ' ...
|
||
'modified by either ''Transpose'', ''FlipLR'', and/or ''FlipUD''. ' ...
|
||
'To supress this warning use either ''Orientation'' or a combination of ' ...
|
||
'''Transpose'', ''FlipLR'', and/or ''FlipUD'' parameters.']);
|
||
end
|
||
end
|
||
|
||
if r.Transpose || r.FlipLR || r.FlipUD
|
||
do_transpose = r.Transpose;
|
||
do_fliplr = r.FlipLR;
|
||
do_flipud = r.FlipUD;
|
||
inputs_orient = [inputs_orient, {'Transpose', r.Transpose}];
|
||
inputs_orient = [inputs_orient, {'FlipLR', r.FlipLR}];
|
||
inputs_orient = [inputs_orient, {'FlipUD', r.FlipUD}];
|
||
end
|
||
|
||
inputs = {};
|
||
if ~isempty(r.H5Location) && ischar(r.H5Location)
|
||
inputs{end+1} = r.H5Location;
|
||
end
|
||
|
||
if r.ReadAttr
|
||
inputs{end+1} = '-sa';
|
||
end
|
||
|
||
% Add slicing indexes if a user specified any of them
|
||
if ~all(ismember({'FrameRange', 'RowFrom', 'RowTo', 'ColumnFrom', 'ColumnTo'}, ...
|
||
p.UsingDefaults))
|
||
|
||
% Support 0's as start/end index -> full left/right range
|
||
if numel(r.FrameRange) == 1
|
||
r.FrameRange(2) = r.FrameRange(1);
|
||
end
|
||
if r.FrameRange(1) == 0; r.FrameRange(1) = 1; end
|
||
if r.FrameRange(2) == 0; r.FrameRange(2) = Inf; end
|
||
if r.RowFrom == 0; r.RowFrom = 1; end
|
||
if r.RowTo == 0; r.RowTo = Inf; end
|
||
if r.ColumnFrom == 0; r.ColumnFrom = 1; end
|
||
if r.ColumnTo == 0; r.ColumnTo = Inf; end
|
||
|
||
% Adjust range values according to the consequent image orientation procedure
|
||
if r.InvertOrientation % Transpose -> FlipLR/FlipUD
|
||
if do_transpose; [r.ColumnTo, r.ColumnFrom, r.RowTo, r.RowFrom] = ...
|
||
deal(r.RowTo, r.RowFrom, r.ColumnTo, r.ColumnFrom); end
|
||
if do_fliplr; [r.ColumnTo, r.ColumnFrom] = deal(-r.ColumnFrom, -r.ColumnTo); end
|
||
if do_flipud; [r.RowTo, r.RowFrom] = deal(-r.RowFrom, -r.RowTo); end
|
||
|
||
else % FlipLR/FlipUD -> Transpose
|
||
if do_fliplr; [r.ColumnTo, r.ColumnFrom] = deal(-r.ColumnFrom, -r.ColumnTo); end
|
||
if do_flipud; [r.RowTo, r.RowFrom] = deal(-r.RowFrom, -r.RowTo); end
|
||
if do_transpose; [r.ColumnTo, r.ColumnFrom, r.RowTo, r.RowFrom] = ...
|
||
deal(r.RowTo, r.RowFrom, r.ColumnTo, r.ColumnFrom); end
|
||
end
|
||
|
||
% Form the input
|
||
inputs{end+1} = {[r.RowFrom, r.RowTo],[r.ColumnFrom, r.ColumnTo], r.FrameRange};
|
||
end
|
||
if iscell(filename)
|
||
|
||
if (r.DisplayFilename)
|
||
fprintf('loading %s\n', filename{1});
|
||
end
|
||
tmp = frames;
|
||
tmp.data = hdf5_load(filename{1}, inputs{:});
|
||
% Orient image frame(s)
|
||
[tmp, vararg_remain] = image_orient(tmp, [inputs_orient, vararg_remain]);
|
||
|
||
% let's handle the 2D (or 3d with singleton) case first
|
||
if isnumeric(tmp.data) && ndims(tmp.data==3) && size(tmp.data,3)==1
|
||
frames.data = zeros([size(tmp.data(:,:,1)) length(filename)*size(tmp.data,3)]);
|
||
frames.data(:,:,1:size(tmp.data,3)) = tmp.data;
|
||
if length(filename)>1
|
||
for frame=2:length(filename)
|
||
if (r.DisplayFilename)
|
||
fprintf('loading %s\n', filename{frame});
|
||
end
|
||
tmp.data = hdf5_load(filename{frame}, inputs{:});
|
||
|
||
% Orient image frame(s)
|
||
[tmp, vararg_remain] = image_orient(tmp, [inputs_orient, vararg_remain]);
|
||
frames.data(:,:,frame) = tmp.data;
|
||
end
|
||
end
|
||
else
|
||
% in case of more than 2 dimensions, concatenate along the
|
||
% specified dimension, or return a cell array
|
||
if length(filename)>1
|
||
frames.data{1} = tmp.data;
|
||
framedim = ndims(frames.data{1});
|
||
for frameID=2:length(filename)
|
||
if (r.DisplayFilename)
|
||
fprintf('loading %s\n', filename{frameID});
|
||
end
|
||
frames.data{frameID} = hdf5_load(filename{frameID}, inputs{:});
|
||
if ndims(frames.data{frameID})~=framedim
|
||
framedim = -1;
|
||
end
|
||
% Orient image frame(s)
|
||
[frames, vararg_remain] = image_orient(frames, [inputs_orient, vararg_remain]);
|
||
end
|
||
if framedim > 0
|
||
try
|
||
if r.CatDim == -1
|
||
frames.data = cat(ndims(frames.data{1}),frames.data{:});
|
||
else
|
||
frames.data = cat(r.CatDim, frames.data{:});
|
||
end
|
||
catch
|
||
warning('Failed to concatenate frames.')
|
||
end
|
||
end
|
||
|
||
else
|
||
frames.data = tmp.data;
|
||
end
|
||
end
|
||
else
|
||
% Support wait-until-exist functionality
|
||
[fid, vararg_remain] = fopen_until_exists(filename, vararg_remain(:));
|
||
if fid >= 0
|
||
fclose(fid);
|
||
else
|
||
% Silently exit if a file was not found and ('ErrorIfNotFound', 0)
|
||
return;
|
||
end
|
||
|
||
|
||
if (r.DisplayFilename)
|
||
fprintf('loading %s\n', filename);
|
||
end
|
||
frames.data = hdf5_load(filename, inputs{:});
|
||
|
||
% Orient image frame(s)
|
||
[frames, vararg_remain] = image_orient(frames, [inputs_orient, vararg_remain]);
|
||
|
||
end
|
||
|
||
% If its a dataset then fill these fields for further showing with
|
||
% image_show.m or image_spec.m
|
||
if isnumeric(frames.data)
|
||
frames.img_full_size = {[size(frames.data, 1), size(frames.data, 2)]};
|
||
frames.rowcol_from = {[r.RowFrom, r.ColumnFrom]};
|
||
frames.no_of_el_read = {size(frames.data, 3)};
|
||
elseif (do_fliplr||do_flipud||do_transpose)
|
||
warning(['H5Location points to a group, not a dataset. Orientation/OrientByExtension/Transpose/FlipUD/FlipLR will be ignored. \n '...
|
||
'To remove this warning, set ''OrientByExtension'' to 0 and ''Orientation'' to [0 0 0]'])
|
||
end
|
||
|
||
% Show a warning message for unsupported input parameters
|
||
unmatched = vararg_remain(1:2:end);
|
||
if ~isempty(unmatched)
|
||
warning('These input parameters are not supported for hdf5 files and will be ignored: %s', ...
|
||
strjoin(unmatched, ', '));
|
||
end
|