def Volume3DToDicom(imgObj, MetadataObj = None, outdir = "", format_templ = "%03d.dcm"): format_templ = os.path.join(outdir, format_templ) entire_region = imgObj.GetLargestPossibleRegion() fngen = itk.NumericSeriesFileNames.New() fngen.SetSeriesFormat(format_templ) fngen.SetStartIndex( entire_region.GetIndex()[2] ) fngen.SetEndIndex( entire_region.GetIndex()[2] + entire_region.GetSize()[2] - 1 ) fngen.SetIncrementIndex(1) if not MetadataObj is None: metadata_array_copy = itk.vector.itkMetaDataDictionary() # I had to create a set of metadata to avoid pointers issues metadata_list_objs = [ itk.MetaDataDictionary() for metadata_list in MetadataObj ] for metadata_list, temp_metadata in zip(MetadataObj, metadata_list_objs): for k,v in metadata_list.items(): temp_metadata[k] = v metadata_array_copy.append(temp_metadata) s,d = itk.template(imgObj)[1] dicom_io = itk.GDCMImageIO.New() writer_type = itk.Image[s,d] writer_otype = itk.Image[s,d-1] writer = itk.ImageSeriesWriter[writer_type, writer_otype].New() writer.SetInput(imgObj) writer.SetImageIO(dicom_io) writer.SetFileNames(fngen.GetFileNames()) if not MetadataObj is None: writer.SetMetaDataDictionaryArray(metadata_array_copy) writer.Update()
# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0.txt # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ==========================================================================*/ import itk md = itk.MetaDataDictionary() # one way of setting and retrieving double value in the dictionary dv = itk.MetaDataObject.D.New() dv.SetMetaDataObjectValue(10.0) md.Set("double", dv) print(md.Get("double")) # other way of setting and retrieving double value (leverages Python's # weak type system) md["double"] = 10.0 print(md["double"]) # Required for "NRRD_measurement frame" itk.MetaDataObject[itk.vector[itk.vector[itk.D]]].New()
def dcm_series_metadata(image, dirname, pattern='IM{}.dcm', metadata_dict=None): """ Return dicom series metadata per slice and filenames :param image: the full itk image to be saved as dicom series :param dirname: the directory name :param pattern: str pattern for the filenames to save, including a placeholder ('{}') for the slice number :param metadata_dict: dictionary of metadata for adding tags or overriding the default values. For example, metadata_dict={'0008|0060': 'US'} will override the default 'CT' modality and set it to 'US' (ultrasound) :return: metadata dictionaries per slice, slice filenames """ # The number of slices n = image.GetLargestPossibleRegion().GetSize().GetElement(2) # Shared properties for all the n slices: mdict = itk.MetaDataDictionary() # Series Instance UID mdict['0020|000e'] = generate_uid() # Study Instance UID mdict['0020|000d'] = generate_uid() # Pixel Spacing - TODO: not necessary - automatically saved spacing = image.GetSpacing() mdict['0028|0030'] = f'{spacing[0]}\\{spacing[1]}' # Spacing Between Slices mdict['0018|0088'] = str(spacing[2]) # Image Orientation (Patient) orientation_str = '\\'.join([ str(image.GetDirection().GetVnlMatrix().get(i, j)) for j in range(2) for i in range(3) ]) mdict['0020|0037'] = orientation_str # Number of Frames mdict['0028|0008'] = '1' # Number of Slices mdict['0054|0081'] = str(n) # Modality mdict['0008|0060'] = 'CT' if metadata_dict is not None: for key, val in metadata_dict.items(): mdict[key] = val # Per slice properties: mdict_list = [] filenames = [] for i in range(n): # copy the shared properties dict: mdict_i = itk.MetaDataDictionary(mdict) # Instance Number mdict_i['0020|0013'] = str(i + 1) # Image Position (Patient) position = image.TransformIndexToPhysicalPoint([0, 0, i]) position_str = '\\'.join([str(position[i]) for i in range(3)]) mdict_i['0020|0032'] = position_str mdict_list += [mdict_i] filenames += [str(Path(dirname) / pattern.format(i + 1))] return mdict_list, filenames