1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19""" A SimpleITK example demonstrating how to convert and resize DICOM files
20 to common image types. """
21
22import argparse
23import csv
24import functools
25import itertools
26import multiprocessing
27import os
28import sys
29
30import SimpleITK as sitk
31
32
33def convert_image(input_file_name, output_file_name, new_width=None):
34 """ Convert a single DICOM image to a common image type. """
35 try:
37
38 image_file_reader.SetImageIO("GDCMImageIO")
39 image_file_reader.SetFileName(input_file_name)
40 image_file_reader.ReadImageInformation()
41 image_size = list(image_file_reader.GetSize())
42 if len(image_size) == 3 and image_size[2] == 1:
43 image_size[2] = 0
44 image_file_reader.SetExtractSize(image_size)
45 image = image_file_reader.Execute()
46 if new_width:
47 original_size = image.GetSize()
48 original_spacing = image.GetSpacing()
49 new_spacing = [
50 (original_size[0] - 1) * original_spacing[0] / (new_width - 1)
51 ] * 2
52 new_size = [
53 new_width,
54 int((original_size[1] - 1) * original_spacing[1] / new_spacing[1]),
55 ]
57 image1=image,
58 size=new_size,
60 interpolator=sitk.sitkLinear,
61 outputOrigin=image.GetOrigin(),
62 outputSpacing=new_spacing,
63 outputDirection=image.GetDirection(),
64 defaultPixelValue=0,
65 outputPixelType=image.GetPixelID(),
66 )
67
68 if image.GetNumberOfComponentsPerPixel() == 1:
72 return True
73 except RuntimeError:
74 return False
75
76
77def convert_images(input_file_names, output_file_names, new_width):
78 """ Convert multiple DICOM images in parallel to a common image type. """
79 MAX_PROCESSES = 15
80 with multiprocessing.Pool(processes=MAX_PROCESSES) as pool:
81 return pool.starmap(
82 functools.partial(convert_image, new_width=new_width),
83 zip(input_file_names, output_file_names),
84 )
85
86
87def positive_int(int_str):
88 """ Custom argparse type for positive integers. """
89 value = int(int_str)
90 if value <= 0:
91 raise argparse.ArgumentTypeError(int_str + " is not a positive integer value")
92 return value
93
94
95def directory(dir_name):
96 """ Custom argparse type for directory. """
97 if not os.path.isdir(dir_name):
98 raise argparse.ArgumentTypeError(dir_name + " is not a valid directory name")
99 return dir_name
100
101
102def main(argv=None):
103 """ Main function. """
104 parser = argparse.ArgumentParser(
105 description="Convert and resize DICOM files to common image types."
106 )
107 parser.add_argument(
108 "root_of_data_directory",
109 type=directory,
110 help="Path to the topmost directory containing data.",
111 )
112 parser.add_argument(
113 "output_file_extension",
114 help="Image file extension, this determines output file type " "(e.g. png) .",
115 )
116 parser.add_argument("--w", type=positive_int, help="Width of converted images.")
117 parser.add_argument("--od", type=directory, help="Output directory.")
118 args = parser.parse_args(argv)
119
120 input_file_names = []
121 for dir_name, _, file_names in os.walk(args.root_of_data_directory):
122 input_file_names += [
123 os.path.join(os.path.abspath(dir_name), fname) for fname in file_names
124 ]
125 if args.od:
126
127
128 file_names = [
129 os.path.join(os.path.abspath(args.od), str(i))
130 for i in range(len(input_file_names))
131 ]
132 else:
133 file_names = input_file_names
134 output_file_names = [
135 file_name + "." + args.output_file_extension for file_name in file_names
136 ]
137
138 res = convert_images(input_file_names, output_file_names, args.w)
139 input_file_names = list(itertools.compress(input_file_names, res))
140 output_file_names = list(itertools.compress(output_file_names, res))
141
142
143
144
145 dir_name = args.od if args.od else os.getcwd()
146 with open(os.path.join(dir_name, "file_names.csv"), mode="w", encoding='utf-8') as fp:
147 fp_writer = csv.writer(
148 fp, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL
149 )
150 fp_writer.writerow(["input file name", "output file name"])
151 for data in zip(input_file_names, output_file_names):
152 fp_writer.writerow(data)
153
154
155if __name__ == "__main__":
156 sys.exit(main())
Read an image file and return a SimpleITK Image.
SITKBasicFilters_EXPORT Image Resample(const Image &image1, Transform transform=itk::simple::Transform(), InterpolatorEnum interpolator=itk::simple::sitkLinear, double defaultPixelValue=0.0, PixelIDValueEnum outputPixelType=sitkUnknown, bool useNearestNeighborExtrapolator=false)
itk::simple::ResampleImageFilter Procedural Interface
SITKIO_EXPORT void WriteImage(const Image &image, const PathType &fileName, bool useCompression=false, int compressionLevel=-1)
WriteImage is a procedural interface to the ImageFileWriter. class which is convenient for many image...
Image RescaleIntensity(Image &&image1, double outputMinimum=0, double outputMaximum=255)
Applies a linear transformation to the intensity levels of the input Image .
Image Cast(const Image &image, PixelIDValueEnum pixelID)