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 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)