view_nii_menu.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. % Imbed Zoom, Interp, and Info menu to view_nii window.
  2. %
  3. % Usage: view_nii_menu(fig);
  4. %
  5. % - Jimmy Shen (jimmy@rotman-baycrest.on.ca)
  6. %
  7. %--------------------------------------------------------------------
  8. function menu_hdl = view_nii_menu(fig, varargin)
  9. if isnumeric(fig)
  10. menu_hdl = init(fig);
  11. return;
  12. end
  13. menu_hdl = [];
  14. switch fig
  15. case 'interp'
  16. if nargin > 1
  17. fig = varargin{1};
  18. else
  19. fig = gcbf;
  20. end
  21. nii_menu = getappdata(fig, 'nii_menu');
  22. interp_on_state = get(nii_menu.Minterp,'Userdata');
  23. if (interp_on_state == 1)
  24. opt.useinterp = 1;
  25. view_nii(fig,opt);
  26. set(nii_menu.Minterp,'Userdata',0,'Label','Interp off');
  27. reset_zoom(fig);
  28. else
  29. opt.useinterp = 0;
  30. view_nii(fig,opt);
  31. set(nii_menu.Minterp,'Userdata',1,'Label','Interp on');
  32. reset_zoom(fig);
  33. end
  34. case 'reset_zoom'
  35. if nargin > 1
  36. fig = varargin{1};
  37. else
  38. fig = gcbf;
  39. end
  40. reset_zoom(fig);
  41. case 'orient'
  42. orient;
  43. case 'editvox'
  44. editvox;
  45. case 'img_info'
  46. img_info;
  47. case 'img_hist'
  48. img_hist;
  49. case 'save_disp'
  50. save_disp;
  51. end
  52. return % view_nii_menu
  53. %--------------------------------------------------------------------
  54. function menu_hdl = init(fig)
  55. % search for edit, view menu
  56. %
  57. nii_menu.Mfile = [];
  58. nii_menu.Medit = [];
  59. nii_menu.Mview = [];
  60. menuitems = findobj(fig, 'type', 'uimenu');
  61. for i=1:length(menuitems)
  62. filelabel = get(menuitems(i),'label');
  63. if strcmpi(strrep(filelabel, '&', ''), 'file')
  64. nii_menu.Mfile = menuitems(i);
  65. end
  66. editlabel = get(menuitems(i),'label');
  67. if strcmpi(strrep(editlabel, '&', ''), 'edit')
  68. nii_menu.Medit = menuitems(i);
  69. end
  70. viewlabel = get(menuitems(i),'label');
  71. if strcmpi(strrep(viewlabel, '&', ''), 'view')
  72. nii_menu.Mview = menuitems(i);
  73. end
  74. end
  75. set(fig, 'menubar', 'none');
  76. if isempty(nii_menu.Mfile)
  77. nii_menu.Mfile = uimenu('Parent',fig, ...
  78. 'Label','File');
  79. nii_menu.Mfile_save = uimenu('Parent',nii_menu.Mfile, ...
  80. 'Label','Save displayed image as ...', ...
  81. 'Callback','view_nii_menu(''save_disp'');');
  82. else
  83. nii_menu.Mfile_save = uimenu('Parent',nii_menu.Mfile, ...
  84. 'Label','Save displayed image as ...', ...
  85. 'separator','on', ...
  86. 'Callback','view_nii_menu(''save_disp'');');
  87. end
  88. if isempty(nii_menu.Medit)
  89. nii_menu.Medit = uimenu('Parent',fig, ...
  90. 'Label','Edit');
  91. nii_menu.Medit_orient = uimenu('Parent',nii_menu.Medit, ...
  92. 'Label','Convert to RAS orientation', ...
  93. 'Callback','view_nii_menu(''orient'');');
  94. nii_menu.Medit_editvox = uimenu('Parent',nii_menu.Medit, ...
  95. 'Label','Edit voxel value at crosshair', ...
  96. 'Callback','view_nii_menu(''editvox'');');
  97. else
  98. nii_menu.Medit_orient = uimenu('Parent',nii_menu.Medit, ...
  99. 'Label','Convert to RAS orientation', ...
  100. 'separator','on', ...
  101. 'Callback','view_nii_menu(''orient'');');
  102. nii_menu.Medit_editvox = uimenu('Parent',nii_menu.Medit, ...
  103. 'Label','Edit voxel value at crosshair', ...
  104. 'Callback','view_nii_menu(''editvox'');');
  105. end
  106. if isempty(nii_menu.Mview)
  107. nii_menu.Mview = uimenu('Parent',fig, ...
  108. 'Label','View');
  109. nii_menu.Mview_info = uimenu('Parent',nii_menu.Mview, ...
  110. 'Label','Image Information', ...
  111. 'Callback','view_nii_menu(''img_info'');');
  112. nii_menu.Mview_info = uimenu('Parent',nii_menu.Mview, ...
  113. 'Label','Volume Histogram', ...
  114. 'Callback','view_nii_menu(''img_hist'');');
  115. else
  116. nii_menu.Mview_info = uimenu('Parent',nii_menu.Mview, ...
  117. 'Label','Image Information', ...
  118. 'separator','on', ...
  119. 'Callback','view_nii_menu(''img_info'');');
  120. nii_menu.Mview_info = uimenu('Parent',nii_menu.Mview, ...
  121. 'Label','Volume Histogram', ...
  122. 'Callback','view_nii_menu(''img_hist'');');
  123. end
  124. nii_menu.Mzoom = rri_zoom_menu(fig);
  125. nii_menu.Minterp = uimenu('Parent',fig, ...
  126. 'Label','Interp on', ...
  127. 'Userdata', 1, ...
  128. 'Callback','view_nii_menu(''interp'');');
  129. setappdata(fig,'nii_menu',nii_menu);
  130. menu_hdl = nii_menu.Minterp;
  131. return % init
  132. %----------------------------------------------------------------
  133. function reset_zoom(fig)
  134. old_handle_vis = get(fig, 'HandleVisibility');
  135. set(fig, 'HandleVisibility', 'on');
  136. nii_view = getappdata(fig, 'nii_view');
  137. nii_menu = getappdata(fig, 'nii_menu');
  138. set(nii_menu.Mzoom,'Userdata',1,'Label','Zoom on');
  139. set(fig,'pointer','arrow');
  140. zoom off;
  141. axes(nii_view.handles.axial_axes);
  142. setappdata(get(gca,'zlabel'), 'ZOOMAxesData', ...
  143. [get(gca, 'xlim') get(gca, 'ylim')])
  144. % zoom reset;
  145. % zoom getlimits;
  146. zoom out;
  147. axes(nii_view.handles.coronal_axes);
  148. setappdata(get(gca,'zlabel'), 'ZOOMAxesData', ...
  149. [get(gca, 'xlim') get(gca, 'ylim')])
  150. % zoom reset;
  151. % zoom getlimits;
  152. zoom out;
  153. axes(nii_view.handles.sagittal_axes);
  154. setappdata(get(gca,'zlabel'), 'ZOOMAxesData', ...
  155. [get(gca, 'xlim') get(gca, 'ylim')])
  156. % zoom reset;
  157. % zoom getlimits;
  158. zoom out;
  159. set(fig, 'HandleVisibility', old_handle_vis);
  160. return; % reset_zoom
  161. %----------------------------------------------------------------
  162. function img_info
  163. nii_view = getappdata(gcbf, 'nii_view');
  164. hdr = nii_view.nii.hdr;
  165. max_value = num2str(double(max(nii_view.nii.img(:))));
  166. min_value = num2str(double(min(nii_view.nii.img(:))));
  167. dim = sprintf('%d %d %d', double(hdr.dime.dim(2:4)));
  168. vox = sprintf('%.3f %.3f %.3f', double(hdr.dime.pixdim(2:4)));
  169. if double(hdr.dime.datatype) == 1
  170. type = '1-bit binary';
  171. elseif double(hdr.dime.datatype) == 2
  172. type = '8-bit unsigned integer';
  173. elseif double(hdr.dime.datatype) == 4
  174. type = '16-bit signed integer';
  175. elseif double(hdr.dime.datatype) == 8
  176. type = '32-bit signed integer';
  177. elseif double(hdr.dime.datatype) == 16
  178. type = '32-bit single float';
  179. elseif double(hdr.dime.datatype) == 64
  180. type = '64-bit double precision';
  181. elseif double(hdr.dime.datatype) == 128
  182. type = '24-bit RGB true color';
  183. elseif double(hdr.dime.datatype) == 256
  184. type = '8-bit signed integer';
  185. elseif double(hdr.dime.datatype) == 511
  186. type = '96-bit RGB true color';
  187. elseif double(hdr.dime.datatype) == 512
  188. type = '16-bit unsigned integer';
  189. elseif double(hdr.dime.datatype) == 768
  190. type = '32-bit unsigned integer';
  191. elseif double(hdr.dime.datatype) == 1024
  192. type = '64-bit signed integer';
  193. elseif double(hdr.dime.datatype) == 1280
  194. type = '64-bit unsigned integer';
  195. end
  196. msg = {};
  197. msg = [msg {''}];
  198. msg = [msg {['Dimension: [', dim, ']']}];
  199. msg = [msg {''}];
  200. msg = [msg {['Voxel Size: [', vox, ']']}];
  201. msg = [msg {''}];
  202. msg = [msg {['Data Type: [', type, ']']}];
  203. msg = [msg {''}];
  204. msg = [msg {['Max Value: [', max_value, ']']}];
  205. msg = [msg {''}];
  206. msg = [msg {['Min Value: [', min_value, ']']}];
  207. msg = [msg {''}];
  208. if isfield(nii_view.nii, 'fileprefix')
  209. if isfield(nii_view.nii, 'filetype') & nii_view.nii.filetype == 2
  210. msg = [msg {['File Name: [', nii_view.nii.fileprefix, '.nii]']}];
  211. msg = [msg {''}];
  212. elseif isfield(nii_view.nii, 'filetype')
  213. msg = [msg {['File Name: [', nii_view.nii.fileprefix, '.img]']}];
  214. msg = [msg {''}];
  215. else
  216. msg = [msg {['File Prefix: [', nii_view.nii.fileprefix, ']']}];
  217. msg = [msg {''}];
  218. end
  219. end
  220. h = msgbox(msg, 'Image Information', 'modal');
  221. set(h,'color',[1 1 1]);
  222. return; % img_info
  223. %----------------------------------------------------------------
  224. function orient
  225. fig = gcbf;
  226. nii_view = getappdata(fig, 'nii_view');
  227. nii = nii_view.nii;
  228. if ~isempty(nii_view.bgimg)
  229. msg = 'You can not modify an overlay image';
  230. h = msgbox(msg, 'Error', 'modal');
  231. return;
  232. end
  233. old_pointer = get(fig,'Pointer');
  234. set(fig,'Pointer','watch');
  235. [nii orient] = rri_orient(nii);
  236. if isequal(orient, [1 2 3]) % do nothing
  237. set(fig,'Pointer',old_pointer);
  238. return;
  239. end
  240. oldopt = view_nii(fig);
  241. opt.command = 'updatenii';
  242. opt.usecolorbar = oldopt.usecolorbar;
  243. opt.usepanel = oldopt.usepanel;
  244. opt.usecrosshair = oldopt.usecrosshair;
  245. opt.usestretch = oldopt.usestretch;
  246. opt.useimagesc = oldopt.useimagesc;
  247. opt.useinterp = oldopt.useinterp;
  248. opt.setarea = oldopt.area;
  249. opt.setunit = oldopt.unit;
  250. opt.setviewpoint = oldopt.viewpoint;
  251. opt.setscanid = oldopt.scanid;
  252. opt.setcbarminmax = oldopt.cbarminmax;
  253. opt.setcolorindex = oldopt.colorindex;
  254. opt.setcolormap = oldopt.colormap;
  255. opt.setcolorlevel = oldopt.colorlevel;
  256. if isfield(oldopt,'highcolor')
  257. opt.sethighcolor = oldopt.highcolor;
  258. end
  259. view_nii(fig, nii, opt);
  260. set(fig,'Pointer',old_pointer);
  261. reset_zoom(fig);
  262. return; % orient
  263. %----------------------------------------------------------------
  264. function editvox
  265. fig = gcbf;
  266. nii_view = getappdata(fig, 'nii_view');
  267. if ~isempty(nii_view.bgimg)
  268. msg = 'You can not modify an overlay image';
  269. h = msgbox(msg, 'Error', 'modal');
  270. return;
  271. end
  272. nii = nii_view.nii;
  273. oldopt = view_nii(fig);
  274. sag = nii_view.imgXYZ.vox(1);
  275. cor = nii_view.imgXYZ.vox(2);
  276. axi = nii_view.imgXYZ.vox(3);
  277. if nii_view.nii.hdr.dime.datatype == 128
  278. imgvalue = [double(nii.img(sag,cor,axi,1,nii_view.scanid)) double(nii.img(sag,cor,axi,2,nii_view.scanid)) double(nii.img(sag,cor,axi,3,nii_view.scanid))];
  279. init_val = sprintf('%7.4g %7.4g %7.4g',imgvalue);
  280. elseif nii_view.nii.hdr.dime.datatype == 511
  281. R = double(nii.img(sag,cor,axi,1,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ...
  282. nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin;
  283. G = double(nii.img(sag,cor,axi,2,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ...
  284. nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin;
  285. B = double(nii.img(sag,cor,axi,3,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ...
  286. nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin;
  287. imgvalue = [R G B];
  288. init_val = sprintf('%7.4g %7.4g %7.4g',imgvalue);
  289. else
  290. imgvalue = double(nii.img(sag,cor,axi,nii_view.scanid));
  291. init_val = sprintf('%.6g',imgvalue);
  292. end
  293. old_pointer = get(fig,'Pointer');
  294. set(fig,'Pointer','watch');
  295. repeat = 1;
  296. while repeat
  297. if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511
  298. init_val = inputdlg({'Replace the current voxel values with 3 new numbers:'}, ...
  299. 'Edit voxel value at crosshair', 1, {num2str(init_val)});
  300. else
  301. init_val = inputdlg({'Replace the current voxel value with 1 new number:'}, ...
  302. 'Edit voxel value at crosshair', 1, {num2str(init_val)});
  303. end
  304. if isempty(init_val)
  305. set(fig,'Pointer',old_pointer);
  306. return
  307. end
  308. imgvalue = str2num(init_val{1});
  309. if ( (nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511) ...
  310. & length(imgvalue) ~= 3 ) | ...
  311. ( (nii_view.nii.hdr.dime.datatype ~= 128 & nii_view.nii.hdr.dime.datatype ~= 511) ...
  312. & length(imgvalue) ~= 1 )
  313. % do nothing
  314. else
  315. repeat = 0;
  316. end
  317. end
  318. if nii_view.nii.hdr.dime.datatype == 128
  319. nii.img(sag,cor,axi,1,nii_view.scanid) = imgvalue(1);
  320. nii.img(sag,cor,axi,2,nii_view.scanid) = imgvalue(2);
  321. nii.img(sag,cor,axi,3,nii_view.scanid) = imgvalue(3);
  322. elseif nii_view.nii.hdr.dime.datatype == 511
  323. nii.img(sag,cor,axi,1,nii_view.scanid) = (imgvalue(1) - nii_view.nii.hdr.dime.glmin) ...
  324. / (nii_view.nii.hdr.dime.glmax - nii_view.nii.hdr.dime.glmin);
  325. nii.img(sag,cor,axi,2,nii_view.scanid) = (imgvalue(2) - nii_view.nii.hdr.dime.glmin) ...
  326. / (nii_view.nii.hdr.dime.glmax - nii_view.nii.hdr.dime.glmin);
  327. nii.img(sag,cor,axi,3,nii_view.scanid) = (imgvalue(3) - nii_view.nii.hdr.dime.glmin) ...
  328. / (nii_view.nii.hdr.dime.glmax - nii_view.nii.hdr.dime.glmin);
  329. else
  330. nii.img(sag,cor,axi,nii_view.scanid) = imgvalue;
  331. end
  332. opt.command = 'updatenii';
  333. opt.usecolorbar = oldopt.usecolorbar;
  334. opt.usepanel = oldopt.usepanel;
  335. opt.usecrosshair = oldopt.usecrosshair;
  336. opt.usestretch = oldopt.usestretch;
  337. opt.useimagesc = oldopt.useimagesc;
  338. opt.useinterp = oldopt.useinterp;
  339. opt.setarea = oldopt.area;
  340. opt.setunit = oldopt.unit;
  341. opt.setviewpoint = oldopt.viewpoint;
  342. opt.setscanid = oldopt.scanid;
  343. opt.setcbarminmax = oldopt.cbarminmax;
  344. opt.setcolorindex = oldopt.colorindex;
  345. opt.setcolormap = oldopt.colormap;
  346. opt.setcolorlevel = oldopt.colorlevel;
  347. if isfield(oldopt,'highcolor')
  348. opt.sethighcolor = oldopt.highcolor;
  349. end
  350. view_nii(fig, nii, opt);
  351. set(fig,'Pointer',old_pointer);
  352. reset_zoom(fig);
  353. return; % editvox
  354. %----------------------------------------------------------------
  355. function save_disp
  356. [filename pathname] = uiputfile('*.*', 'Save displayed image as (*.nii or *.img)');
  357. if isequal(filename,0) | isequal(pathname,0)
  358. return;
  359. else
  360. out_imgfile = fullfile(pathname, filename); % original image file
  361. end
  362. old_pointer = get(gcbf,'Pointer');
  363. set(gcbf,'Pointer','watch');
  364. nii_view = getappdata(gcbf, 'nii_view');
  365. nii = nii_view.nii;
  366. try
  367. save_nii(nii, out_imgfile);
  368. catch
  369. msg = 'File can not be saved.';
  370. msgbox(msg, 'File write error', 'modal');
  371. end
  372. set(gcbf,'Pointer',old_pointer);
  373. return; % save_disp
  374. %----------------------------------------------------------------
  375. function img_hist
  376. nii_view = getappdata(gcbf, 'nii_view');
  377. N = hist(double(nii_view.nii.img(:)),256);
  378. x = linspace(double(min(nii_view.nii.img(:))), double(max(nii_view.nii.img(:))), 256);
  379. figure;bar(x,N);
  380. set(gcf, 'number', 'off', 'name', 'Volume Histogram');
  381. set(gcf, 'windowstyle', 'modal'); % no zoom ...
  382. xspan = max(x) - min(x) + 1;
  383. yspan = max(N) + 1;
  384. set(gca, 'xlim', [min(x)-xspan/20, max(x)+xspan/20]);
  385. set(gca, 'ylim', [-yspan/20, max(N)+yspan/20]);
  386. return; % img_hist