dicomrt_rasterizeVoi.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. function [ROIS] = dicomrt_rasterizeVoi(VOI, ct, ct_xmesh, ct_ymesh, ct_zmesh)
  2. % See also: dicomrt_build3dVOI()
  3. % Check input
  4. % % % Commented for ease of downsample
  5. % % % [ct_temp,type_ct,label,PatientPosition]=dicomrt_checkinput(ct);
  6. % % % ct=dicomrt_varfilter(ct_temp);
  7. [VOI_temp]=dicomrt_checkinput(VOI);
  8. VOI=dicomrt_varfilter(VOI_temp);
  9. % TODO check VOI has to be 2D and along z
  10. % TODO(?) check x,y,zmesh has to be monotonic and unique
  11. % assistant variables
  12. xdim = length(ct_xmesh);
  13. ydim = length(ct_ymesh);
  14. zdim = length(ct_zmesh);
  15. voi2use = 1:size(VOI,1);
  16. [XMESH YMESH] = meshgrid(ct_xmesh, ct_ymesh);
  17. % Progress bar data
  18. h = waitbar(0, 'Rasterizing', 'Name', 'dicomrt_rasterizeVoi');
  19. for kk = 1:length(voi2use)
  20. waitbar(kk./length(voi2use), h, ['Rasterizing: ', VOI{kk,1}]);
  21. % For each voi create a matrix with just 1 and 0
  22. rasterVOI = zeros(xdim, ydim, zdim, 'int8');
  23. num_curves = numel(VOI{kk,2});
  24. for k = 1:num_curves
  25. % if k == 6 %% manual fix for hippocampus
  26. % continue
  27. % end
  28. % the N x 3 curve matrix
  29. curve = VOI{kk,2}{k};
  30. % skip empty curves
  31. numPoints = size(curve,1);
  32. if numPoints < 3
  33. continue;
  34. end
  35. % z coordinate of current VOI
  36. voi_z = VOI{kk,2}{k}(1,3);
  37. % find the appropriate slice
  38. % TODO can simplify this once I'm more confident
  39. dist_z = abs(ct_zmesh-voi_z);
  40. slice = find(dist_z == min(dist_z));
  41. % slice = find(abs(ct_zmesh-voi_z) < dz);
  42. if isempty(slice)
  43. warning('Can not find matching slice');
  44. error('Closest slice found at %f cm', min(abs(ct_zmesh-voi_z)));
  45. elseif numel(slice) > 1
  46. warning('Multiple matching slices found');
  47. % elseif dist_z(slice) >= abs(ct_zmesh(1)-ct_zmesh(2)) % grozomah
  48. % error('Closest slice found at %f cm', min(abs(ct_zmesh-voi_z)));
  49. end
  50. % binary mask of current curve
  51. if exist('InPolygon', 'file') == 3
  52. % favor the mex function for performance
  53. BW = InPolygon(XMESH,YMESH,curve(:,1),curve(:,2));
  54. else
  55. BW = inpolygon(XMESH,YMESH,curve(:,1),curve(:,2));
  56. end
  57. % merge with existing curve
  58. rasterVOI(:,:,slice) = int8(xor(BW, rasterVOI(:,:,slice)));
  59. end
  60. % Create contour polygon on X and Y plane
  61. Xcurves = cell(0);
  62. for slice = 1:size(rasterVOI, 1)
  63. B = bwboundaries(squeeze(rasterVOI(slice,:,:)));
  64. if ~isempty(B)
  65. for ii = 1:numel(B)
  66. % Here x, y, z vertices means coordinate along 1st, 2nd and 3rd dimension,
  67. % respectively as in line Xcurves{end+1} = cat(2, x, y, z);
  68. x_vertices = ct_xmesh(slice) * ones(size(B{ii}, 1), 1);
  69. y_vertices = interp1(1:numel(ct_ymesh), ct_ymesh, B{ii}(:,1));
  70. z_vertices = interp1(1:numel(ct_zmesh), ct_zmesh, B{ii}(:,2));
  71. Xcurves{end+1} = cat(2, x_vertices, y_vertices, z_vertices);
  72. end
  73. end
  74. end
  75. Ycurves = cell(0);
  76. for slice = 1:size(rasterVOI, 2)
  77. B = bwboundaries(squeeze(rasterVOI(:,slice,:)));
  78. if ~isempty(B)
  79. for ii = 1:numel(B)
  80. y_vertices = ct_ymesh(slice) * ones(size(B{ii}, 1), 1);
  81. x_vertices = interp1(1:numel(ct_xmesh), ct_xmesh, B{ii}(:,1));
  82. z_vertices = interp1(1:numel(ct_zmesh), ct_zmesh, B{ii}(:,2));
  83. Ycurves{end+1} = cat(2, x_vertices, y_vertices, z_vertices);
  84. end
  85. end
  86. end
  87. % Save the ROIs struct
  88. % ROIS{kk}.BW = rasterVOI;
  89. ROIS{kk}.name = VOI{kk,1};
  90. ROIS{kk}.Xcurves = Xcurves;
  91. ROIS{kk}.Ycurves = Ycurves;
  92. % legacy nomenclature: num_curves and curves both refer to Z dimension
  93. ROIS{kk}.num_curves = num_curves;
  94. for k = 1:num_curves
  95. ROIS{kk}.curves{k} = VOI{kk,2}{k};
  96. end
  97. ROIS{kk}.ind = int32(find(rasterVOI));
  98. ROIS{kk}.dim = [xdim ydim zdim];
  99. ROIS{kk}.pixdim = [abs(ct_xmesh(2)-ct_xmesh(1)) abs(ct_ymesh(2)-ct_ymesh(1)) abs(ct_zmesh(2)-ct_zmesh(1))];
  100. ROIS{kk}.start = [ct_xmesh(1) ct_ymesh(1) ct_zmesh(1)];
  101. ROIS{kk}.start_ind = '(1,1,1)';
  102. end
  103. delete(h);