def WriteDICOM_slice(self, pixel_array,filename, itemnumber=0, PhotometricInterpretation="MONOCHROME2"): from dicom.dataset import Dataset, FileDataset import numpy as np import datetime, time """ INPUTS: pixel_array: 2D numpy ndarray. If pixel_array is larger than 2D, errors. filename: string name for the output file. """ ## This code block was taken from the output of a MATLAB secondary ## capture. I do not know what the long dotted UIDs mean, but ## this code works. file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' ds = FileDataset(filename, {},file_meta = file_meta,preamble="\0"*128) ds.Modality = 'WSD' ds.ContentDate = str(datetime.date.today()).replace('-','') ds.ContentTime = str(time.time()) #milliseconds since the epoch ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421859172643143649' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 if PhotometricInterpretation=="MONOCHROME2": ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' elif PhotometricInterpretation=="RGB": ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' pixel_array = pixel_array[0] print pixel_array.shape ds.Columns = pixel_array.shape[0] ds.ItemNumber = str(itemnumber) ds.InstanceNumber = str(itemnumber) ds.SliceLocation = str(itemnumber) ds.Rows = pixel_array.shape[1] if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() ds.save_as(filename) return filename
def WriteDCMFile(pixel_array,filename): file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'RT Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' ds = FileDataset(filename, {},file_meta = file_meta,preamble="\0"*128) ds.Modality = 'RTIMAGE' ds.ContentDate = str(datetime.date.today()).replace('-','') ds.ContentTime = str(time.time()) #milliseconds since the epoch ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421859172643143649' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.SOPClassUID = 'RT Image Storage' ds.SecondaryCaptureDeviceManufacturer = 'Varian Medical Systems' ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.ImagePlanePixelSpacing=[0.392,0.392] ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 # ds.SmallestImagePixelValue = '\\x00\\x00' # ds.LargestImagePixelValue = '\\xff\\xff' ds.Columns =1024# pixel_array.shape[0] ds.Rows =764# pixel_array.shape[1] ds.RescaleSlope=1.0 ds.RescaleIntercept=1.0 # if type(pixel_array) != np.uint16: # pixel_array =np.uint16(pixel_array) ds.PixelData = pixel_array ds.save_as(filename,write_like_original=True) return
def write_dicom(pixel_array, filename): file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0" * 128) ds.Modality = 'WSD' ds.ContentDate = str(datetime.date.today()).replace('-', '') ds.ContentTime = str(time.time()) #milliseconds since the epoch ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421859172643143649' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() ds.save_as(filename)
def write_dicom(pixel_array, filename): file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684' file_meta.MediaStorageSOPInstanceUID += '411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' ds = FileDataset(filename, {}, file_meta=file_meta, preamble=b"\0"*128) ds.Modality = 'MR' ds.ContentDate = str(date.today()).replace('-', '') ds.ContentTime = str(time()) ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.1243139774123601752342712' ds.StudyInstanceUID += '87472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421' ds.SeriesInstanceUID += '859172643143649' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385' ds.SOPInstanceUID += '720736873780' ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 3.3.5' # Options ds.InstitutionName = "Imperial College London" ds.RepetitionTime = 300 # These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.Columns = pixel_array.shape[1] ds.Rows = pixel_array.shape[0] ds.PixelData = pixel_array.tostring() ds.save_as(filename) return 0
def write_dicom(pixel_array, index, filename): ## This code block was taken from the output of a MATLAB secondary ## capture. I do not know what the long dotted UIDs mean, but ## this code works. target_dir = '/'.join(filename.split('/')[:-1]) print(target_dir) mkdir_p(target_dir) file_meta = Dataset() ds = FileDataset(filename, {},file_meta = file_meta) ds.ContentDate = str(datetime.date.today()).replace('-','') ds.ContentTime = str(time.time()) #milliseconds since the epoch ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.InstanceNumber = index #ds.PhotometricInterpretation = bytes("MONOCHROME2", "UTF-8") ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 #ds.SmallestImagePixelValue = bytes('\\x00\\x00', 'UTF-8') #ds.LargestImagePixelValue = bytes('\\xff\\xff', 'UTF-8') ds.Columns = pixel_array.shape[1] ds.Rows = pixel_array.shape[0] if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() ds.save_as(filename)
def saveDicomFile(filename, patientName, patientId, gender, birthday, imageArray, transpose=False): meta = Dataset() SOPClassUID = "1.2.840.10008.5.1.4.1.1.2" # sop class UID dla obrazow CT meta.MediaStorageSOPClassUID = SOPClassUID # Wygenerowany unikalny UID date = datetime.datetime.now().strftime('%Y%m%d') # Obecny czas time = datetime.datetime.now().strftime('%H%M%S.%f') # Obecny czas randomUId = SOPClassUID + "." + date + time # Wygenerowany unikalny UID meta.MediaStorageSOPInstanceUID = randomUId # Wygenerowany unikalny UID meta.ImplementationClassUID = randomUId + "." + "1" # Wygenerowany unikalny UID dataSet = FileDataset(filename, {}, file_meta=meta, preamble=b"\0" * 128) # Utworzenie obiektu DICOM dataSet.PatientName = patientName # Imie pacjenta dataSet.PatientID = patientId # Id pacjenta dataSet.PatientBirthDate = birthday # Data urodzenia pacjenta dataSet.PatientSex = gender # Plec pacjenta dataSet.is_little_endian = True dataSet.is_implicit_VR = True dataSet.ContentDate = date # Czas utworzenia pliku (YYYY:MM:DD) dataSet.StudyDate = date # Czas ostatniego otworzenia obrazu (YYYY-MM-DD) dataSet.StudyTime = time # Czas ostatniego otworzenia obrazu (HH:MM:SS) dataSet.ContentTime = time # Czas utworzenia pliku (HH:MM:SS) dataSet.StudyInstanceUID = randomUId + "." + "2" # Wygenerowany unikalny UID dataSet.SeriesInstanceUID = randomUId + "." + "3" # Wygenerowany unikalny UID dataSet.SOPInstanceUID = randomUId + "." + "4" # Wygenerowany unikalny UID dataSet.SOPClassUID = "CT." + date + time # Wygenerowany unikalny UID dataSet.SamplesPerPixel = 1 # Liczba kanałów. 1 - dla skali szarosci dataSet.PhotometricInterpretation = "MONOCHROME2" # MONOCHROE - obraz jest w skali szarości, 2 - maksymalna wartosc wskazuje kolor bialy dataSet.PixelRepresentation = 0 # 0 - wartosci sa tylko dodatnie (unsigned) 1 - wartosci sa tez ujemne dataSet.HighBit = 15 # Najważniejszy bit w pliku z obrazem dataSet.BitsStored = 16 # Liczba bitow na jedna wartosc w obrazie dataSet.BitsAllocated = 16 # Liczba bitow na jedna wartosc ktora jest zaalokowana dla obrazu dataSet.SmallestImagePixelValue = b'\\x00\\x00' # Wskazanie minimalnej wartosci dla kanalu dataSet.LargestImagePixelValue = b'\\xff\\xff' # Wskazanie maksymalnej wartosci dla kanalu dataSet.Rows = imageArray.shape[1] # Liczba wierszy dataSet.Columns = imageArray.shape[0] # Liczba kolumn if imageArray.dtype != np.uint16: # Sprawdzenie czy wartosci sa w przedziale [0,255] imageArray = skimage.img_as_uint( imageArray) # Zamiana na wartosci w przedziale [0,255] if transpose == True: # Zamiana wierszy i kolumn (opcjonalne) dataSet.Rows = imageArray.shape[0] dataSet.Columns = imageArray.shape[1] dataSet.PixelData = imageArray.tostring() # Zapisanie obrazu dataSet.save_as(filename) # Zapisanie pliku na dysku
def write_dicom(pixel_array, filename): """ INPUTS: pixel_array: 2D or 3D numpy ndarray. filename: string name for the output file. """ file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.1' file_meta.MediaStorageSOPInstanceUID = '1.2' file_meta.ImplementationClassUID = '1.3' ds = FileDataset(filename, {}, file_meta=file_meta, preamble=b'\x00' * 128) ds.Modality = 'PET' # imaging modality name ds.ContentDate = str(datetime.date.today()).replace('-', '') ds.ContentTime = str(time.time()) # milliseconds since the epoch ds.StudyInstanceUID = '1.3' ds.SeriesInstanceUID = '1.3' ds.SOPInstanceUID = '1.3' ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 3.7.5' # Patient-related data ds.PatientName = 'Wawrzyniec L. Dobrucki' ds.PatientID = 'M12345' ds.PatientSex = 'M' ds.PatientBirthDate = '12/12/12' ds.SeriesNumber = 5 ds.SeriesDescription = 'test image' ds.SliceThickness = '0.5' # slice thickness in mm ds.PixelSpacing = '0.5' # pixel spacing or size in mm # These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 # unsigned (default) ds.HighBit = 15 ds.BitsStored = 16 # default ds.BitsAllocated = 16 # default ds.NumberOfFrames = 216 # number of frames for 3D files # ds.SmallestImagePixelValue = '\\x00\\x00' # ds.LargestImagePixelValue = '\\xff\\xff' ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() ds.save_as(filename) return
def write_dicom_mask(img_slice, ds_slice, slice_no, window, level, outputdirectory, mask_suffix, filepattern=".dcm"): series_number = ds_slice[0x0020, 0x0011].value base_fname = str(slice_no).zfill(6) filename = outputdirectory + os.path.sep + base_fname + "_" + str( series_number) + mask_suffix + filepattern ds = FileDataset(filename, ds_slice, file_meta=ds_slice.file_meta, preamble=b"\0" * 128) ds.SOPInstanceUID = ds_slice.SOPInstanceUID ds.SOPClassUID = "1.2.840.10008.5.1.4.1.1.2" ds.StudyID = "123" ds.PatientName = "Liver^Larry^H" # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = False # These are the necessary imaging components of the FileDataset object. (rows, cols) = img_slice.shape ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 # 0 for mask, 1=MIS AWL image ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.Columns = cols ds.Rows = rows ds.PixelData = img_slice.tobytes() image_type_val = ds_slice[0x0008, 0x0008].value image_type_val_str = "\\".join(str(x) for x in image_type_val) image_type_val_str2 = image_type_val_str.replace("ORIGINAL", "DERIVED", 1) ds.ImageType = image_type_val_str2 # display components ds.WindowCenter = [0] # 0028,1050 Window Center ds.WindowWidth = [1] # 0028,1051 Window Width ds.RescaleIntercept = 0 # 0028,1052 Rescale Intercept: 0 ds.RescaleSlope = 1 # 0028,1053 Rescale Slope: 1 ds.save_as(filename)
def writeDicom(ods, mrn, studyID, outdir): file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '0.0' file_meta.ImplementationClassUID = '0.0' ds = FileDataset(studyID, {}, file_meta=file_meta, preamble="\0" * 128) ds.Modality = ods.Modality if "Modality" in ods else "" ds.StudyDate = ods.StudyDate if "StudyDate" in ods else "" ds.StudyTime = ods.StudyTime if "StudyTime" in ods else "" ds.StudyInstanceUID = '0.0' ds.SeriesInstanceUID = '0.0' ds.SOPInstanceUID = '0.0' ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ## These are the necessary imaging components of the FileDataset object. ds.AccessionNumber = str(studyID) ds.PatientID = str(mrn) ds.StudyID = str(studyID) ds.PatientName = str(studyID) ds.PatientBirthDate = "00000000" ds.PatientAge = calculateAge( ods.StudyDate, ods.PatientBirthDate ) if "StudyDate" in ods and "PatientBirthDate" in ods else "" ds.PatientSex = ods.PatientSex if "PatientSex" in ods else "" ds.StudyDescription = ods.StudyDescription if "StudyDescription" in ods else "" ds.SeriesDescription = ods.SeriesDescription if "SeriesDescription" in ods else "" ds.ViewPosition = ods.ViewPosition if "ViewPosition" in ods else "" ds.InstanceNumber = ods.InstanceNumber if "InstanceNumber" in ods else "" ds.SeriesNumber = ods.SeriesNumber if "SeriesNumber" in ods else "" ds.SamplesPerPixel = ods.SamplesPerPixel if "SamplesPerPixel" in ods else "" ds.PhotometricInterpretation = ods.PhotometricInterpretation if "PhotometricInterpretation" in ods else "" ds.PixelRepresentation = ods.PixelRepresentation if "PixelRepresentation" in ods else "" ds.HighBit = ods.HighBit if "HighBit" in ods else "" ds.BitsStored = ods.BitsStored if "BitsStored" in ods else "" ds.BitsAllocated = ods.BitsAllocated if "BitsAllocated" in ods else "" ds.Columns = ods.Columns if "Columns" in ods else "" ds.Rows = ods.Rows if "Rows" in ods else "" ds.PixelData = ods.PixelData if "PixelData" in ods else "" filename = cleanString( str(studyID) + "_" + str(ds.SeriesNumber) + "_" + str(ds.InstanceNumber) + "_" + str(ds.Modality) + "_" + str(ds.StudyDescription) + "_" + str(ds.SeriesDescription) + "_" + str(ds.ViewPosition) + ".dcm") outpath = os.path.join(outdir, filename) ds.save_as(outpath) return
def writeDicom(pixel_array, filename): """ Source: https://codedump.io/share/qCDN4fOKcTAS/1/create-pydicom-file-from-numpy-array INPUTS: pixel_array: 2D numpy ndarray. If pixel_array is larger than 2D, errors. filename: string name for the output file. """ ## This code block was taken from the output of a MATLAB secondary ## capture. I do not know what the long dotted UIDs mean, but ## this code works. file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' ds = FileDataset(filename, {}, file_meta=file_meta, preamble=b'\x00' * 128) ds.Modality = 'WSD' ds.ContentDate = str(datetime.date.today()).replace('-', '') ds.ContentTime = str(time.time()) #milliseconds since the epoch ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421859172643143649' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() ds.save_as(filename) return
def write_dicom(pixel_array,filename): """ INPUTS: pixel_array: 2D numpy ndarray. If pixel_array is larger than 2D, errors. filename: string name for the output file. """ ## Metadata is captured from Osirix file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.4' file_meta.MediaStorageSOPInstanceUID = '1.2.276.0.7230010.3.1.4.680961.1356.1477424584.260802' file_meta.ImplementationClassUID = '1.2.276.0.7230010.3.0.3.6.0' ds = FileDataset(filename, {},file_meta = file_meta,preamble="\0"*128) ds.Modality = 'MR' ds.ContentDate = str(datetime.date.today()).replace('-','') ds.ContentTime = str(time.time()) #milliseconds since the epoch ds.StudyInstanceUID = '1.2.840.113619.2.40.20410.4.1101731106.1478904046.976759' ds.SeriesInstanceUID = '1.2.840.113619.2.40.20410.4.1101731106.1478904045.846068' ds.SOPInstanceUID = '1.2.840.113619.2.40.20410.4.1101731106.1478904123.170427' ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.4' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ds.SliceThickness = 2.4 ds.SpacingBetweenSlices = 2.4 ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 1 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() ds.save_as(filename) return
def write_dicom(pixel_array,index,filename): """ INPUTS: pixel_array: 2D numpy ndarray. If pixel_array is larger than 2D, errors. filename: string name for the output file. """ ## This code block was taken from the output of a MATLAB secondary ## capture. I do not know what the long dotted UIDs mean, but ## this code works. file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.2.3.4.5.6.7.8.9.00'+str(index) file_meta.ImplementationClassUID = '1.2.3.4.5.6.7.8.9.0' ds = FileDataset(filename, {},file_meta = file_meta,preamble="\0"*128) ds.Modality = 'WSD' ds.ContentDate = str(datetime.date.today()).replace('-','') ds.ContentTime = str(time.time()) #milliseconds since the epoch ds.StudyInstanceUID = '1.2.3.4.5.6.7.8.9' ds.SeriesInstanceUID = '1.2.3.4.5.6.7.8.9.00' ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3 by Linkingmed' ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() ds.save_as(filename) return
def convert(self,imagefile,dicomfile,ox=0,oy=0,oz=0,xv=[1,0,0],yv=[0,1,0]): file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.7' # file_meta.MediaStorageSOPInstanceUID = dicom.UID.generate_uid() file_meta.ImplementationClassUID = file_meta.MediaStorageSOPInstanceUID # Create the FileDataset instance (initially no data elements, but file_meta supplied) ds = FileDataset(dicomfile, {}, file_meta=file_meta, preamble=b"\0" * 128) img = Image.open(imagefile) # Add the data elements -- not trying to set all required here. Check DICOM standard ds.PatientName = str(imagefile) val = np.random.randint(1,99999) ds.PatientID = '%05d' % (val) ds.SOPInstanceUID = dicom.UID.generate_uid() ds.add_new(Tag(0x20, 0x32), 'DS', [ox,oy,oz]) ds.add_new(Tag(0x20, 0x37),'DS', xv+yv) ds.Columns = img.size[0] #img width ds.Rows = img.size[1] #img height #This is specific to the type of jpeg encoding #These parameters were obtained from the dicom created by using img2dcm tool of dcmtk #They seem to work for PIL loaded files if img.mode == 'L': ds.SamplesPerPixel=1 ds.PhotometricInterpretation= 'MONOCHROME2' # Should match img.mode elif img.mode == 'RGB': ds.SamplesPerPixel=3 ds.PhotometricInterpretation= 'RGB' # Should match img.mode ds.PixelSpacing = [1,1,1] ds.BitsAllocated= 8 ds.BitsStored=8 ds.HighBit=7 ds.PixelRepresentation=0 ds.LossyImageCompression='01' ds.LossyImageCompressionMethod= 'ISO_10918_1' #ds.TransferSyntaxIndex = '1.2.840.10008.1.2' ds.PixelData = np.array(img).tostring() ds.save_as(dicomfile)
def _write_numpy_2_dicom(pixel_array, dcmfilename): filename = dcmfilename[dcmfilename.index('-') + 1:dcmfilename.index('.mhd')] print(filename) for i in range(pixel_array.shape[0]): file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' # CT Image Storage file_meta.MediaStorageSOPInstanceUID = "1.2.3" # !! Need valid UID here for real work file_meta.ImplementationClassUID = "1.2.3.4" # !!! Need valid UIDs here ds = FileDataset(dcmfilename, {}, file_meta=file_meta, preamble="\0" * 128) ds.Modality = 'WSD' ds.ContentDate = str(datetime.date.today()).replace('-', '') ds.ContentTime = str(time.time()) # milliseconds since the epoch ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421859172643143649' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' ds.Columns = pixel_array.shape[1] ds.Rows = pixel_array.shape[2] ds.PixelData = pixel_array[i].tostring() dcm = "{0}{1}-{2}.dcm".format(output_path, filename, i) print("dcm filename = %s,shape = %s" % (dcm, pixel_array[0].shape)) ds.save_as(dcm)
def copyCTtoRTDose(self, path, ds, doseData, imageRow, imageCol, sliceCount, dgs): # Create a RTDose file for broadcasting. file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.2' # CT Image Storage # Needs valid UID file_meta.MediaStorageSOPInstanceUID = ds.file_meta.MediaStorageSOPInstanceUID file_meta.ImplementationClassUID = ds.file_meta.ImplementationClassUID #create DICOM RT-Dose object. rtdose = FileDataset(path + '/rtdose.dcm', {}, file_meta=file_meta, preamble="\0"*128) #No DICOM object standard. Use only required to avoid errors with viewers. rtdose.SOPInstanceUID = ds.SOPInstanceUID rtdose.SOPClassUID = '1.2.840.10008.5.1.4.1.1.481.2' rtdose.file_meta.TransferSyntaxUID = ds.file_meta.TransferSyntaxUID rtdose.PatientsName = ds.PatientsName rtdose.PatientID = ds.PatientID rtdose.PatientsBirthDate = ds.PatientsBirthDate #Crashed caused if no sex. try: rtdose.PatientsSex = ds.PatientsSex except: rtdose.PatientsSex, ds.PatientsSex = 'O', 'O' self.data.update({'images':ds}) rtdose.StudyDate = ds.StudyDate rtdose.StudyTime = ds.StudyTime rtdose.StudyInstanceUID = ds.StudyInstanceUID rtdose.SeriesInstanceUID = ds.SeriesInstanceUID rtdose.StudyID = ds.StudyID rtdose.SeriesNumber = ds.SeriesNumber rtdose.Modality = 'RTDOSE' rtdose.ImagePositionPatient = ds.ImagePositionPatient rtdose.ImageOrientationPatient = ds.ImageOrientationPatient rtdose.FrameofReferenceUID = ds.FrameofReferenceUID rtdose.PositionReferenceIndicator = ds.PositionReferenceIndicator rtdose.PixelSpacing = ds.PixelSpacing rtdose.SamplesperPixel = 1 rtdose.PhotometricInterpretation = 'MONOCHROME2' rtdose.NumberofFrames = sliceCount rtdose.Rows = imageRow rtdose.Columns = imageCol rtdose.BitsAllocated = 32 rtdose.BitsStored = 32 rtdose.HighBit = 31 rtdose.PixelRepresentation = 0 rtdose.DoseUnits = 'GY' rtdose.DoseType = 'PHYSICAL' rtdose.DoseSummationType = 'FRACTION' #In case spaceing tag is missing. if not ds.has_key('SpacingBetweenSlices'): ds.SpacingBetweenSlices = ds.SliceThickness #Ensure patient pos is on "Last slice". if fnmatch.fnmatch(ds.PatientPosition, 'FF*'): #For compliance with dicompyler update r57d9155cc415 which uses a reverssed slice ordering. doseData = doseData[::-1] rtdose.ImagePositionPatient[2] = ds.ImagePositionPatient[2] elif fnmatch.fnmatch(ds.PatientPosition, 'HF*'): rtdose.ImagePositionPatient[2] = ds.ImagePositionPatient[2] - (sliceCount-1)*ds.SpacingBetweenSlices #Create Type A(Relative) GFOV. rtdose.GridFrameOffsetVector = list(np.arange(0., sliceCount*ds.SpacingBetweenSlices,ds.SpacingBetweenSlices)) #Scaling from int to physical dose rtdose.DoseGridScaling = dgs #Store images in pixel_array(int) & Pixel Data(raw). rtdose.pixel_array = doseData rtdose.PixelData = doseData.tostring() #Tag required by dicompyler. plan_meta = Dataset() rtdose.ReferencedRTPlans = [] rtdose.ReferencedRTPlans.append([]) rtdose.ReferencedRTPlans[0] = plan_meta rtdose.ReferencedRTPlans[0].ReferencedSOPClassUID = 'RT Plan Storage' rtdose.ReferencedRTPlans[0].ReferencedSOPInstanceUID = ds.SOPInstanceUID #Create RTPlan to acticate DVH file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.5' # RT Plan Storage file_meta.MediaStorageSOPInstanceUID = ds.file_meta.MediaStorageSOPInstanceUID file_meta.ImplementationClassUID = ds.file_meta.ImplementationClassUID #create DICOM RT-Plan object. rtPlan = FileDataset(path + '/rtplan.dcm', {}, file_meta=file_meta, preamble="\0"*128) #No DICOM object standard. Use only required to avoid errora with viewers. rtPlan.SOPInstanceUID = ds.SOPInstanceUID rtPlan.SOPClassUID = '1.2.840.10008.5.1.4.1.1.481.5' rtPlan.ReferencedSOPInstanceUID = ds.SOPInstanceUID #Need to change rtPlan.file_meta.TransferSyntaxUID = ds.file_meta.TransferSyntaxUID rtPlan.PatientsName = ds.PatientsName rtPlan.PatientID = ds.PatientID rtPlan.PatientsSex = ds.PatientsSex rtPlan.PatientsBirthDate = ds.PatientsBirthDate rtPlan.RTPlanLabel = 'Simulation' rtPlan.RTPlanDate = ds.StudyDate rtPlan.RTPlanTime = ds.StudyTime rtPlan.Modality = 'RTPLAN' rtPlan.StudyInstanceUID = ds.StudyInstanceUID rtPlan.SeriesInstanceUID = ds.SeriesInstanceUID rtPlan.StudyID = ds.StudyID rtPlan.SeriesNumber = ds.SeriesNumber return rtdose, rtPlan
def write_dicom(pixel_array, filename, ds_ori, series_number, sop_id, series_description): """Write a dicom from a pixel_array (numpy). :param pixel_array: 2D numpy ndarray. If pixel_array is larger than 2D, errors. :param filename: string name for the output file. :param ds_ori: original pydicom object of the pixel_array :param series_number: number of the series being processed :param sop_id: SOPInstanceUID for the DICOM :param series_description: series description for Osirix display """ # Set the DICOM dataset file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = ds_ori.SOPInstanceUID file_meta.ImplementationClassUID = ds_ori.SOPClassUID ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0"*128) # Copy the tag from the original DICOM for tag, d_obj in ds_ori.items(): if tag != ds_ori.data_element("PixelData").tag: ds[tag] = d_obj # Other tags to set ds.SeriesNumber = series_number sop_uid = sop_id + str(datetime.datetime.now()).replace('-', '')\ .replace(':', '')\ .replace('.', '')\ .replace(' ', '') ds.SOPInstanceUID = sop_uid[:-1] ds.ProtocolName = '%s Verdict MAP' % series_description # Set SeriesDate/ContentDate now = datetime.date.today() ds.SeriesDate = '%d%02d%02d' % (now.year, now.month, now.day) ds.ContentDate = '%d%02d%02d' % (now.year, now.month, now.day) ds.Modality = 'MR' ds.ConversionType = 'WSD' ds.StudyDescription = 'INNOVATE' ds.SeriesDescription = series_description ds.AcquisitionNumber = 1 ds.SamplesperPixel = 1 ds.PhotometricInterpretation = 'MONOCHROME2' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' nb_frames = pixel_array.shape[2]*pixel_array.shape[3] ds.NumberOfFrames = nb_frames ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 8 ds.BitsAllocated = 8 ds.SmallestImagePixelValue = pixel_array.min() ds.LargestImagePixelValue = pixel_array.max() ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] # Fixing the sequence if the number of frames was less than the original # it happens if we remove the last volume for phillips data (mean) if ds_ori.NumberOfFrames > nb_frames: new_seq = Sequence() for i in xrange(0, ds_ori.NumberOfFrames): if i % 5 == 0: # take one slice for each (14) new_seq.append(ds_ori[0x5200, 0x9230][i]) ds[0x5200, 0x9230].value = new_seq # Organise the array: pixel_array2 = np.zeros((pixel_array.shape[0]*pixel_array.shape[2], pixel_array.shape[1])) for i in range(pixel_array.shape[2]): pixel_array2[pixel_array.shape[0]*i:pixel_array.shape[0]*(i+1), :] = pixel_array[:, :, i, 0] # Set the Image pixel array if pixel_array2.dtype != np.uint8: pixel_array2 = pixel_array2.astype(np.uint8) ds.PixelData = pixel_array2.tostring() # Save the image ds.save_as(filename)
# Required for Segmentation IOD ds.Modality = 'SEG' ds.SeriesNumber = '001' ds.ImageType = '1' # Derived = 1, Primary = 2 #Set image parameters ds.SpacingBetweenSlices = '2.0' ds.ImageOrientationPatient = ['-1', '0', '0', '0', '-1', '0'] ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = 'MONOCHROME2' ds.Rows = 109 ds.Columns = 91 ds.PixelSpacing = ['-2.0', '2.0'] ds.BitsAllocated = 8 # Binary = 1 ds.BitsStored = 8 # Binary = 1 ds.HighBit = 7 # Binary = 0 ds.SegmentationType = 'FRACTIONAL' #FRACTIONAL or BINARY ds.SegmentationFractionalType = 'OCCUPANCY' #Can be OCCUPANCY or PROBABILITY ds.MaximumFractionalValue = 116 # 116 is the number of labels in AAL ds.PixelRepresentation = 1 # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = True print "Writing test file", filename ds.save_as(filename) print "File saved."
def writeDicomFiles(self, filename): for i in range(1,len(self.PA)): #Image 0 is a null image for default display and will not be written out fileName = filename + str(i) + ".dcm" # print ("printing dicom file " + fileName) # Populate required values for file meta information file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' # Create the FileDataset instance (initially no data elements, but file_meta supplied) ds = FileDataset(fileName, {}, file_meta=file_meta, preamble="\0"*128) ds.Modality = 'MR' ds.ContentDate = str(datetime.date.today()).replace('-','') ds.ContentTime = str(time.time()) #milliseconds since the epoch ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421859172643143649' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.SOPClassUID = 'MR Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' #Add MRI data elements ds.bValue= self.bValue[i] ds.Columns=self.Columns[i] ds.FoVX=self.FoVX[i] ds.FoVY=self.FoVY[i] ds.ImageOrientationPatient=self.ImagePosition[i].tolist() ds.InstitutionName=self.InstitutionName[i] ds.PixelBandwidth= self.PixelBandwidth[i] ds.PixelSpacing =[self.PixelSpacingY[i],self.PixelSpacingX[i]] ds.Rows= self.Rows[i] ds.PatientName = self.PatientName[i] ds.PatientID = "123456" ds.ProtocolName=self.ProtocolName[i] ds.RepetitionTime = self.TR[i] ds.SeriesDescription=self.SeriesDescription[i] ds.EchoTime = self.TE[i] ds.FlipAngle= self.FA[i] ds.InversionTime=self.TI[i] ds.ImageOrientationPatient[3:6]=self.ColumnDirection[i].tolist() ds.ImageOrientationPatient[:3]=self.RowDirection[i].tolist() ds.MagneticFieldStrength = self.MagneticFieldStrength[i] ds.Manufacturer = self.Manufacturer[i] pixel_array=np.transpose(self.PA[i]) #numpy pixel array if self.DataType[i].lower() == "phase" : pixel_array=(pixel_array+np.pi) *10000 # phase data -pi to pi is converted to 0 to 10000pi #print "Adjusting phase to 16 bit integer" if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() # image byte data # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = True ds.save_as(fileName)
def WriteDICOM_slice(self, pixel_array, filename, itemnumber=0, PhotometricInterpretation="MONOCHROME2"): from dicom.dataset import Dataset, FileDataset import numpy as np import datetime, time """ INPUTS: pixel_array: 2D numpy ndarray. If pixel_array is larger than 2D, errors. filename: string name for the output file. """ ## This code block was taken from the output of a MATLAB secondary ## capture. I do not know what the long dotted UIDs mean, but ## this code works. file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0" * 128) ds.Modality = 'WSD' ds.ContentDate = str(datetime.date.today()).replace('-', '') ds.ContentTime = str(time.time()) #milliseconds since the epoch ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421859172643143649' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 if PhotometricInterpretation == "MONOCHROME2": ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' elif PhotometricInterpretation == "RGB": ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' pixel_array = pixel_array[0] print pixel_array.shape ds.Columns = pixel_array.shape[0] ds.ItemNumber = str(itemnumber) ds.InstanceNumber = str(itemnumber) ds.SliceLocation = str(itemnumber) ds.Rows = pixel_array.shape[1] if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() ds.save_as(filename) return filename
def copyCTtoRTDose(self, path, ds, doseData, imageRow, imageCol, sliceCount, dgs): # Create a RTDose file for broadcasting. file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.2' # CT Image Storage # Needs valid UID file_meta.MediaStorageSOPInstanceUID = ds.file_meta.MediaStorageSOPInstanceUID file_meta.ImplementationClassUID = ds.file_meta.ImplementationClassUID #create DICOM RT-Dose object. rtdose = FileDataset(path + '/rtdose.dcm', {}, file_meta=file_meta, preamble="\0" * 128) #No DICOM object standard. Use only required to avoid errors with viewers. rtdose.SOPInstanceUID = ds.SOPInstanceUID rtdose.SOPClassUID = '1.2.840.10008.5.1.4.1.1.481.2' rtdose.file_meta.TransferSyntaxUID = ds.file_meta.TransferSyntaxUID rtdose.PatientsName = ds.PatientsName rtdose.PatientID = ds.PatientID rtdose.PatientsBirthDate = ds.PatientsBirthDate #Crashed caused if no sex. try: rtdose.PatientsSex = ds.PatientsSex except: rtdose.PatientsSex, ds.PatientsSex = 'O', 'O' self.data.update({'images': ds}) rtdose.StudyDate = ds.StudyDate rtdose.StudyTime = ds.StudyTime rtdose.StudyInstanceUID = ds.StudyInstanceUID rtdose.SeriesInstanceUID = ds.SeriesInstanceUID rtdose.StudyID = ds.StudyID rtdose.SeriesNumber = ds.SeriesNumber rtdose.Modality = 'RTDOSE' rtdose.ImagePositionPatient = ds.ImagePositionPatient rtdose.ImageOrientationPatient = ds.ImageOrientationPatient rtdose.FrameofReferenceUID = ds.FrameofReferenceUID rtdose.PositionReferenceIndicator = ds.PositionReferenceIndicator rtdose.PixelSpacing = ds.PixelSpacing rtdose.SamplesperPixel = 1 rtdose.PhotometricInterpretation = 'MONOCHROME2' rtdose.NumberofFrames = sliceCount rtdose.Rows = imageRow rtdose.Columns = imageCol rtdose.BitsAllocated = 32 rtdose.BitsStored = 32 rtdose.HighBit = 31 rtdose.PixelRepresentation = 0 rtdose.DoseUnits = 'GY' rtdose.DoseType = 'PHYSICAL' rtdose.DoseSummationType = 'FRACTION' #In case spaceing tag is missing. if not ds.has_key('SpacingBetweenSlices'): ds.SpacingBetweenSlices = ds.SliceThickness #Ensure patient pos is on "Last slice". if fnmatch.fnmatch(ds.PatientPosition, 'FF*'): #For compliance with dicompyler update r57d9155cc415 which uses a reverssed slice ordering. doseData = doseData[::-1] rtdose.ImagePositionPatient[2] = ds.ImagePositionPatient[2] elif fnmatch.fnmatch(ds.PatientPosition, 'HF*'): rtdose.ImagePositionPatient[2] = ds.ImagePositionPatient[2] - ( sliceCount - 1) * ds.SpacingBetweenSlices #Create Type A(Relative) GFOV. rtdose.GridFrameOffsetVector = list( np.arange(0., sliceCount * ds.SpacingBetweenSlices, ds.SpacingBetweenSlices)) #Scaling from int to physical dose rtdose.DoseGridScaling = dgs #Store images in pixel_array(int) & Pixel Data(raw). rtdose.pixel_array = doseData rtdose.PixelData = doseData.tostring() #Tag required by dicompyler. plan_meta = Dataset() rtdose.ReferencedRTPlans = [] rtdose.ReferencedRTPlans.append([]) rtdose.ReferencedRTPlans[0] = plan_meta rtdose.ReferencedRTPlans[0].ReferencedSOPClassUID = 'RT Plan Storage' rtdose.ReferencedRTPlans[ 0].ReferencedSOPInstanceUID = ds.SOPInstanceUID #Create RTPlan to acticate DVH file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.5' # RT Plan Storage file_meta.MediaStorageSOPInstanceUID = ds.file_meta.MediaStorageSOPInstanceUID file_meta.ImplementationClassUID = ds.file_meta.ImplementationClassUID #create DICOM RT-Plan object. rtPlan = FileDataset(path + '/rtplan.dcm', {}, file_meta=file_meta, preamble="\0" * 128) #No DICOM object standard. Use only required to avoid errora with viewers. rtPlan.SOPInstanceUID = ds.SOPInstanceUID rtPlan.SOPClassUID = '1.2.840.10008.5.1.4.1.1.481.5' rtPlan.ReferencedSOPInstanceUID = ds.SOPInstanceUID #Need to change rtPlan.file_meta.TransferSyntaxUID = ds.file_meta.TransferSyntaxUID rtPlan.PatientsName = ds.PatientsName rtPlan.PatientID = ds.PatientID rtPlan.PatientsSex = ds.PatientsSex rtPlan.PatientsBirthDate = ds.PatientsBirthDate rtPlan.RTPlanLabel = 'Simulation' rtPlan.RTPlanDate = ds.StudyDate rtPlan.RTPlanTime = ds.StudyTime rtPlan.Modality = 'RTPLAN' rtPlan.StudyInstanceUID = ds.StudyInstanceUID rtPlan.SeriesInstanceUID = ds.SeriesInstanceUID rtPlan.StudyID = ds.StudyID rtPlan.SeriesNumber = ds.SeriesNumber return rtdose, rtPlan
def write_dicom(pixel_array, filename, series_number, fdf_info, series_description, project, subject, session): """Write a dicom from a pixel_array (numpy). :param pixel_array: 2D numpy ndarray. If pixel_array is larger than 2D, errors. :param filename: string name for the output file. :param ds_ori: original pydicom object of the pixel_array :param series_number: number of the series being processed :param series_description: series description for Osirix display :param project: XNAT Project ID :param subject: XNAT Subject label :param session: XNAT Session label """ # Variables pixel_array = np.rot90(pixel_array) pixel_array = np.rot90(pixel_array) pixel_array = np.rot90(pixel_array) # less than zero # pixel_array[pixel_array < 0] = 0 now = datetime.datetime.now() date = '%d%02d%02d' % (now.year, now.month, now.day) sop_id = '1.2.840.10008.5.1.4.1.1.4.%s' % date ti = str(time.time()) uid = sop_id + ti # Other tags to set sop_uid = sop_id + str(now).replace('-', '')\ .replace(':', '')\ .replace('.', '')\ .replace(' ', '') # Number of frames size = pixel_array.shape nb_frames = None if len(size) == 3: nb_frames = size[2] elif len(size) == 4: nb_frames = size[2]*size[3] # Create the ds object file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = sop_id file_meta.ImplementationClassUID = '1.2.840.10008.5.1.4.1.1.4' ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0"*128) ds.SeriesDate = '%d%02d%02d' % (now.year, now.month, now.day) ds.ContentDate = '%d%02d%02d' % (now.year, now.month, now.day) ds.ContentTime = str(time.time()) # milliseconds since the epoch ds.StudyInstanceUID = uid ds.SeriesInstanceUID = uid # Other tags to set ds.SOPInstanceUID = sop_uid[:-1] ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' # These are the necessary imaging components of the FileDataset object. ds.Modality = 'MR' ds.ConversionType = 'WSD' ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] ds.ProtocolName = '%s 9.4T' % series_description ds.StudyDescription = project ds.PatientsName = subject ds.PatientID = session ds.SeriesDescription = series_description ds.SeriesNumber = 1 ds.SmallestImagePixelValue = pixel_array.min() ds.LargestImagePixelValue = pixel_array.max() ds.AcquisitionNumber = 1 ds.SamplesperPixel = 1 ds.PixelSpacing = '%s\%s' % (fdf_info['spacing'][0], fdf_info['spacing'][1]) ds.SpacingBetweenSlices = float(fdf_info['spacing'][2]) ds.ImageOrientation = '\\'.join(fdf_info['orientation']) ds.PatientPosition = '\\'.join(fdf_info['origin']) if nb_frames: ds.NumberOfFrames = nb_frames # Organise the array: if len(size) == 3: pixel_array2 = np.zeros((size[0]*size[2], size[1])) for i in range(size[2]): pixel_array2[size[0]*i:size[0]*(i+1), :] = pixel_array[:, :, i] elif len(size) > 3: pixel_array2 = np.zeros((size[0]*size[2]*size[3], size[1])) for i in range(size[2]): for j in range(size[3]): pixel_array2[size[0]*j+i*size[3]*size[0]: size[0]*(j+1)+i*size[3]*size[0], :] = pixel_array[:, :, i, j] else: pixel_array2 = pixel_array # Set the Image pixel array if pixel_array2.dtype != np.uint16: pixel_array2 = pixel_array2.astype(np.uint16) print pixel_array2.max() print pixel_array2.min() ds.PixelData = pixel_array2.tostring() # Save the image ds.save_as(filename)
def writeDicomFiles(self, filename): for i in range( 1, len(self.PA) ): #Image 0 is a null image for default display and will not be written out fileName = filename + str(i) + ".dcm" # print ("printing dicom file " + fileName) # Populate required values for file meta information file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' # Create the FileDataset instance (initially no data elements, but file_meta supplied) ds = FileDataset(fileName, {}, file_meta=file_meta, preamble="\0" * 128) ds.Modality = 'MR' ds.ContentDate = str(datetime.date.today()).replace('-', '') ds.ContentTime = str(time.time()) #milliseconds since the epoch ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421859172643143649' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.SOPClassUID = 'MR Image Storage' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ## These are the necessary imaging components of the FileDataset object. ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' #Add MRI data elements ds.bValue = self.bValue[i] ds.Columns = self.Columns[i] ds.FoVX = self.FoVX[i] ds.FoVY = self.FoVY[i] ds.ImageOrientationPatient = self.ImagePosition[i].tolist() ds.InstitutionName = self.InstitutionName[i] ds.PixelBandwidth = self.PixelBandwidth[i] ds.PixelSpacing = [self.PixelSpacingY[i], self.PixelSpacingX[i]] ds.Rows = self.Rows[i] ds.PatientName = self.PatientName[i] ds.PatientID = "123456" ds.ProtocolName = self.ProtocolName[i] ds.RepetitionTime = self.TR[i] ds.SeriesDescription = self.SeriesDescription[i] ds.EchoTime = self.TE[i] ds.FlipAngle = self.FA[i] ds.InversionTime = self.TI[i] ds.ImageOrientationPatient[3:6] = self.ColumnDirection[i].tolist() ds.ImageOrientationPatient[:3] = self.RowDirection[i].tolist() ds.MagneticFieldStrength = self.MagneticFieldStrength[i] ds.Manufacturer = self.Manufacturer[i] pixel_array = np.transpose(self.PA[i]) #numpy pixel array if self.DataType[i].lower() == "phase": pixel_array = ( pixel_array + np.pi ) * 10000 # phase data -pi to pi is converted to 0 to 10000pi #print "Adjusting phase to 16 bit integer" if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() # image byte data # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = True ds.save_as(fileName)
def encode(self, input_image, text, output_file): print("using file: " + input_image) print("analysis result is: " + text) # first we need to setup some meta data # Populate required values for file meta information file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' # CT Image Storage .... check here: http://dicom.nema.org/dicom/2013/output/chtml/part04/sect_B.5.html file_meta.MediaStorageSOPInstanceUID = "1.2.3" # !! Need valid UID here for real work file_meta.ImplementationClassUID = "1.2.3.4" # !!! Need valid UIDs here # Create the FileDataset instance (initially no data elements, but file_meta supplied) ds = FileDataset(output_file, {}, file_meta=file_meta, preamble=b"\0" * 128) # Add the data elements -- not trying to set all required here. Check DICOM standard # ds.PatientName = "John Smith2" ds.add_new(Tag(0x10,0x10), "PN", "John 99") # this is the tag for patient's name ds.PatientID = "123456" # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = True # Set creation date/time dt = datetime.datetime.now() ds.ContentDate = dt.strftime('%Y%m%d') timeStr = dt.strftime('%H%M%S.%f') # long format with micro seconds ds.ContentTime = timeStr # imge file data # read this http://stackoverflow.com/questions/14350675/create-pydicom-file-from-numpy-array # img=mpimg.imread(input_image) img = cv2.imread(input_image, 0) # we read the image monochrome print(img.shape) plt.imshow(img) print(img.shape[0]) ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = bytes((0,)) ds.LargestImagePixelValue = bytes((255,)) img = img.astype(np.uint16) print(np.amin(img)) print(np.amax(img)) ds.PixelData = img.tostring() ds.Rows = img.shape[0] ds.Columns = img.shape[1] print("Writing test file", output_file) ds.save_as(output_file) print("File saved.") return
def changer(): net = torch.load('Train1_Dream_8.pt') #LOAD THE REQUIRED MODEL decoder = net.module.decoder new_file = open('000135.kmxm', 'rb') #SPECIFY THE INPUT FILENAME filename = 'conv.dcm' #SPECIFY THE OUTPUT FILE NAME #READING THE REQUIRED CHARACTERS new_file.seek(33) rows = new_file.read(8) h = struct.unpack('Q', rows)[0] new_file.seek(41) columns = new_file.read(8) w = struct.unpack('Q', columns)[0] new_file.seek(49) bpp = new_file.read(1) b = struct.unpack('B', bpp)[0] new_file.seek(50) img = new_file.read() #print w,h #CONVERTING TO THE VALUES WITH THE PADDING wn = (int(np.floor(w / 16)) + 1) * 16 hn = (int(np.floor(h / 16)) + 1) * 16 imgfile = np.fromstring(img, sep='', dtype=np.uint8) imgfile = imgfile.reshape((8, wn / 16, hn / 16)) w1 = (int(np.floor(w / 16)) + 1) * 16 - w h1 = (int(np.floor(h / 16)) + 1) * 16 - h imgfile = torch.unsqueeze(torch.from_numpy(imgfile.astype(float)), 0).float() imgfile = imgfile / 255.0 imgfile = decoder(Variable(imgfile)) imgfile = imgfile.data imgfile = torch.round((imgfile.clamp(0.0, 1.0)) * (255.0)) imgfile = imgfile[0] imgfile = imgfile[0] imgfile = imgfile.numpy().astype(np.uint16) imgfile = imgfile[int(w1 / 2):int(w1 / 2) + w, int(h1 / 2):int(h1 / 2) + h] #print "length of ",len(imgfile) #SAVING PNG OF THE IMAGE (OPTIONAL) im = fromarray(imgfile).convert("L") ## Saving preview image im.save('dicom.png') imgdata = imgfile.tostring() #WRITING THE DICOM FILE file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0" * 128) #INCASE OF IRREGULARTIES FROM ACTUAL IMAGE CHECK THESE VALUES WITH ACTUAL FILE ds.Modality = 'MG' ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 11 ds.BitsStored = 12 ds.WindowCenter = 128 ds.WindowWidth = 256 ds.BitsAllocated = 16 ds.Rows = w ds.Columns = h ds.PixelData = imgdata ds.save_as(filename) print "file saved"
ds.SliceThickness = dsOld.SliceThickness #ds.SpacingBetweenSlices = dsOld.SpacingBetweenSlices ds.PatientPosition = dsOld.PatientPosition #Image info (check need in ct modality ds.ImagePositionPatient = dsOld.ImagePositionPatient ds.ImageOrientationPatient = dsOld.ImageOrientationPatient ds.FrameofReferenceUID = dsOld.FrameofReferenceUID ds.SliceLocation = dsOld.SliceLocation ds.PixelSpacing = dsOld.PixelSpacing ds.SamplesperPixel = dsOld.SamplesperPixel ds.PhotometricInterpretation = dsOld.PhotometricInterpretation ds.Rows = dsOld.Rows ds.Columns = dsOld.Columns ds.BitsAllocated = dsOld.BitsAllocated ds.BitsStored = dsOld.BitsStored ds.HighBit = dsOld.HighBit ds.PixelRepresentation = dsOld.PixelRepresentation #ds.WindowCenter = dsOld.WindowCenter #ds.WindowWidth = dsOld.WindowWidth ds.RescaleIntercept = dsOld.RescaleIntercept ds.RescaleSlope = dsOld.RescaleSlope # create 2d image of air HU ds.pixel_array = dsOld.pixel_array ds.PixelData = dsOld.PixelData # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = True
def write_dicom(pixel_array, filename, ds_ori, series_number, sop_id, nb_acq, project, subject, session): """Write a dicom from a pixel_array (numpy). :param pixel_array: 2D numpy ndarray. If pixel_array is larger than 2D, errors. :param filename: string name for the output file. :param ds_ori: original pydicom object of the pixel_array :param series_number: number of the series being processed :param sop_id: SOPInstanceUID for the DICOM :param nb_acq: acquisition number :param project: project name on XNAT :param subject: subject name on XNAT :param session: session name on XNAT """ # Set the DICOM dataset file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = ds_ori.SOPInstanceUID file_meta.ImplementationClassUID = ds_ori.file_meta.ImplementationClassUID ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0"*128) # Copy UID from dicom ds.InstanceCreatorUID = ds_ori.InstanceCreatorUID ds.SOPClassUID = ds_ori.SOPClassUID # ds.ReferencedStudySequence = ds_ori.ReferencedStudySequence ds.StudyInstanceUID = ds_ori.StudyInstanceUID ds.SeriesInstanceUID = ds_ori.SeriesInstanceUID # Other tags to set ds.SeriesNumber = series_number sop_uid = sop_id + str(datetime.datetime.now()).replace('-', '')\ .replace(':', '')\ .replace('.', '')\ .replace(' ', '') ds.SOPInstanceUID = sop_uid[:-1] ds.ProtocolName = 'ADC Map %d' % nb_acq ds.SeriesDescription = 'ADC Map %d' % nb_acq ds.PatientName = subject ds.PatientID = session # Set SeriesDate/ContentDate now = datetime.date.today() ds.SeriesDate = '%d%02d%02d' % (now.year, now.month, now.day) ds.ContentDate = '%d%02d%02d' % (now.year, now.month, now.day) ds.Modality = 'MR' ds.StudyDescription = project ds.AcquisitionNumber = 1 ds.SamplesperPixel = 1 ds.PhotometricInterpretation = 'MONOCHROME2' ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.11' ds.NumberOfFrames = pixel_array.shape[2] ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 8 ds.BitsAllocated = 8 ds.SmallestImagePixelValue = pixel_array.min() ds.LargestImagePixelValue = pixel_array.max() ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] # Organise the array: pixel_array2 = np.zeros((pixel_array.shape[0]*pixel_array.shape[2], pixel_array.shape[1])) for i in range(pixel_array.shape[2]): pixel_array2[pixel_array.shape[0]*i:pixel_array.shape[0]*(i+1), :] = pixel_array[:, :, i] # Set the Image pixel array if pixel_array2.dtype != np.uint8: pixel_array2 = pixel_array2.astype(np.uint8) ds.PixelData = pixel_array2.tostring() # Save the image ds.save_as(filename)
def write_dicom(arguments, pixel_array, meta_arr=[]): """ Function to create completely new DICOM file. :param arguments: Dictionary containing input parameters. :param pixel_array: 2D or 3D numpy array containing pixel values. :param meta_arr: An array contaning parsed meta data. :return: """ #TODO:Check the possibility to use UID generator instead hardcoded ones. file_meta = Dataset() # The Secondary Capture (SC) Image Information Object Definition (IOD) specifies images that are converted from # a non-DICOM format to a modality independent DICOM format. file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' # Since we don't want to store any additional info in the header, we set it to x00 ds = FileDataset(arguments['out_file'], {}, file_meta=file_meta, preamble=b'0' * 128) # Type of equipment that originally acquired the data. ds.Modality = 'WSD' # Setting the date and time ds.ContentDate = str(datetime.date.today()).replace('-', '') ds.ContentTime = str(time.time()) # milliseconds since the epoch # Keep scrolling :) ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.369231118011061003403421859172643143649' # Manufacturer ds.SecondaryCaptureDeviceManufctur = 'NCBJ' # These are the necessary imaging components of the FileDataset object. # Number of color channels. ds.SamplesPerPixel = 1 # It defines what does every color channel hold ds.PhotometricInterpretation = "MONOCHROME2" # ds.PixelRepresentation = 0 ds.HighBit = 15 # Here meta-data is put into the Data Set. It can override hardcoded values, but parameters providided as program # arguments will be inserted no matter what is in the meta-data file. ds = write_meta(meta_arr, ds) # How many bits are allocated to store pixel info ds.BitsAllocated = arguments['bytes_per_pix'] * 8 # How many bits are used to store pixel info ds.BitsStored = arguments['bytes_per_pix'] * 8 # Whether signed or unsigned numbers are used if arguments['is_signed']: ds.PixelRepresentation = 1 else: ds.PixelRepresentation = 0 # Read from data the dimensions. if len(pixel_array.shape) == 3: ds.NumberOfFrames = pixel_array.shape[0] ds.Columns = pixel_array.shape[1] ds.Rows = pixel_array.shape[2] else: ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] try: err_str = '[ERROR] The file could not be created because of: ' data_type = recognize_type(arguments['bytes_per_pix'], arguments['is_signed'], arguments['is_float']) if pixel_array.dtype != data_type: pixel_array = pixel_array.astype(data_type) ds.PixelData = pixel_array.tostring() ds.save_as(arguments['out_file'].replace('.dcm', '') + '.dcm') print('[INFO] Writing to DICOM file is complete!') except ValueError as ve: print(err_str + 'ValueError ' + str(ve)) sys.exit(1) except FileExistsError as fe: print(err_str + 'FileExistsError ' + str(fe)) sys.exit(1) except Exception as e: print(err_str + str(e)) sys.exit(1)
def write_dicom(pixel_array, filename, origin, origins, orientation): file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' ds = FileDataset(filename, {},file_meta = file_meta,preamble="\0"*128) ds.ImageType= 'ORIGINAL\PRIMARY\AXIAL\CT' ds.SOPClassUID = 'Secondary Capture Image Storage' ds.SOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' ds.StudyDate = str(datetime.date.today()).replace('-','') #ds.ImageDate = str(datetime.date.today()).replace('-','') ds.StudyTime = str(time.time()) #ds.ImageTime = str(time.time()) ds.AccessionNumber = '153745645' ds.Modality = 'CT' ds.Manufacturer = 'PY_BONEMAT_ABAQUS' ds.InstitutionName = 'UNIVERISTY_OF_BATH' ds.ReferringPhysiciansName = 'NOTAPPLICABLE' ds.ManufacturersModelName = 'VERSION1-0-9' ds.ReferencedImageSequence = '' ds.PatientsName = 'SUBJECT001' ds.PatientID = '' ds.PatientsBirthDate = '' ds.PatientsSex = 'F' ds.SliceThickness = 2.7 ds.KVP = 120 ds.SpacingBetweenSlices = 1 ds.DataCollectionDiameter = 430 ds.ReconstructionDiameter = 430.00 ds.DistanceSourceToDetector = 1093 ds.DistanceSourceToPatient = 630. ds.GantryDetectorTilt = 0.0 ds.ScanArc = 403 ds.XRayTubeCurrent = 200 ds.Exposure = 135 ds.FilterType = 'F' ds.PatientPosition = 'HFS' ds.StudyInstanceUID = '1.3.6.1.4.1.9590.100.1.1.124313977412360175234271287472804872093' ds.SeriesInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780.1' #ds.ReferenceSOPClassUID = 'Secondary Capture Image Storage' #ds.ReferencedSOPInstanceUID = '1.3.6.1.4.1.9590.100.1.1.111165684411017669021768385720736873780' #ds.ContentDate = str(datetime.date.today()).replace('-','') #ds.ContentTime = str(time.time()) ds.StudyID = '15346254' ds.SeriesNumber = '8733' ds.AcquisitionNumber = 1 ds.ImageNumber = origins.index(origin) + 1 ds.SliceLocation = origin[2] ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 0 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = '\\x00\\x00' ds.LargestImagePixelValue = '\\xff\\xff' ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] ds.PatientOrientation = ['L','P'] ds.ImagePositionPatient = origin ds.ImageOrientationPatient = orientation ds.PixelSpacing = [1.0, 1.0] ds.RescaleSlope = 1.0 ds.RescaleIntercept = 0.0 if pixel_array.dtype != np.uint16: pixel_array = pixel_array.astype(np.uint16) ds.PixelData = pixel_array.tostring() ds.save_as(filename) return