Reconstruction.m 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. %% Author: Rodrigo de Barros Vimieiro and Aleks Prša
  2. % Date: April, 2018; 2022
  3. % rodrigo.vimieiro@gmail.com / alex.prsa@gmail.com
  4. % =========================================================================
  5. %{
  6. %
  7. % DESCRIPTION:
  8. %
  9. % The goal of this software is to present an open source reconstruction
  10. % toolbox, which features the four basic types of DBT reconstruction,
  11. % with the possibility of different acquisition geometries. This
  12. % toolbox is intended for academic usage. Since it is an open source
  13. % toolbox, researchers are welcome to contribute to the current version
  14. % of the software.
  15. %
  16. % Department of Electrical and Computer Engineering,
  17. % São Carlos School of Engineering,
  18. % University of São Paulo,
  19. % São Carlos, Brazil.
  20. %
  21. % Faculty of Mathematic and Physics
  22. % University in Ljubljana
  23. % Ljubljana, Slovenia
  24. %
  25. % ---------------------------------------------------------------------
  26. % Copyright (C) <2018> <Rodrigo de Barros Vimieiro>
  27. %
  28. % This program is free software: you can redistribute it and/or modify
  29. % it under the terms of the GNU General Public License as published by
  30. % the Free Software Foundation, either version 3 of the License, or
  31. % (at your option) any later version.
  32. %
  33. % This program is distributed in the hope that it will be useful,
  34. % but WITHOUT ANY WARRANTY; without even the implied warranty of
  35. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  36. % GNU General Public License for more details.
  37. %
  38. % You should have received a copy of the GNU General Public License
  39. % along with this program. If not, see <http://www.gnu.org/licenses/>.
  40. %
  41. %}
  42. % =========================================================================
  43. %% Reconstruction Code %%
  44. close all;clear;clc
  45. %% Global parameters
  46. global showinfo saveinfo animation
  47. showinfo = uint8(1); % Show projection animation
  48. saveinfo = uint8(1); % Save reconstructed volume
  49. animation = uint8(1); % Graphical animation
  50. %% GUI - Data decision
  51. answer = questdlg(['Load Images or Create a Virtual Phantom?'], ...
  52. 'Data selection', ...
  53. 'Images', 'Virtual', 'Images');
  54. % Handle response
  55. switch answer
  56. case 'Virtual'
  57. fprintf('Creating a Virtual Phantom... \n')
  58. data = 2;
  59. case 'Images'
  60. answer = questdlg(['Load Clinical images, Microcalcification images or Noised images?'], ...
  61. 'Image selection', ...
  62. 'Clinical', 'Noised', 'Microcalcifications', 'Microcalcifications');
  63. switch answer
  64. case 'Clinical'
  65. fprintf('Loading Clinical images... \n')
  66. data = 1;
  67. case 'Noised'
  68. fprintf('Loading Noised images... \n')
  69. data = 1;
  70. case 'Microcalcifications'
  71. fprintf('Loading Microcalcifications images... \n')
  72. data = 1;
  73. otherwise
  74. fprintf('Cancelled by user \n');
  75. return;
  76. end
  77. end
  78. %% Load components
  79. addpath(genpath('Functions'));
  80. addpath(genpath('Parameters'));
  81. if(~exist('Output','dir'))
  82. mkdir('Output')
  83. saveinfo = 1;
  84. end
  85. addpath('Output');
  86. if(data == 1) % ** Dicom data **
  87. ParameterSettings_GE
  88. if(~exist(['Output',filesep,'Clinical'],'dir'))
  89. mkdir(['Output',filesep,'Clinical'])
  90. end
  91. % Load projection data
  92. path_User = userpath;
  93. path_ProjData = uigetdir(path_User);
  94. if(path_ProjData == 0)
  95. fprintf('Cancelled by user \n');
  96. return;
  97. else
  98. userpath(path_ProjData)
  99. fprintf('Reading DICOMs ')
  100. [dataProj,infoDicom] = readDicom(path_ProjData,parameter,answer);
  101. parameter.bitDepth = infoDicom(:,1).BitDepth;
  102. % Pre-process projections
  103. fprintf('\nPre-processing DICOMs... \n')
  104. [dataProj,parameter] = dataPreprocess(dataProj,parameter);
  105. dataProj = flip(dataProj, 2); % Source is on the left side
  106. % Transform intensity image in attenuation coefficients
  107. dataProj(dataProj == 0) = 1;
  108. dataProj = -log(dataProj./(2^16-1));
  109. if(numel(find(dataProj==inf)) ~= 0)
  110. error('Numeric error. Please, double-check if you input data has zeros on it')
  111. end
  112. end
  113. else % ** Virtual data **
  114. ParameterSettings_Phantom;
  115. if(~exist(['Output',filesep,'Virtual'],'dir'))
  116. mkdir(['Output',filesep,'Virtual'])
  117. end
  118. addpath(['Output',filesep,'Virtual']);
  119. % Create virtual phantom
  120. data3d = single(phantom(parameter));
  121. data3d(data3d<0) = eps;
  122. data3d = flip(data3d, 1); % Phantom in accordance with coordinate system
  123. data3d = flip(data3d, 2); % Source is on the left side
  124. % Make the projections
  125. if(animation || saveinfo)
  126. % Tomosynthesis
  127. figureScreenSize()
  128. fprintf('Creating projections ')
  129. dataProj = projection(data3d,parameter,[]);
  130. dataProj = flip(dataProj, 2); % Source is on the left side
  131. % Save phantom projection as DICOM
  132. filestring = ['Output',filesep,'Virtual',filesep,'Projections'];
  133. if(~exist(filestring))
  134. mkdir(filestring)
  135. end
  136. fprintf('\nWriting DICOM projections ')
  137. writeDcmProj(dataProj,filestring,parameter);
  138. if(saveinfo)
  139. fprintf('\nSaving projections... \n')
  140. save(['Output',filesep,'Virtual',filesep,'Projections.mat'],'dataProj','-v7.3')
  141. infoDicom = [];
  142. else
  143. load Projections.mat
  144. end
  145. else
  146. load Projections.mat
  147. end
  148. % Transform intensity image in attenuation coefficients
  149. dataProj(dataProj == 0) = 0.00001;
  150. dataProj = -log(dataProj./(2^16-1));
  151. dataProj = flip(dataProj, 2); % Source is on the left side
  152. if(numel(find(dataProj==inf)) ~= 0)
  153. error('Numeric error. Please, double-check if you input data has zeros on it')
  154. end
  155. end
  156. fprintf('Starting reconstruction');
  157. %% Set specific recon parameters
  158. nIter = [2,3,4,8]; % Iteration to be saved (MLEM or SART)
  159. filterType = 'FBP'; % Filter type: 'BP', 'FBP'
  160. cutoff = 0.7; % Percentage until cut off frequency (FBP)
  161. filterOrder = 4; % Butterworth filter order
  162. %% Reconstruction methods
  163. % ## Uncomment to use ##
  164. dataRecon3d = FBP(dataProj,filterType,cutoff,filterOrder,parameter);
  165. dataProj = flip(dataProj, 2);
  166. dataRecon3d{1,1} = flip(dataRecon3d{1,1}, 2);
  167. if(saveinfo)
  168. saveData(dataRecon3d,parameter,answer,[],infoDicom);
  169. end
  170. % ## Uncomment to use ##
  171. % dataRecon3d = MLEM(dataProj,nIter,parameter);
  172. % if(saveinfo)
  173. % saveData(dataRecon3d,parameter,answer,[],infoDicom);
  174. % end
  175. % ## Uncomment to use ##
  176. % dataRecon3d = SART(dataProj,nIter,parameter);
  177. % if(saveinfo)
  178. % saveData(dataRecon3d,parameter,answer,[],infoDicom);
  179. % end
  180. % ## Uncomment to use ##
  181. % dataRecon3d = SIRT(dataProj,nIter,parameter);
  182. % if(saveinfo)
  183. % saveData(dataRecon3d,parameter,answer,[],infoDicom);
  184. % end
  185. fprintf('\n\nFINISHED - Data stored in "Output" folder\n')
  186. %% Show info
  187. % DICOM images
  188. if(animation && data == 1)
  189. %{
  190. % Projected planes viewer
  191. figure("Name", 'Projections', NumberTitle='off')
  192. sliceViewer(dataProj);
  193. %figure("Name", 'Projections', NumberTitle='off')
  194. %montage(dataProj, 'Size', [5 5], 'DisplayRange', []);
  195. %
  196. % Reconstructed slice viewer
  197. figure("Name", 'Reconstructed images', NumberTitle='off')
  198. sliceViewer(dataRecon3d{1,1});
  199. %figure("Name", 'Reconstructed images', NumberTitle='off')
  200. %montage(dataRecon3d{1,1}, 'Size', [10 round(parameter.nz/10)], 'DisplayRange', []);
  201. %}
  202. end
  203. % Virtual Phantom
  204. if(animation && data == 2)
  205. %
  206. % Phantom slice viewer
  207. figure("Name", 'Phantom', NumberTitle='off')
  208. sliceViewer(data3d);
  209. %sliceViewer(imrotate(data3d, 90));
  210. %figure("Name", 'Phantom', NumberTitle='off')
  211. %orthosliceViewer(imrotate(data3d, 90));
  212. %figure("Name", 'Phantom', NumberTitle='off')
  213. %montage(imrotate(data3d, 90), 'Size', [10 parameter.nz/10], 'DisplayRange', []);
  214. %
  215. % Projected planes viewer
  216. figure("Name", 'Projections', NumberTitle='off')
  217. sliceViewer(dataProj);
  218. %sliceViewer(imrotate(dataProj, 90));
  219. %figure("Name", 'Projections', NumberTitle='off')
  220. %montage(imrotate(dataProj, 90), 'Size', [3 3], 'DisplayRange', []);
  221. %
  222. % Reconstructed slice viewer
  223. figure("Name", 'Reconstructed phantom', NumberTitle='off')
  224. sliceViewer(dataRecon3d{1,1});
  225. %sliceViewer(imrotate(dataRecon3d{1,1}, 90));
  226. %figure("Name", 'Phantom', NumberTitle='off')
  227. %orthosliceViewer(imrotate(dataRecon3d{1,1}, 90));
  228. %figure("Name", 'Reconstructed phantom', NumberTitle='off')
  229. %montage(imrotate(dataRecon3d{1,1}, 90), 'Size', [10 parameter.nz/10], 'DisplayRange', []);
  230. %{
  231. % 3D Backprojection Visualization
  232. figureScreenSize()
  233. for k=1:parameter.nz
  234. subplot(1,2,1)
  235. imshow(data3d(:,:,k))
  236. title(['Phantom slice ',num2str(k)]);axis on;
  237. subplot(1,2,2)
  238. imshow(dataRecon3d{1,end}(:,:,k),[])
  239. title(['Reconstructed slice ',num2str(k)]);axis on;
  240. pause(0.02)
  241. end
  242. %}
  243. end
  244. beep