SimpleITK  1.2.4
DicomSeriesReadModifyWrite/DicomSeriesReadModifySeriesWrite.py
1 #=========================================================================
2 #
3 # Copyright Insight Software Consortium
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0.txt
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17 #=========================================================================
18 
19 from __future__ import print_function
20 
21 import SimpleITK as sitk
22 
23 import sys, time, os
24 
25 if len( sys.argv ) < 3:
26  print( "Usage: python " + __file__ + " <input_directory_with_DICOM_series> <output_directory>" )
27  sys.exit ( 1 )
28 
29 
30 # Read the original series. First obtain the series file names using the
31 # image series reader.
32 data_directory = sys.argv[1]
33 series_IDs = sitk.ImageSeriesReader.GetGDCMSeriesIDs(data_directory)
34 if not series_IDs:
35  print("ERROR: given directory \""+data_directory+"\" does not contain a DICOM series.")
36  sys.exit(1)
37 series_file_names = sitk.ImageSeriesReader.GetGDCMSeriesFileNames(data_directory, series_IDs[0])
38 
39 series_reader = sitk.ImageSeriesReader()
40 series_reader.SetFileNames(series_file_names)
41 
42 # Configure the reader to load all of the DICOM tags (public+private):
43 # By default tags are not loaded (saves time).
44 # By default if tags are loaded, the private tags are not loaded.
45 # We explicitly configure the reader to load tags, including the
46 # private ones.
47 series_reader.MetaDataDictionaryArrayUpdateOn()
48 series_reader.LoadPrivateTagsOn()
49 image3D = series_reader.Execute()
50 
51 # Modify the image (blurring)
52 filtered_image = sitk.DiscreteGaussian(image3D)
53 
54 # Write the 3D image as a series
55 # IMPORTANT: There are many DICOM tags that need to be updated when you modify an
56 # original image. This is a delicate opration and requires knowlege of
57 # the DICOM standard. This example only modifies some. For a more complete
58 # list of tags that need to be modified see:
59 # http://gdcm.sourceforge.net/wiki/index.php/Writing_DICOM
60 
61 writer = sitk.ImageFileWriter()
62 # Use the study/series/frame of reference information given in the meta-data
63 # dictionary and not the automatically generated information from the file IO
64 writer.KeepOriginalImageUIDOn()
65 
66 # Copy relevant tags from the original meta-data dictionary (private tags are also
67 # accessible).
68 tags_to_copy = ["0010|0010", # Patient Name
69  "0010|0020", # Patient ID
70  "0010|0030", # Patient Birth Date
71  "0020|000D", # Study Instance UID, for machine consumption
72  "0020|0010", # Study ID, for human consumption
73  "0008|0020", # Study Date
74  "0008|0030", # Study Time
75  "0008|0050", # Accession Number
76  "0008|0060" # Modality
77 ]
78 
79 modification_time = time.strftime("%H%M%S")
80 modification_date = time.strftime("%Y%m%d")
81 
82 # Copy some of the tags and add the relevant tags indicating the change.
83 # For the series instance UID (0020|000e), each of the components is a number, cannot start
84 # with zero, and separated by a '.' We create a unique series ID using the date and time.
85 # tags of interest:
86 direction = filtered_image.GetDirection()
87 series_tag_values = [(k, series_reader.GetMetaData(0,k)) for k in tags_to_copy if series_reader.HasMetaDataKey(0,k)] + \
88  [("0008|0031",modification_time), # Series Time
89  ("0008|0021",modification_date), # Series Date
90  ("0008|0008","DERIVED\\SECONDARY"), # Image Type
91  ("0020|000e", "1.2.826.0.1.3680043.2.1125."+modification_date+".1"+modification_time), # Series Instance UID
92  ("0020|0037", '\\'.join(map(str, (direction[0], direction[3], direction[6],# Image Orientation (Patient)
93  direction[1],direction[4],direction[7])))),
94  ("0008|103e", series_reader.GetMetaData(0,"0008|103e") + " Processed-SimpleITK")] # Series Description
95 
96 for i in range(filtered_image.GetDepth()):
97  image_slice = filtered_image[:,:,i]
98  # Tags shared by the series.
99  for tag, value in series_tag_values:
100  image_slice.SetMetaData(tag, value)
101  # Slice specific tags.
102  image_slice.SetMetaData("0008|0012", time.strftime("%Y%m%d")) # Instance Creation Date
103  image_slice.SetMetaData("0008|0013", time.strftime("%H%M%S")) # Instance Creation Time
104  image_slice.SetMetaData("0020|0032", '\\'.join(map(str,filtered_image.TransformIndexToPhysicalPoint((0,0,i))))) # Image Position (Patient)
105  image_slice.SetMetaData("0020|0013", str(i)) # Instance Number
106 
107  # Write to the output directory and add the extension dcm, to force writing in DICOM format.
108  writer.SetFileName(os.path.join(sys.argv[2],str(i)+'.dcm'))
109  writer.Execute(image_slice)
110 sys.exit( 0 )