function V4 = spm_file_merge(V,fname,dt) % Concatenate 3D volumes into a single 4D volume % FUNCTION V4 = spm_file_merge(V,fname,dt) % V - images to concatenate (char array or spm_vol struct) % fname - filename for output 4D volume [defaults: '4D.nii'] % Unless explicit, output folder is the one containing first image % dt - datatype (see spm_type) [defaults: 0] % 0 means same datatype than first input volume % % V4 - spm_vol struct of the 4D volume %__________________________________________________________________________ % % For integer datatypes, the file scale factor is chosen as to maximise % the range of admissible values. This may lead to quantization error % differences between the input and output images values. %__________________________________________________________________________ % Copyright (C) 2009-2012 Wellcome Trust Centre for Neuroimaging % John Ashburner % $Id: spm_file_merge.m 5040 2012-11-07 12:36:23Z guillaume $ %-Input: V %-------------------------------------------------------------------------- if ~nargin [V,sts] = spm_select([1 Inf],'image','Select images to concatenate'); if ~sts, return; end end if ischar(V) V = spm_vol(V); elseif iscellstr(V) V = spm_vol(char(V)); end ind = cat(1,V.n); N = cat(1,V.private); %-Input: fname %-------------------------------------------------------------------------- cwd = fileparts(V(1).fname); if isempty(cwd), cwd = pwd; end if nargin < 2 fname = fullfile(cwd,'4D.nii'); else [p,n,e] = fileparts(fname); if isempty(e), fname = [fname '.nii']; end if isempty(p), fname = fullfile(cwd, fname); end end %-Input: dtype %-------------------------------------------------------------------------- if nargin < 3 dt = 0; end if dt == 0 dt = V(1).dt(1); end %-Set scalefactors and offsets %========================================================================== d = cat(1,V.dt); d = d(:,1); s = cat(2,V.pinfo); s = s(1,:); o = cat(2,V.pinfo); o = o(2,:); %-Reuse parameters of input images if same scalefactor, offset and datatype %-------------------------------------------------------------------------- if length(unique(s)) == 1 && length(unique(o)) == 1 ... && length(unique(d)) == 1 && d(1) == dt sf = V(1).pinfo(1); off = V(1).pinfo(2); else dmx = spm_type(dt,'maxval'); dmn = spm_type(dt,'minval'); %-Integer datatypes: scale to min/max of overall data %---------------------------------------------------------------------- if isfinite(dmx) spm_progress_bar('Init',numel(V),'Computing scale factor','Volumes Complete'); mx = -Inf; mn = Inf; for i=1:numel(V) dat = V(i).private.dat(:,:,:,ind(i,1),ind(i,2)); dat = dat(isfinite(dat)); mx = max(mx,max(dat(:))); mn = min(mn,min(dat(:))); spm_progress_bar('Set',i); end spm_progress_bar('Clear'); if isempty(mx), mx = 0; end if isempty(mn), mn = 0; end if mx~=mn if dmn < 0 sf = max(mx/dmx,-mn/dmn); else sf = mx/dmx; end off = 0; else sf = mx/dmx; off = 0; end %-floating precison: no scaling %---------------------------------------------------------------------- else sf = 1; off = 0; end end %-Create and write 4D volume image %========================================================================== spm_unlink(fname); ni = nifti; ni.dat = file_array(fname,... [V(1).dim numel(V)],... [dt spm_platform('bigend')],... 0,... sf,... off); ni.mat = N(1).mat; ni.mat0 = N(1).mat; ni.descrip = '4D image'; create(ni); spm_progress_bar('Init',size(ni.dat,4),'Saving 4D image','Volumes Complete'); for i=1:size(ni.dat,4) ni.dat(:,:,:,i) = N(i).dat(:,:,:,ind(i,1),ind(i,2)); spm_get_space([ni.dat.fname ',' num2str(i)], V(i).mat); spm_progress_bar('Set',i); end spm_progress_bar('Clear'); if nargout V4 = spm_vol(ni.dat.fname); end