projection.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. %% Author: Rodrigo de Barros Vimieiro
  2. % Date: April, 2018
  3. % rodrigo.vimieiro@gmail.com
  4. % =========================================================================
  5. %{
  6. % -------------------------------------------------------------------------
  7. % projection(data3d,param,projNumber)
  8. % -------------------------------------------------------------------------
  9. % DESCRIPTION:
  10. % This function calculates for each detector pixel, which voxel is
  11. % associated with that pixel in the specific projection. That is done
  12. % for all angles specified.
  13. % The geometry is for DBT with half cone-beam. All parameters are set
  14. % in "ParameterSettings" code.
  15. %
  16. % INPUT:
  17. %
  18. % - data3d = 3D volume for projection
  19. % - param = Parameter of all geometry
  20. % - projNumber = Vector with projections numbers to be processed
  21. %
  22. % OUTPUT:
  23. %
  24. % - proj = projection for each angle.
  25. %
  26. % Reference: Patent US5872828
  27. %
  28. % ---------------------------------------------------------------------
  29. % Copyright (C) <2018> <Rodrigo de Barros Vimieiro>
  30. %
  31. % This program is free software: you can redistribute it and/or modify
  32. % it under the terms of the GNU General Public License as published by
  33. % the Free Software Foundation, either version 3 of the License, or
  34. % (at your option) any later version.
  35. %
  36. % This program is distributed in the hope that it will be useful,
  37. % but WITHOUT ANY WARRANTY; without even the implied warranty of
  38. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39. % GNU General Public License for more details.
  40. %
  41. % You should have received a copy of the GNU General Public License
  42. % along with this program. If not, see <http://www.gnu.org/licenses/>.
  43. %}
  44. % =========================================================================
  45. %% Projection Code
  46. function proj = projection(data3d,param,projNumber)
  47. global animation
  48. % Get parameters from struct
  49. DSR = param.DSR;
  50. DDR = param.DDR;
  51. tubeAngle = deg2rad(param.tubeDeg);
  52. numVPixels = param.nv;
  53. numUPixels = param.nu;
  54. numYVoxels = param.ny;
  55. numXVoxels = param.nx;
  56. numSlices = param.nz;
  57. numProjs = param.nProj;
  58. zCoords = param.zs; % Z object coordinates
  59. % Test if there's specific angles
  60. if(isempty(projNumber))
  61. projNumber = 1:numProjs;
  62. else
  63. if(max(projNumber(:)) <= numProjs)
  64. numProjs = size(projNumber,2);
  65. else
  66. error('Projection number exceeds the maximum for the equipment.')
  67. end
  68. end
  69. % Stack of projections
  70. proj = zeros(param.nv, param.nu, numProjs, 'single');
  71. % Detector Coordinate system in (mm)
  72. [uCoord,vCoord] = meshgrid(param.us,param.vs);
  73. % Object Coordinate system in (mm) (just for 3D visualization)
  74. [xCoord,yCoord] = meshgrid(param.xs,param.ys);
  75. [ ~ ,zCoord] = meshgrid(param.ys,param.zs);
  76. fprintf('%2d/%2d', 1, numProjs)
  77. % For each projection
  78. for p=1:numProjs
  79. fprintf('\b\b\b\b\b%2d/%2d', p, numProjs)
  80. % Get specific projection number
  81. projN = projNumber(p);
  82. % Get specific tube angle for the projection
  83. teta = tubeAngle(projN);
  84. % Temporary projection variable to acumulate all projection from the slices
  85. proj_tmp = zeros(numVPixels, numUPixels, 'single');
  86. % For each slice
  87. for nz=1:numSlices
  88. % Calculates a relation of detector and voxel coordinates
  89. pyCoord = ((vCoord.*((DSR.*cos(teta))+DDR-zCoords(nz)))-(zCoords(nz).*DSR.*sin(teta)))./...
  90. (DSR.*cos(teta)+DDR);
  91. pxCoord = (uCoord.*((DSR.*cos(teta))+DDR-zCoords(nz)))./...
  92. ((DSR.*cos(teta))+DDR);
  93. % 3D Visualization
  94. if(nz==numSlices && animation == 1)
  95. figure(1)
  96. % Calculus of projection on the detector for visualization
  97. pvCoord = yCoord+((zCoords(nz).*((DSR.*sin(teta))+ yCoord))./...
  98. ((DSR.*cos(teta))-zCoords(nz)));
  99. puCoord = (xCoord.*DSR.*cos(teta))./ ...
  100. ((DSR.*cos(teta))-zCoords(nz));
  101. % Draw 3D animation
  102. draw3d(xCoord,yCoord,zCoord,puCoord,pvCoord,param,projN,teta);
  103. end
  104. % Coordinate in pixel of slice plane axis origin
  105. x0 = numXVoxels;
  106. y0 = numYVoxels/2;
  107. % Represent slice plane axis (X,Y) in the image plane axis (i,j) (covert mm to Pixels)
  108. pxCoord = -(pxCoord./param.dx) + x0;
  109. pyCoord = (pyCoord./param.dy) + y0;
  110. % Interpolation of the pixel coordinates of the "Slice" at the calculated pixel coordinates for the detector
  111. proj_tmp = proj_tmp + interp2(data3d(:,:,nz),pxCoord,pyCoord,'linear',0);
  112. end % Loop end slices
  113. % Converting attenuation coefficients to signal image + adding noise
  114. proj(:,:,p) = projImage(proj_tmp, param);
  115. if(animation == 1)
  116. % 2D Visualization
  117. figure(1)
  118. subplot(2,2,2)
  119. imshow(imrotate(data3d(:,:,round(numSlices/2)),90),[])
  120. title('Slice');axis on;
  121. subplot(2,2,4)
  122. imshow(imrotate(proj(:,:,p),90),[]); title(['Projection ',num2str(projN)]);axis on;
  123. end
  124. end % Loop end Projections
  125. end