def test_lut_descriptor(self): """Test correcting elements which require LUTDescriptor.""" ref_ds = Dataset() ref_ds.PixelRepresentation = 0 # If LUTDescriptor[0] is 1 then LUTData VR is 'US' ref_ds.LUTDescriptor = b'\x01\x00\x00\x01\x10\x00' # 1\256\16 ref_ds.LUTData = b'\x00\x01' # Little endian 256 ds = correct_ambiguous_vr(deepcopy(ref_ds), True) # Little endian self.assertEqual(ds.LUTDescriptor[0], 1) self.assertEqual(ds[0x00283002].VR, 'US') self.assertEqual(ds.LUTData, 256) self.assertEqual(ds[0x00283006].VR, 'US') # If LUTDescriptor[0] is not 1 then LUTData VR is 'OW' ref_ds.LUTDescriptor = b'\x02\x00\x00\x01\x10\x00' # 2\256\16 ref_ds.LUTData = b'\x00\x01\x00\x02' ds = correct_ambiguous_vr(deepcopy(ref_ds), True) # Little endian self.assertEqual(ds.LUTDescriptor[0], 2) self.assertEqual(ds[0x00283002].VR, 'US') self.assertEqual(ds.LUTData, b'\x00\x01\x00\x02') self.assertEqual(ds[0x00283006].VR, 'OW') # If no LUTDescriptor then VR should be unchanged ref_ds = Dataset() ref_ds.LUTData = b'\x00\x01' ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.LUTData, b'\x00\x01') self.assertEqual(ds[0x00283006].VR, 'US or OW')
def test_waveform_bits_allocated(self): """Test correcting elements which require WaveformBitsAllocated.""" ref_ds = Dataset() # If WaveformBitsAllocated > 8 then VR must be OW ref_ds.WaveformBitsAllocated = 16 ref_ds.WaveformData = b'\x00\x01' # Little endian 256 ds = correct_ambiguous_vr(deepcopy(ref_ds), True) # Little endian self.assertEqual(ds.WaveformData, b'\x00\x01') self.assertEqual(ds[0x54001010].VR, 'OW') ds = correct_ambiguous_vr(deepcopy(ref_ds), False) # Big endian self.assertEqual(ds.WaveformData, b'\x00\x01') self.assertEqual(ds[0x54001010].VR, 'OW') # If WaveformBitsAllocated <= 8 then VR is OB or OW, but not sure which # so leave VR unchanged ref_ds.WaveformBitsAllocated = 8 ref_ds.WaveformData = b'\x01\x02' ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.WaveformData, b'\x01\x02') self.assertEqual(ds[0x54001010].VR, 'OB or OW') # If no WaveformBitsAllocated then VR should be unchanged ref_ds = Dataset() ref_ds.WaveformData = b'\x00\x01' # Big endian 1 ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.WaveformData, b'\x00\x01') self.assertEqual(ds[0x54001010].VR, 'OB or OW')
def create_dcm_file(image): # Create some temporary filenames suffix = '.dcm' filename_little_endian = tempfile.NamedTemporaryFile(suffix=suffix).name print("Setting file meta information...") # Populate required values for file meta information file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' file_meta.MediaStorageSOPInstanceUID = "1.2.3" file_meta.ImplementationClassUID = "1.2.3.4" print("Setting dataset values...") # Create the FileDataset instance (initially no data elements, but file_meta # supplied) ds = FileDataset(filename_little_endian, {}, file_meta=file_meta, preamble=b"\0" * 128) # Add the data elements -- not trying to set all required here. Check DICOM # standard ds.PatientName = "" ds.PatientID = "" ds.PixelRepresentation = 1 # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = False ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 1 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = str.encode('\x00\x00') ds.LargestImagePixelValue = str.encode('\xff\xff') ds.Columns = image.shape[0] ds.Rows = image.shape[1] # 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 try: if image.max() <= 1: image *= 255 image = image.astype("uint16") ds.PixelData = Image.fromarray(image).tobytes() except Exception: traceback.print_exc() print("Writing test file", filename_little_endian) ds.file_meta.TransferSyntaxUID = pydicom.uid.ExplicitVRLittleEndian ds = correct_ambiguous_vr(ds, True) ds.save_as(filename_little_endian) print("File saved.") print("File saved.") print('Load file {} ...'.format(filename_little_endian)) ds = pydicom.dcmread(filename_little_endian) print('Remove file {} ...'.format(filename_little_endian)) os.remove(filename_little_endian) return ds
def save(self): image = np.array(self.img, dtype=np.uint16) # Create some temporary filenames suffix = '.dcm' filename_little_endian = tempfile.NamedTemporaryFile( suffix=suffix).name.replace('/tmp', '') # Populate required values for file meta information file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' file_meta.MediaStorageSOPInstanceUID = "1.2.3" file_meta.ImplementationClassUID = "1.2.3.4" # Create the FileDataset instance (initially no data elements, but file_meta # supplied) ds = FileDataset(filename_little_endian, {}, file_meta=file_meta, preamble=b"\0" * 128) ds.PatientID = self.patient_id.get() ds.PatientName = self.patient_name.get() ds.PatientSex = self.patient_sex.get() ds.PatientBirthDate = self.patient_birthdate.get() ds.StudyDate = self.examination_date.get() ds.ImageComments = self.comment.get() ds.PixelRepresentation = 1 ds.is_little_endian = True ds.is_implicit_VR = False ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" ds.PixelRepresentation = 1 ds.HighBit = 15 ds.BitsStored = 16 ds.BitsAllocated = 16 ds.SmallestImagePixelValue = str.encode('\x00\x00') ds.LargestImagePixelValue = str.encode('\xff\xff') ds.Columns = image.shape[0] ds.Rows = image.shape[1] dt = datetime.datetime.now() try: if image.max() <= 1: image *= 255 image = image.astype("uint16") ds.PixelData = Image.fromarray(image).tobytes() except Exception: traceback.print_exc() ds.file_meta.TransferSyntaxUID = pydicom.uid.ExplicitVRLittleEndian ds = correct_ambiguous_vr(ds, True) filename = filedialog.asksaveasfilename( initialdir="./", title="choose save location", filetypes=(("dicom files", "*.dcm"), ("all files", "*.*"))) if filename is None: return ds.save_as(filename) print("File saved.")
def test_pixel_representation_vm_three(self): """Test correcting VM 3 elements which require PixelRepresentation.""" ref_ds = Dataset() # If PixelRepresentation is 0 then VR should be US - Little endian ref_ds.PixelRepresentation = 0 ref_ds.LUTDescriptor = b'\x01\x00\x00\x01\x10\x00' # 1\256\16 ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.LUTDescriptor, [1, 256, 16]) self.assertEqual(ds[0x00283002].VR, 'US') # If PixelRepresentation is 1 then VR should be SS ref_ds.PixelRepresentation = 1 ref_ds.LUTDescriptor = b'\x01\x00\x00\x01\x00\x10' ds = correct_ambiguous_vr(deepcopy(ref_ds), False) self.assertEqual(ds.LUTDescriptor, [256, 1, 16]) self.assertEqual(ds[0x00283002].VR, 'SS') # If no PixelRepresentation then should be unchanged ref_ds = Dataset() ref_ds.LUTDescriptor = b'\x01\x00\x00\x01\x00\x10' ds = correct_ambiguous_vr(deepcopy(ref_ds), False) self.assertEqual(ds.LUTDescriptor, b'\x01\x00\x00\x01\x00\x10') self.assertEqual(ds[0x00283002].VR, 'US or SS')
def test_pixel_representation_vm_one(self): """Test correcting VM 1 elements which require PixelRepresentation.""" ref_ds = Dataset() # If PixelRepresentation is 0 then VR should be US ref_ds.PixelRepresentation = 0 ref_ds.SmallestValidPixelValue = b'\x00\x01' # Little endian 256 ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.SmallestValidPixelValue, 256) self.assertEqual(ds[0x00280104].VR, 'US') # If PixelRepresentation is 1 then VR should be SS ref_ds.PixelRepresentation = 1 ref_ds.SmallestValidPixelValue = b'\x00\x01' # Big endian 1 ds = correct_ambiguous_vr(deepcopy(ref_ds), False) self.assertEqual(ds.SmallestValidPixelValue, 1) self.assertEqual(ds[0x00280104].VR, 'SS') # If no PixelRepresentation then should be unchanged ref_ds = Dataset() ref_ds.SmallestValidPixelValue = b'\x00\x01' # Big endian 1 ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.SmallestValidPixelValue, b'\x00\x01') self.assertEqual(ds[0x00280104].VR, 'US or SS')
def test_overlay(self): """Test correcting OverlayData""" # Implicit VR must be 'OW' ref_ds = Dataset() ref_ds.is_implicit_VR = True ref_ds.add(DataElement(0x60003000, 'OB or OW', b'\x00')) ref_ds.add(DataElement(0x601E3000, 'OB or OW', b'\x00')) ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertTrue(ds[0x60003000].VR == 'OW') self.assertTrue(ds[0x601E3000].VR == 'OW') self.assertTrue(ref_ds[0x60003000].VR == 'OB or OW') self.assertTrue(ref_ds[0x601E3000].VR == 'OB or OW') # Explicit VR may be 'OB' or 'OW' (leave unchanged) ref_ds.is_implicit_VR = False ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertTrue(ds[0x60003000].VR == 'OB or OW') self.assertTrue(ref_ds[0x60003000].VR == 'OB or OW') # Missing is_implicit_VR (leave unchanged) del ref_ds.is_implicit_VR ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertTrue(ds[0x60003000].VR == 'OB or OW') self.assertTrue(ref_ds[0x60003000].VR == 'OB or OW')
def test_sequence(self): """Test correcting elements in a sequence.""" ref_ds = Dataset() ref_ds.BeamSequence = [Dataset()] ref_ds.BeamSequence[0].PixelRepresentation = 0 ref_ds.BeamSequence[0].SmallestValidPixelValue = b'\x00\x01' ref_ds.BeamSequence[0].BeamSequence = [Dataset()] ref_ds.BeamSequence[0].BeamSequence[0].PixelRepresentation = 0 ref_ds.BeamSequence[0].BeamSequence[0].SmallestValidPixelValue = b'\x00\x01' ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.BeamSequence[0].SmallestValidPixelValue, 256) self.assertEqual(ds.BeamSequence[0][0x00280104].VR, 'US') self.assertEqual(ds.BeamSequence[0].BeamSequence[0].SmallestValidPixelValue, 256) self.assertEqual(ds.BeamSequence[0].BeamSequence[0][0x00280104].VR, 'US')
def test_pixel_data(self): """Test correcting PixelData.""" ref_ds = Dataset() # If BitsAllocated > 8 then VR must be OW ref_ds.BitsAllocated = 16 ref_ds.PixelData = b'\x00\x01' # Little endian 256 ds = correct_ambiguous_vr(deepcopy(ref_ds), True) # Little endian self.assertEqual(ds.PixelData, b'\x00\x01') self.assertEqual(ds[0x7fe00010].VR, 'OW') ds = correct_ambiguous_vr(deepcopy(ref_ds), False) # Big endian self.assertEqual(ds.PixelData, b'\x00\x01') self.assertEqual(ds[0x7fe00010].VR, 'OW') # If BitsAllocated <= 8 then VR can be OB or OW: OW ref_ds = Dataset() ref_ds.BitsAllocated = 8 ref_ds.Rows = 2 ref_ds.Columns = 2 ref_ds.PixelData = b'\x01\x00\x02\x00\x03\x00\x04\x00' ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.PixelData, b'\x01\x00\x02\x00\x03\x00\x04\x00') self.assertEqual(ds[0x7fe00010].VR, 'OW') # If BitsAllocated <= 8 then VR can be OB or OW: OB ref_ds = Dataset() ref_ds.BitsAllocated = 8 ref_ds.Rows = 2 ref_ds.Columns = 2 ref_ds.PixelData = b'\x01\x02\x03\x04' ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.PixelData, b'\x01\x02\x03\x04') self.assertEqual(ds[0x7fe00010].VR, 'OB') # If no BitsAllocated then VR should be unchanged ref_ds = Dataset() ref_ds.PixelData = b'\x00\x01' # Big endian 1 ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.PixelData, b'\x00\x01') self.assertEqual(ds[0x7fe00010].VR, 'OB or OW') # If required elements missing then VR should be unchanged ref_ds = Dataset() ref_ds.BitsAllocated = 8 ref_ds.Rows = 2 ref_ds.PixelData = b'\x01\x02\x03\x04' ds = correct_ambiguous_vr(deepcopy(ref_ds), True) self.assertEqual(ds.PixelData, b'\x01\x02\x03\x04') self.assertEqual(ds[0x7fe00010].VR, 'OB or OW')