Files
fold_slice/+io/image_read.m
T
2026-08-07 15:56:42 +09:00

729 lines
28 KiB
Matlab
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
% 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