Save NIFTI dataset. Support both *.nii and *.hdr/*.img file extension. If file extension is not provided, *.hdr/*.img will be used as default. Usage: save_nii_cbi(nii, filename, [old_RGB]) nii.hdr - struct with NIFTI header fields. nii.img - 3D (or 4D) matrix of NIFTI data. filename - NIFTI file name. old_RGB - an optional boolean variable to handle special RGB data sequence [R1 R2 ... G1 G2 ... B1 B2 ...] that is used only by AnalyzeDirect (Analyze Software). Since both NIfTI and Analyze file format use RGB triple [R1 G1 B1 R2 G2 B2 ...] sequentially for each voxel, this variable is set to FALSE by default. If you would like the saved image only to be opened by AnalyzeDirect Software, set old_RGB to TRUE (or 1). Tip: to change the data type, set nii.hdr.dime.datatype, and nii.hdr.dime.bitpix to: 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN 1 Binary (ubit1, bitpix=1) % DT_BINARY 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 128 Red-Green-Blue (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 Part of this file is copied and modified under GNU license from MRI_TOOLBOX developed by CNSP in Flinders University, Australia NIFTI data format can be found on: http://nifti.nimh.nih.gov - Jimmy Shen (pls@rotman-baycrest.on.ca) - "old_RGB" related codes in "save_nii.m" are added by Mike Harms (2006.06.28)
0001 % Save NIFTI dataset. Support both *.nii and *.hdr/*.img file extension. 0002 % If file extension is not provided, *.hdr/*.img will be used as default. 0003 % 0004 % Usage: save_nii_cbi(nii, filename, [old_RGB]) 0005 % 0006 % nii.hdr - struct with NIFTI header fields. 0007 % nii.img - 3D (or 4D) matrix of NIFTI data. 0008 % filename - NIFTI file name. 0009 % 0010 % old_RGB - an optional boolean variable to handle special RGB data 0011 % sequence [R1 R2 ... G1 G2 ... B1 B2 ...] that is used only by 0012 % AnalyzeDirect (Analyze Software). Since both NIfTI and Analyze 0013 % file format use RGB triple [R1 G1 B1 R2 G2 B2 ...] sequentially 0014 % for each voxel, this variable is set to FALSE by default. If you 0015 % would like the saved image only to be opened by AnalyzeDirect 0016 % Software, set old_RGB to TRUE (or 1). 0017 % 0018 % Tip: to change the data type, set nii.hdr.dime.datatype, 0019 % and nii.hdr.dime.bitpix to: 0020 % 0021 % 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN 0022 % 1 Binary (ubit1, bitpix=1) % DT_BINARY 0023 % 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 0024 % 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 0025 % 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 0026 % 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 0027 % 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 0028 % 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 0029 % 128 Red-Green-Blue (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 0030 % 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 0031 % 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 0032 % 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 0033 % 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 0034 % 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 0035 % 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 0036 % 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 0037 % 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 0038 % 0039 % Part of this file is copied and modified under GNU license from 0040 % MRI_TOOLBOX developed by CNSP in Flinders University, Australia 0041 % 0042 % NIFTI data format can be found on: http://nifti.nimh.nih.gov 0043 % 0044 % - Jimmy Shen (pls@rotman-baycrest.on.ca) 0045 % - "old_RGB" related codes in "save_nii.m" are added by Mike Harms (2006.06.28) 0046 % 0047 function save_nii_cbi(nii, fileprefix, old_RGB) 0048 0049 if ~exist('nii','var') | isempty(nii) | ~isfield(nii,'hdr') | ... 0050 ~isfield(nii,'img') | ~exist('fileprefix','var') | isempty(fileprefix) 0051 0052 error('Usage: save_nii_cbi(nii, filename, [old_RGB])'); 0053 end 0054 0055 if ~exist('old_RGB','var'), old_RGB = 0; end 0056 0057 filetype = 1; 0058 0059 % Note: fileprefix is actually the filename you want to save 0060 % 0061 if findstr('.nii',fileprefix) 0062 filetype = 2; 0063 fileprefix = strrep(fileprefix,'.nii',''); 0064 end 0065 0066 if findstr('.hdr',fileprefix) 0067 fileprefix = strrep(fileprefix,'.hdr',''); 0068 end 0069 0070 if findstr('.img',fileprefix) 0071 fileprefix = strrep(fileprefix,'.img',''); 0072 end 0073 0074 write_nii(nii, filetype, fileprefix, old_RGB); 0075 0076 if filetype == 1 0077 0078 % So earlier versions of SPM can also open it with correct originator 0079 % 0080 M=[[diag(nii.hdr.dime.pixdim(2:4)) -[nii.hdr.hist.originator(1:3).*nii.hdr.dime.pixdim(2:4)]'];[0 0 0 1]]; 0081 save(fileprefix, 'M'); 0082 end 0083 0084 return % save_nii_cbi 0085 0086 0087 %----------------------------------------------------------------------------------- 0088 function write_nii(nii, filetype, fileprefix, old_RGB) 0089 0090 hdr = nii.hdr; 0091 0092 switch double(hdr.dime.datatype), 0093 case 1, 0094 hdr.dime.bitpix = int16(1 ); precision = 'ubit1'; 0095 case 2, 0096 hdr.dime.bitpix = int16(8 ); precision = 'uint8'; 0097 case 4, 0098 hdr.dime.bitpix = int16(16); precision = 'int16'; 0099 case 8, 0100 hdr.dime.bitpix = int16(32); precision = 'int32'; 0101 case 16, 0102 hdr.dime.bitpix = int16(32); precision = 'float32'; 0103 case 32, 0104 hdr.dime.bitpix = int16(64); precision = 'float32'; 0105 case 64, 0106 hdr.dime.bitpix = int16(64); precision = 'float64'; 0107 case 128, 0108 hdr.dime.bitpix = int16(24); precision = 'uint8'; 0109 case 256 0110 hdr.dime.bitpix = int16(8 ); precision = 'int8'; 0111 case 512 0112 hdr.dime.bitpix = int16(16); precision = 'uint16'; 0113 case 768 0114 hdr.dime.bitpix = int16(32); precision = 'uint32'; 0115 case 1024 0116 hdr.dime.bitpix = int16(64); precision = 'int64'; 0117 case 1280 0118 hdr.dime.bitpix = int16(64); precision = 'uint64'; 0119 case 1792, 0120 hdr.dime.bitpix = int16(128); precision = 'float64'; 0121 otherwise 0122 error('This datatype is not supported'); 0123 end 0124 0125 hdr.dime.glmax = round(double(max(nii.img(:)))); 0126 hdr.dime.glmin = round(double(min(nii.img(:)))); 0127 0128 if filetype == 2 0129 fid = fopen(sprintf('%s.nii',fileprefix),'w'); 0130 0131 if fid < 0, 0132 msg = sprintf('Cannot open file %s.nii.',fileprefix); 0133 error(msg); 0134 end 0135 0136 hdr.dime.vox_offset = 352; 0137 hdr.hist.magic = 'n+1'; 0138 save_nii_hdr_cbi(hdr, fid); 0139 else 0140 fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 0141 0142 if fid < 0, 0143 msg = sprintf('Cannot open file %s.hdr.',fileprefix); 0144 error(msg); 0145 end 0146 0147 hdr.dime.vox_offset = 0; 0148 hdr.hist.magic = 'ni1'; 0149 save_nii_hdr_cbi(hdr, fid); 0150 0151 fclose(fid); 0152 fid = fopen(sprintf('%s.img',fileprefix),'w'); 0153 end 0154 0155 ScanDim = double(hdr.dime.dim(5)); % t 0156 SliceDim = double(hdr.dime.dim(4)); % z 0157 RowDim = double(hdr.dime.dim(3)); % y 0158 PixelDim = double(hdr.dime.dim(2)); % x 0159 SliceSz = double(hdr.dime.pixdim(4)); 0160 RowSz = double(hdr.dime.pixdim(3)); 0161 PixelSz = double(hdr.dime.pixdim(2)); 0162 0163 x = 1:PixelDim; 0164 0165 if filetype == 2 0166 skip_bytes = double(hdr.dime.vox_offset) - 348; 0167 else 0168 skip_bytes = 0; 0169 end 0170 0171 if double(hdr.dime.datatype) == 128 0172 0173 % RGB planes are expected to be in the 4th dimension of nii.img 0174 % 0175 if(size(nii.img,4)~=3) 0176 error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); 0177 end 0178 0179 if old_RGB 0180 nii.img = permute(nii.img, [1 2 4 3 5]); 0181 else 0182 nii.img = permute(nii.img, [4 1 2 3 5]); 0183 end 0184 end 0185 0186 % For complex float32 or complex float64, voxel values 0187 % include [real, imag] 0188 % 0189 if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 0190 real_img = real(nii.img(:))'; 0191 nii.img = imag(nii.img(:))'; 0192 nii.img = [real_img; nii.img]; 0193 end 0194 0195 if skip_bytes 0196 fwrite(fid, ones(1,skip_bytes), 'uint8'); 0197 end 0198 0199 fwrite(fid, nii.img, precision); 0200 % fwrite(fid, nii.img, precision, skip_bytes); % error using skip 0201 fclose(fid); 0202 0203 return; % write_nii 0204