[797475]: / dicom_and_image_tools / segment / dicom2nifti.py

Download this file

118 lines (81 with data), 3.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import sys
import argparse
import os
import SimpleITK as sitk # pylint: disable=F0401
def process_command_line(argv):
'''Parse the command line and do a first-pass on processing them into a
format appropriate for the rest of the script.'''
parser = argparse.ArgumentParser(formatter_class=argparse.
ArgumentDefaultsHelpFormatter)
parser.add_argument(
"--dicomdirs", nargs="+",
help="The dicom directories to operate on.")
parser.add_argument(
"--out_dir",
help="The directory to deposit the output files.")
parser.add_argument(
"--json", default=None,
help="Depost a JSON file with metadata at this path.")
args = parser.parse_args(argv[1:])
return args
def dicom_files(indir):
'''Returns a list of the names of all files in a dicom series given the
directory in which they're stored. The list is sorted based upon the
SliceLocation DICOM parameter'''
import dicom
slices = [(f, dicom.read_file(os.path.join(indir, f)))
for f in os.listdir(indir)]
slices.sort(key=lambda x: x[1].SliceLocation)
return [os.path.join(indir, x[0]) for x in slices]
def dicom_hash(dicom):
'''Compute an the sha1 hash of the contents of a dicom stack. Returns the
hexadecimal representation as a string.'''
import hashlib
sha = hashlib.sha1()
for dcm in dicom_files(dicom):
with open(dcm, 'rb') as f:
sha.update(f.read())
return sha.hexdigest()
def load_dicom(dicomdir):
'''Load the directory dicomdir as a sitk image.'''
reader = sitk.ImageSeriesReader()
reader.SetFileNames(dicom_files(dicomdir))
return reader.Execute()
def dicom_to_nii(indir, output):
'''Convert an input dicom directory to a nii file.'''
img = load_dicom(indir)
out = sitk.ImageFileWriter()
out.SetFileName(output)
out.Execute(img)
def convert_to_nii(dicom_in, nifti_dir):
'''Convert the given dicom directory (dicom_in) into a nifti formatted
image and place it in nifti_dir using an md5 hash of its contents.
Returns the absolute path of the output file'''
try:
os.makedirs(nifti_dir)
except OSError:
# no need to do anything if the directory already exists.
pass
sha = dicom_hash(dicom_in)
outname = os.path.join(nifti_dir, sha+".nii")
dicom_to_nii(dicom_in, outname)
return sha
def main(argv=None):
'''Run the driver script for this module. This code only runs if we're
being run as a script. Otherwise, it's silent and just exposes methods.'''
args = process_command_line(argv)
info = {}
for dicomdir in args.dicomdirs:
sha = convert_to_nii(dicomdir, args.out_dir)
info[sha] = {}
info[sha]['file'] = os.path.abspath(dicomdir)
info[sha]['zslices'] = len(dicom_files(dicomdir))
if args.json is not None:
import json
with open(args.json, 'w') as f:
json_out = json.dumps(info, sort_keys=True,
indent=4, separators=(',', ': '))
f.write(json_out)
return 1
if __name__ == "__main__":
sys.exit(main(sys.argv))