save_untouch_slice.m 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. % Save back to the original image with a portion of slices that was
  2. % loaded by "load_untouch_nii". You can process those slices matrix
  3. % in any way, as long as their dimension is not altered.
  4. %
  5. % Usage: save_untouch_slice(slice, filename, ...
  6. % slice_idx, [img_idx], [dim5_idx], [dim6_idx], [dim7_idx])
  7. %
  8. % slice - a portion of slices that was loaded by "load_untouch_nii".
  9. % This should be a numeric matrix (i.e. only the .img field in the
  10. % loaded structure)
  11. %
  12. % filename - NIfTI or ANALYZE file name.
  13. %
  14. % slice_idx (depending on slice size) - a numerical array of image
  15. % slice indices, which should be the same as that you entered
  16. % in "load_untouch_nii" command.
  17. %
  18. % img_idx (depending on slice size) - a numerical array of image
  19. % volume indices, which should be the same as that you entered
  20. % in "load_untouch_nii" command.
  21. %
  22. % dim5_idx (depending on slice size) - a numerical array of 5th
  23. % dimension indices, which should be the same as that you entered
  24. % in "load_untouch_nii" command.
  25. %
  26. % dim6_idx (depending on slice size) - a numerical array of 6th
  27. % dimension indices, which should be the same as that you entered
  28. % in "load_untouch_nii" command.
  29. %
  30. % dim7_idx (depending on slice size) - a numerical array of 7th
  31. % dimension indices, which should be the same as that you entered
  32. % in "load_untouch_nii" command.
  33. %
  34. % Example:
  35. % nii = load_nii('avg152T1_LR_nifti.nii');
  36. % save_nii(nii, 'test.nii');
  37. % view_nii(nii);
  38. % nii = load_untouch_nii('test.nii','','','','','',[40 51:53]);
  39. % nii.img = ones(91,109,4)*122;
  40. % save_untouch_slice(nii.img, 'test.nii', [40 51:52]);
  41. % nii = load_nii('test.nii');
  42. % view_nii(nii);
  43. %
  44. % - Jimmy Shen (jimmy@rotman-baycrest.on.ca)
  45. %
  46. function save_untouch_slice(slice, filename, slice_idx, img_idx, dim5_idx, dim6_idx, dim7_idx)
  47. if ~exist('slice','var') | ~isnumeric(slice)
  48. msg = [char(10) '"slice" argument should be a portion of slices that was loaded' char(10)];
  49. msg = [msg 'by "load_untouch_nii.m". This should be a numeric matrix (i.e.' char(10)];
  50. msg = [msg 'only the .img field in the loaded structure).'];
  51. error(msg);
  52. end
  53. if ~exist('filename','var') | ~exist(filename,'file')
  54. error('In order to save back, original NIfTI or ANALYZE file must exist.');
  55. end
  56. if ~exist('slice_idx','var') | isempty(slice_idx) | ~isequal(size(slice,3),length(slice_idx))
  57. msg = [char(10) '"slice_idx" is a numerical array of image slice indices, which' char(10)];
  58. msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)];
  59. msg = [msg 'command.'];
  60. error(msg);
  61. end
  62. if ~exist('img_idx','var') | isempty(img_idx)
  63. img_idx = [];
  64. if ~isequal(size(slice,4),1)
  65. msg = [char(10) '"img_idx" is a numerical array of image volume indices, which' char(10)];
  66. msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)];
  67. msg = [msg 'command.'];
  68. error(msg);
  69. end
  70. elseif ~isequal(size(slice,4),length(img_idx))
  71. msg = [char(10) '"img_idx" is a numerical array of image volume indices, which' char(10)];
  72. msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)];
  73. msg = [msg 'command.'];
  74. error(msg);
  75. end
  76. if ~exist('dim5_idx','var') | isempty(dim5_idx)
  77. dim5_idx = [];
  78. if ~isequal(size(slice,5),1)
  79. msg = [char(10) '"dim5_idx" is a numerical array of 5th dimension indices, which' char(10)];
  80. msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)];
  81. msg = [msg 'command.'];
  82. error(msg);
  83. end
  84. elseif ~isequal(size(slice,5),length(img_idx))
  85. msg = [char(10) '"img_idx" is a numerical array of 5th dimension indices, which' char(10)];
  86. msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)];
  87. msg = [msg 'command.'];
  88. error(msg);
  89. end
  90. if ~exist('dim6_idx','var') | isempty(dim6_idx)
  91. dim6_idx = [];
  92. if ~isequal(size(slice,6),1)
  93. msg = [char(10) '"dim6_idx" is a numerical array of 6th dimension indices, which' char(10)];
  94. msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)];
  95. msg = [msg 'command.'];
  96. error(msg);
  97. end
  98. elseif ~isequal(size(slice,6),length(img_idx))
  99. msg = [char(10) '"img_idx" is a numerical array of 6th dimension indices, which' char(10)];
  100. msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)];
  101. msg = [msg 'command.'];
  102. error(msg);
  103. end
  104. if ~exist('dim7_idx','var') | isempty(dim7_idx)
  105. dim7_idx = [];
  106. if ~isequal(size(slice,7),1)
  107. msg = [char(10) '"dim7_idx" is a numerical array of 7th dimension indices, which' char(10)];
  108. msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)];
  109. msg = [msg 'command.'];
  110. error(msg);
  111. end
  112. elseif ~isequal(size(slice,7),length(img_idx))
  113. msg = [char(10) '"img_idx" is a numerical array of 7th dimension indices, which' char(10)];
  114. msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)];
  115. msg = [msg 'command.'];
  116. error(msg);
  117. end
  118. v = version;
  119. % Check file extension. If .gz, unpack it into temp folder
  120. %
  121. if length(filename) > 2 & strcmp(filename(end-2:end), '.gz')
  122. if ~strcmp(filename(end-6:end), '.img.gz') & ...
  123. ~strcmp(filename(end-6:end), '.hdr.gz') & ...
  124. ~strcmp(filename(end-6:end), '.nii.gz')
  125. error('Please check filename.');
  126. end
  127. if str2num(v(1:3)) < 7.1 | ~usejava('jvm')
  128. error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.');
  129. elseif strcmp(filename(end-6:end), '.img.gz')
  130. filename1 = filename;
  131. filename2 = filename;
  132. filename2(end-6:end) = '';
  133. filename2 = [filename2, '.hdr.gz'];
  134. tmpDir = tempname;
  135. mkdir(tmpDir);
  136. gzFileName = filename;
  137. filename1 = gunzip(filename1, tmpDir);
  138. filename2 = gunzip(filename2, tmpDir);
  139. filename = char(filename1); % convert from cell to string
  140. elseif strcmp(filename(end-6:end), '.hdr.gz')
  141. filename1 = filename;
  142. filename2 = filename;
  143. filename2(end-6:end) = '';
  144. filename2 = [filename2, '.img.gz'];
  145. tmpDir = tempname;
  146. mkdir(tmpDir);
  147. gzFileName = filename;
  148. filename1 = gunzip(filename1, tmpDir);
  149. filename2 = gunzip(filename2, tmpDir);
  150. filename = char(filename1); % convert from cell to string
  151. elseif strcmp(filename(end-6:end), '.nii.gz')
  152. tmpDir = tempname;
  153. mkdir(tmpDir);
  154. gzFileName = filename;
  155. filename = gunzip(filename, tmpDir);
  156. filename = char(filename); % convert from cell to string
  157. end
  158. end
  159. % Read the dataset header
  160. %
  161. [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename);
  162. if nii.filetype == 0
  163. nii.hdr = load_untouch0_nii_hdr(nii.fileprefix,nii.machine);
  164. else
  165. nii.hdr = load_untouch_nii_hdr(nii.fileprefix,nii.machine,nii.filetype);
  166. end
  167. % Clean up after gunzip
  168. %
  169. if exist('gzFileName', 'var')
  170. % fix fileprefix so it doesn't point to temp location
  171. %
  172. nii.fileprefix = gzFileName(1:end-7);
  173. % rmdir(tmpDir,'s');
  174. end
  175. [p,f] = fileparts(filename);
  176. fileprefix = fullfile(p, f);
  177. % fileprefix = nii.fileprefix;
  178. filetype = nii.filetype;
  179. if ~isequal( nii.hdr.dime.dim(2:3), [size(slice,1),size(slice,2)] )
  180. msg = [char(10) 'The first two dimensions of slice matrix should be the same as' char(10)];
  181. msg = [msg 'the first two dimensions of image loaded by "load_untouch_nii".'];
  182. error(msg);
  183. end
  184. % Save the dataset body
  185. %
  186. save_untouch_slice_img(slice, nii.hdr, filetype, fileprefix, ...
  187. nii.machine, slice_idx,img_idx,dim5_idx,dim6_idx,dim7_idx);
  188. % gzip output file if requested
  189. %
  190. if exist('gzFileName', 'var')
  191. [p,f] = fileparts(gzFileName);
  192. if filetype == 1
  193. gzip([fileprefix, '.img']);
  194. delete([fileprefix, '.img']);
  195. movefile([fileprefix, '.img.gz']);
  196. gzip([fileprefix, '.hdr']);
  197. delete([fileprefix, '.hdr']);
  198. movefile([fileprefix, '.hdr.gz']);
  199. elseif filetype == 2
  200. gzip([fileprefix, '.nii']);
  201. delete([fileprefix, '.nii']);
  202. movefile([fileprefix, '.nii.gz']);
  203. end;
  204. rmdir(tmpDir,'s');
  205. end;
  206. return % save_untouch_slice
  207. %--------------------------------------------------------------------------
  208. function save_untouch_slice_img(slice,hdr,filetype,fileprefix,machine,slice_idx,img_idx,dim5_idx,dim6_idx,dim7_idx)
  209. if ~exist('hdr','var') | ~exist('filetype','var') | ~exist('fileprefix','var') | ~exist('machine','var')
  210. error('Usage: save_untouch_slice_img(slice,hdr,filetype,fileprefix,machine,slice_idx,[img_idx],[dim5_idx],[dim6_idx],[dim7_idx]);');
  211. end
  212. if ~exist('slice_idx','var') | isempty(slice_idx) | hdr.dime.dim(4)<1
  213. slice_idx = [];
  214. end
  215. if ~exist('img_idx','var') | isempty(img_idx) | hdr.dime.dim(5)<1
  216. img_idx = [];
  217. end
  218. if ~exist('dim5_idx','var') | isempty(dim5_idx) | hdr.dime.dim(6)<1
  219. dim5_idx = [];
  220. end
  221. if ~exist('dim6_idx','var') | isempty(dim6_idx) | hdr.dime.dim(7)<1
  222. dim6_idx = [];
  223. end
  224. if ~exist('dim7_idx','var') | isempty(dim7_idx) | hdr.dime.dim(8)<1
  225. dim7_idx = [];
  226. end
  227. % check img_idx
  228. %
  229. if ~isempty(img_idx) & ~isnumeric(img_idx)
  230. error('"img_idx" should be a numerical array.');
  231. end
  232. if length(unique(img_idx)) ~= length(img_idx)
  233. error('Duplicate image index in "img_idx"');
  234. end
  235. if ~isempty(img_idx) & (min(img_idx) < 1 | max(img_idx) > hdr.dime.dim(5))
  236. max_range = hdr.dime.dim(5);
  237. if max_range == 1
  238. error(['"img_idx" should be 1.']);
  239. else
  240. range = ['1 ' num2str(max_range)];
  241. error(['"img_idx" should be an integer within the range of [' range '].']);
  242. end
  243. end
  244. % check dim5_idx
  245. %
  246. if ~isempty(dim5_idx) & ~isnumeric(dim5_idx)
  247. error('"dim5_idx" should be a numerical array.');
  248. end
  249. if length(unique(dim5_idx)) ~= length(dim5_idx)
  250. error('Duplicate index in "dim5_idx"');
  251. end
  252. if ~isempty(dim5_idx) & (min(dim5_idx) < 1 | max(dim5_idx) > hdr.dime.dim(6))
  253. max_range = hdr.dime.dim(6);
  254. if max_range == 1
  255. error(['"dim5_idx" should be 1.']);
  256. else
  257. range = ['1 ' num2str(max_range)];
  258. error(['"dim5_idx" should be an integer within the range of [' range '].']);
  259. end
  260. end
  261. % check dim6_idx
  262. %
  263. if ~isempty(dim6_idx) & ~isnumeric(dim6_idx)
  264. error('"dim6_idx" should be a numerical array.');
  265. end
  266. if length(unique(dim6_idx)) ~= length(dim6_idx)
  267. error('Duplicate index in "dim6_idx"');
  268. end
  269. if ~isempty(dim6_idx) & (min(dim6_idx) < 1 | max(dim6_idx) > hdr.dime.dim(7))
  270. max_range = hdr.dime.dim(7);
  271. if max_range == 1
  272. error(['"dim6_idx" should be 1.']);
  273. else
  274. range = ['1 ' num2str(max_range)];
  275. error(['"dim6_idx" should be an integer within the range of [' range '].']);
  276. end
  277. end
  278. % check dim7_idx
  279. %
  280. if ~isempty(dim7_idx) & ~isnumeric(dim7_idx)
  281. error('"dim7_idx" should be a numerical array.');
  282. end
  283. if length(unique(dim7_idx)) ~= length(dim7_idx)
  284. error('Duplicate index in "dim7_idx"');
  285. end
  286. if ~isempty(dim7_idx) & (min(dim7_idx) < 1 | max(dim7_idx) > hdr.dime.dim(8))
  287. max_range = hdr.dime.dim(8);
  288. if max_range == 1
  289. error(['"dim7_idx" should be 1.']);
  290. else
  291. range = ['1 ' num2str(max_range)];
  292. error(['"dim7_idx" should be an integer within the range of [' range '].']);
  293. end
  294. end
  295. % check slice_idx
  296. %
  297. if ~isempty(slice_idx) & ~isnumeric(slice_idx)
  298. error('"slice_idx" should be a numerical array.');
  299. end
  300. if length(unique(slice_idx)) ~= length(slice_idx)
  301. error('Duplicate index in "slice_idx"');
  302. end
  303. if ~isempty(slice_idx) & (min(slice_idx) < 1 | max(slice_idx) > hdr.dime.dim(4))
  304. max_range = hdr.dime.dim(4);
  305. if max_range == 1
  306. error(['"slice_idx" should be 1.']);
  307. else
  308. range = ['1 ' num2str(max_range)];
  309. error(['"slice_idx" should be an integer within the range of [' range '].']);
  310. end
  311. end
  312. write_image(slice,hdr,filetype,fileprefix,machine,slice_idx,img_idx,dim5_idx,dim6_idx,dim7_idx);
  313. return % save_untouch_slice_img
  314. %---------------------------------------------------------------------
  315. function write_image(slice,hdr,filetype,fileprefix,machine,slice_idx,img_idx,dim5_idx,dim6_idx,dim7_idx)
  316. if filetype == 2
  317. fid = fopen(sprintf('%s.nii',fileprefix),'r+');
  318. if fid < 0,
  319. msg = sprintf('Cannot open file %s.nii.',fileprefix);
  320. error(msg);
  321. end
  322. else
  323. fid = fopen(sprintf('%s.img',fileprefix),'r+');
  324. if fid < 0,
  325. msg = sprintf('Cannot open file %s.img.',fileprefix);
  326. error(msg);
  327. end
  328. end
  329. % Set bitpix according to datatype
  330. %
  331. % /*Acceptable values for datatype are*/
  332. %
  333. % 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN
  334. % 1 Binary (ubit1, bitpix=1) % DT_BINARY
  335. % 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8
  336. % 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16
  337. % 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32
  338. % 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32
  339. % 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64
  340. % 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64
  341. % 128 uint8 RGB (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24
  342. % 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8
  343. % 511 Single RGB (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96
  344. % 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16
  345. % 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32
  346. % 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64
  347. % 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64
  348. % 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128
  349. % 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128
  350. % 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128
  351. %
  352. switch hdr.dime.datatype
  353. case 2,
  354. hdr.dime.bitpix = 8; precision = 'uint8';
  355. case 4,
  356. hdr.dime.bitpix = 16; precision = 'int16';
  357. case 8,
  358. hdr.dime.bitpix = 32; precision = 'int32';
  359. case 16,
  360. hdr.dime.bitpix = 32; precision = 'float32';
  361. case 64,
  362. hdr.dime.bitpix = 64; precision = 'float64';
  363. case 128,
  364. hdr.dime.bitpix = 24; precision = 'uint8';
  365. case 256
  366. hdr.dime.bitpix = 8; precision = 'int8';
  367. case 511
  368. hdr.dime.bitpix = 96; precision = 'float32';
  369. case 512
  370. hdr.dime.bitpix = 16; precision = 'uint16';
  371. case 768
  372. hdr.dime.bitpix = 32; precision = 'uint32';
  373. case 1024
  374. hdr.dime.bitpix = 64; precision = 'int64';
  375. case 1280
  376. hdr.dime.bitpix = 64; precision = 'uint64';
  377. otherwise
  378. error('This datatype is not supported');
  379. end
  380. hdr.dime.dim(find(hdr.dime.dim < 1)) = 1;
  381. % move pointer to the start of image block
  382. %
  383. switch filetype
  384. case {0, 1}
  385. fseek(fid, 0, 'bof');
  386. case 2
  387. fseek(fid, hdr.dime.vox_offset, 'bof');
  388. end
  389. if hdr.dime.datatype == 1 | isequal(hdr.dime.dim(4:8),ones(1,5)) | ...
  390. (isempty(img_idx) & isempty(dim5_idx) & isempty(dim6_idx) & isempty(dim7_idx) & isempty(slice_idx))
  391. msg = [char(10) char(10) ' "save_untouch_slice" is used to save back to the original image a' char(10)];
  392. msg = [msg ' portion of slices that were loaded by "load_untouch_nii". You can' char(10)];
  393. msg = [msg ' process those slices matrix in any way, as long as their dimension' char(10)];
  394. msg = [msg ' is not changed.'];
  395. error(msg);
  396. else
  397. d1 = hdr.dime.dim(2);
  398. d2 = hdr.dime.dim(3);
  399. d3 = hdr.dime.dim(4);
  400. d4 = hdr.dime.dim(5);
  401. d5 = hdr.dime.dim(6);
  402. d6 = hdr.dime.dim(7);
  403. d7 = hdr.dime.dim(8);
  404. if isempty(slice_idx)
  405. slice_idx = 1:d3;
  406. end
  407. if isempty(img_idx)
  408. img_idx = 1:d4;
  409. end
  410. if isempty(dim5_idx)
  411. dim5_idx = 1:d5;
  412. end
  413. if isempty(dim6_idx)
  414. dim6_idx = 1:d6;
  415. end
  416. if isempty(dim7_idx)
  417. dim7_idx = 1:d7;
  418. end
  419. %ROMAN: begin
  420. roman = 1;
  421. if(roman)
  422. % compute size of one slice
  423. %
  424. img_siz = prod(hdr.dime.dim(2:3));
  425. % For complex float32 or complex float64, voxel values
  426. % include [real, imag]
  427. %
  428. if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792
  429. img_siz = img_siz * 2;
  430. end
  431. %MPH: For RGB24, voxel values include 3 separate color planes
  432. %
  433. if hdr.dime.datatype == 128 | hdr.dime.datatype == 511
  434. img_siz = img_siz * 3;
  435. end
  436. end; %if(roman)
  437. % ROMAN: end
  438. for i7=1:length(dim7_idx)
  439. for i6=1:length(dim6_idx)
  440. for i5=1:length(dim5_idx)
  441. for t=1:length(img_idx)
  442. for s=1:length(slice_idx)
  443. % Position is seeked in bytes. To convert dimension size
  444. % to byte storage size, hdr.dime.bitpix/8 will be
  445. % applied.
  446. %
  447. pos = sub2ind([d1 d2 d3 d4 d5 d6 d7], 1, 1, slice_idx(s), ...
  448. img_idx(t), dim5_idx(i5),dim6_idx(i6),dim7_idx(i7)) -1;
  449. pos = pos * hdr.dime.bitpix/8;
  450. % ROMAN: begin
  451. if(roman)
  452. % do nothing
  453. else
  454. img_siz = prod(hdr.dime.dim(2:3));
  455. % For complex float32 or complex float64, voxel values
  456. % include [real, imag]
  457. %
  458. if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792
  459. img_siz = img_siz * 2;
  460. end
  461. %MPH: For RGB24, voxel values include 3 separate color planes
  462. %
  463. if hdr.dime.datatype == 128 | hdr.dime.datatype == 511
  464. img_siz = img_siz * 3;
  465. end
  466. end; % if (roman)
  467. % ROMAN: end
  468. if filetype == 2
  469. fseek(fid, pos + hdr.dime.vox_offset, 'bof');
  470. else
  471. fseek(fid, pos, 'bof');
  472. end
  473. % For each frame, fwrite will write precision of value
  474. % in img_siz times
  475. %
  476. fwrite(fid, slice(:,:,s,t,i5,i6,i7), sprintf('*%s',precision));
  477. end
  478. end
  479. end
  480. end
  481. end
  482. end
  483. fclose(fid);
  484. return % write_image