从多个jpg图像创建Dicom

3

我已成功地使用一个图像构建了DICOM文件,但是我无法找到一种添加更多图像的方法...... 我认为问题可能出在我的像素数组上,请问有谁可以帮我纠正一下吗?

# Populate required values for file meta information
meta = pydicom.Dataset()
meta.TransferSyntaxUID = pydicom.uid.ExplicitVRLittleEndian
meta.MediaStorageSOPClassUID = pydicom._storage_sopclass_uids.MRImageStorage
meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid()

# build dataset
ds = Dataset()
ds.file_meta = meta
ds.fix_meta_info()

# unknown options
ds.is_little_endian = True
ds.is_implicit_VR = False
ds.SOPClassUID = pydicom._storage_sopclass_uids.MRImageStorage
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.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.PixelRepresentation = 1

# Case options
ds.PatientName = "Anonymous"
ds.PatientID = "123456"
ds.Modality = "MR"
ds.StudyDate = '20200225'
ds.ContentDate = '20200225'

def ensure_even(stream):
    # Very important for some viewers
    if len(stream) % 2:
        return stream + b"\x00"
    return stream

pixel_data_list = []
for root, dir, filenames in walk(folder):
    filenames.sort(key=natural_keys)
    for filename in filenames:
        filename = folder + filename
        # convert image to grayscale
        img = Image.open(filename).convert('L')
        img.save(filename)

        # open image, decode and ensure_even stream
        with open(filename, 'rb') as f:
            arr = decode(f)

        pixel_data_list.append(arr.tobytes())

# required for pixel handler
ds.BitsStored = 8
ds.BitsAllocated = 8
ds.HighBit = 7
ds.PixelRepresentation = 0

# grayscale without compression
ds.PhotometricInterpretation = "MONOCHROME2"
ds.SamplesPerPixel = 1  # 1 color = 1 sampleperpixel
ds.file_meta.TransferSyntaxUID = pydicom.uid.ExplicitVRLittleEndian
ds.PixelData = array(pixel_data_list)
ds.NumberOfFrames = len(pixel_data_list)

# Image shape
ds['PixelData'].is_undefined_length = False
ds.Columns = img.width
ds.Rows = img.height

# validate and save
pydicom.dataset.validate_file_meta(ds.file_meta, enforce_standard=True)
new_filename = filename.replace('.jpg', name + '.dcm')
ds.save_as(new_filename, write_like_original=False)

此外,似乎无法压缩图像,只有单色效果有效(请参见尝试https://dev59.com/PGYq5IYBdhLWcg3wmRya#68939321)......

不过这并不是问题的关键,最重要的是能够添加多个图像。感谢任何指导!

1个回答

2

像素数据应该是字节。如果您的传输语法未压缩,则需要将数据连接在一起,如果连接后的数据长度为奇数,则必须添加尾随填充字节:

# For uncompressed transfer syntaxes only!
pixel_data = b"".join(pixel_data_list)
ds.PixelData = pixel_data + b"\x00" if len(pixel_data) % 2 else pixel_data

对于压缩传输语法,必须使用封装


1
太棒了!谢谢,现在它可以工作了^^ 这是很好的进展。 - Johann
你知道为什么我只能在查看器中看到一张图片吗? ds.NumberOfFrames = len(pixel_data_list) ds.ImagesInAcquisition = len(pixel_data_list) 似乎没有起作用... - Johann
我的意思是阅读器只显示一个实例。这些实例是如何定义的? 我正在阅读文档,但很难找到答案。 - Johann
一个实例(SOP实例)是一个单独的数据集。我认为MR图像存储通常不是多帧的,查看器支持它吗?也许你想要增强型MR - scaramallion
观看器支持它(GXD5)。我已经尝试了 ds.SOPClassUID = pydicom._storage_sopclass_uids.EnhancedMRImageStorage 并添加了所有必需的值,如 ds.SharedFunctionalGroupsSequence = "" ds.VolumetricProperties = "MIXED" ds.VolumeBasedCalculationTechnique = "NONE" 还加入了ContentTime。 但我不知道应该在ds.DimensionOrganizationSequence中放什么。现在文件打开后立即关闭,似乎有些东西损坏了文件?这真是太复杂了……非常感谢您的帮助。 - Johann
我有一种感觉,我只是缺少SharedFunctionalGroupsSequence和DimensionOrganizationSequence的正确值才能使其正常工作。 - Johann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接