Create pydicom file from numpy array

后端 未结 5 1030
别跟我提以往
别跟我提以往 2020-12-16 04:42

I\'m trying to create a mew dicom image from a standard-sized (512 x 512 or 256 x 256) numpy array. It seems like this should be straightforward, and I\'ve adapted my code

5条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-16 05:14

    2020 update :)

    None of these answers worked for me. This is what I ended up with to save a valid monochrome 16bpp MR slice which is correctly displayed at least in Slicer, Radiant and MicroDicom:

    import pydicom
    from pydicom.dataset import Dataset, FileDataset
    from pydicom.uid import ExplicitVRLittleEndian
    import pydicom._storage_sopclass_uids
    
    image2d = image2d.astype(np.uint16)
    
    print("Setting file meta information...")
    # Populate required values for file meta information
    
    meta = pydicom.Dataset()
    meta.MediaStorageSOPClassUID = pydicom._storage_sopclass_uids.MRImageStorage
    meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid()
    meta.TransferSyntaxUID = pydicom.uid.ExplicitVRLittleEndian  
    
    ds = Dataset()
    ds.file_meta = meta
    
    ds.is_little_endian = True
    ds.is_implicit_VR = False
    
    ds.SOPClassUID = pydicom._storage_sopclass_uids.MRImageStorage
    ds.PatientName = "Test^Firstname"
    ds.PatientID = "123456"
    
    ds.Modality = "MR"
    ds.SeriesInstanceUID = pydicom.uid.generate_uid()
    ds.StudyInstanceUID = pydicom.uid.generate_uid()
    ds.FrameOfReferenceUID = pydicom.uid.generate_uid()
    
    ds.BitsStored = 16
    ds.BitsAllocated = 16
    ds.SamplesPerPixel = 1
    ds.HighBit = 15
    
    ds.ImagesInAcquisition = "1"
    
    ds.Rows = image2d.shape[0]
    ds.Columns = image2d.shape[1]
    ds.InstanceNumber = 1
    
    ds.ImagePositionPatient = r"0\0\1"
    ds.ImageOrientationPatient = r"1\0\0\0\-1\0"
    ds.ImageType = r"ORIGINAL\PRIMARY\AXIAL"
    
    ds.RescaleIntercept = "0"
    ds.RescaleSlope = "1"
    ds.PixelSpacing = r"1\1"
    ds.PhotometricInterpretation = "MONOCHROME2"
    ds.PixelRepresentation = 1
    
    pydicom.dataset.validate_file_meta(ds.file_meta, enforce_standard=True)
    
    print("Setting pixel data...")
    ds.PixelData = image2d.tobytes()
    
    ds.save_as(r"out.dcm")
    

    Note the following:

    • Going through FileDataset constructor as PyDicom docs suggest was failing to create a valid header for me
    • validate_file_meta will create some missing elements in header for you (version)
    • You need to specify endianness and explicit/implicit VR twice :/
    • This method will allow you to create a valid volume as well as long as you update ImagePositionPatient and InstanceNumber for each slice accordingly
    • Make sure your numpy array is cast to data format that has same number of bits as your BitsStored

提交回复
热议问题