prepareCtSeries7-1-14.m 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. function prepareCtSeries(indir, outdir)
  2. % Usage:copy and paste the line belwo in MATLAB command line; change the
  3. % directory and name as needed
  4. % prepareCtSeries('C:\WiscPhotonkV\ratDICOMs', 'C:\WiscPhotonkV\ratDICOMs_Downsampled');
  5. % outdir = 'C:\WiscPhotonkV\ratDICOMs_2Downsampled';
  6. % indir = 'C:\WiscPhotonkV\ratDICOMs';
  7. ctvol = readCtSeries(indir);
  8. % reset orientation (dirty fix)
  9. ctvol.info.ImageOrientationPatient = [1;0;0;0;1;0];
  10. ctvol.info.PatientPosition = 'HFS';
  11. dsvol = simpleDownsampleCtVol(ctvol, [1 1 1]);
  12. if size(dsvol.data,1) > size(dsvol.data,2)
  13. fprintf('Padding unequal dimension CT\n');
  14. dsvol.data = padarray(dsvol.data, [0, size(dsvol.data,1) - size(dsvol.data,2), 0], -1000, 'post');
  15. elseif size(dsvol.data,1) < size(dsvol.data,2)
  16. fprintf('Padding unequal dimension CT\n');
  17. dsvol.data = padarray(dsvol.data, [size(dsvol.data,2) - size(dsvol.data,1), 0, 0], -1000, 'post');
  18. end
  19. writeCtVol(dsvol, outdir)
  20. function s = readCtSlice(filename)
  21. s.info = dicominfo(filename);
  22. s.data = single(dicomread(filename)) * s.info.RescaleSlope + s.info.RescaleIntercept;
  23. function ctvol = readCtSeries(indir)
  24. filelist = dir(indir);
  25. slices = arrayfun(@(x)readCtSlice(fullfile(indir, x.name)), filelist(3:end));
  26. [~, ix] = sort(arrayfun(@(x)x.info.ImagePositionPatient(3), slices));
  27. slices = slices(ix);
  28. ctvol.info = slices(1).info;
  29. ctvol.info.SliceThickness = slices(2).info.ImagePositionPatient(3) - slices(1).info.ImagePositionPatient(3);
  30. ctvol.data = cell2mat(reshape({slices.data}, [1 1 numel(slices)]));
  31. % ctinfs = arrayfun(@(x)dicominfo(fullfile(indir, x.name)), filelist(3:end), 'UniformOutput', false);
  32. % ctimgs = arrayfun(@(x)dicomread(fullfile(indir, x.name)), filelist(3:end), 'UniformOutput', false);
  33. % [~, ix] = sort(cellfun(@(x)x.ImagePositionPatient(3), ctinfs));
  34. % ctinfs = ctinfs(ix);
  35. % ctimgs = ctimgs(ix);
  36. % ctvol.info = ctinfs{1};
  37. % ctvol.info.SliceThickness = ctinfs{2}.ImagePositionPatient(3) - ctinfs{1}.ImagePositionPatient(3);
  38. % ctvol.data = cell2mat(reshape(ctimgs, [1 1 numel(ctimgs)]));
  39. function dsvol = simpleDownsampleCtVol(ctvol, dsfactor)
  40. meanFilter = ones(dsfactor) / prod(dsfactor);
  41. meanImg = imfilter(ctvol.data, meanFilter, 'same');
  42. dsvol.data = meanImg(1:dsfactor(1):end, 1:dsfactor(2):end, 1:dsfactor(3):end);
  43. dsvol.info = ctvol.info;
  44. dsvol.info.PixelSpacing = ctvol.info.PixelSpacing .* reshape(dsfactor(1:2), [], 1);
  45. dsvol.info.SliceThickness = ctvol.info.SliceThickness * dsfactor(3);
  46. function writeCtVol(ctvol, outdir)
  47. mkdir(outdir);
  48. % changes common to all slices
  49. ctvol.info.SeriesInstanceUID = dicomuid;
  50. ctvol.info.RescaleIntercept = min(ctvol.data(:));
  51. ctvol.info.RescaleSlope = (max(ctvol.data(:)) - min(ctvol.data(:))) / 65536;
  52. ctvol.data = uint16((ctvol.data - ctvol.info.RescaleIntercept) / ctvol.info.RescaleSlope);
  53. % ctvol.info
  54. for k = 1:size(ctvol.data, 3)
  55. info = rmfield(ctvol.info, 'SliceThickness');
  56. info.SOPInstanceUID = dicomuid;
  57. info.ImagePositionPatient(3) = ctvol.info.ImagePositionPatient(3) + (k-1) * ctvol.info.SliceThickness;
  58. dicomwrite(ctvol.data(:,:,k), fullfile(outdir, sprintf('CT.%s.%d.dcm', info.SeriesInstanceUID, k)), info, 'CreateMode', 'copy');
  59. end