Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用pydicom创建JPEG压缩的DICOM数据集?_Python_Jpeg_Dicom_Imaging_Pydicom - Fatal编程技术网

Python 如何使用pydicom创建JPEG压缩的DICOM数据集?

Python 如何使用pydicom创建JPEG压缩的DICOM数据集?,python,jpeg,dicom,imaging,pydicom,Python,Jpeg,Dicom,Imaging,Pydicom,我正在尝试使用创建一个JPEG压缩的DICOM图像。一个很好的源材料关于彩色DICOM图像可以找到,但主要是理论和C++。在下面的代码示例中,我在output raw.dcm(未压缩)中创建了一个淡蓝色省略号,如下所示: 导入io 从PIL导入图像,ImageDraw 从pydicom.dataset导入数据集 从pydicom.uid导入生成\u uid,JPEG扩展 从pydicom.\u存储\u sopclass\u UID导入第二个CaptureImageStorage 宽度=100

我正在尝试使用创建一个JPEG压缩的DICOM图像。一个很好的源材料关于彩色DICOM图像可以找到,但主要是理论和C++。在下面的代码示例中,我在
output raw.dcm
(未压缩)中创建了一个淡蓝色省略号,如下所示:

导入io
从PIL导入图像,ImageDraw
从pydicom.dataset导入数据集
从pydicom.uid导入生成\u uid,JPEG扩展
从pydicom.\u存储\u sopclass\u UID导入第二个CaptureImageStorage
宽度=100
高度=100
def确保_均匀(流):
#对一些观众来说非常重要
如果len(流)%2:
返回流+b“\x00”
回流
def bob_ross_magic():
image=image.new(“RGB”(宽度、高度),color=“红色”)
draw=ImageDraw.draw(图像)
绘制矩形([10,10,90,90],fill=“黑色”)
绘制椭圆([30,20,70,80],fill=“青色”)
text((11,11),“Hello”,fill=(255,255,0))
返回图像
ds=数据集()
ds.is_little_endian=True
ds.is_implicit_VR=True
ds.SOPClassUID=SecondaryCaptureImageStorage
ds.SOPInstanceUID=generate_uid()
ds.fix_meta_info()
ds.Modality=“OT”
ds.samplesperpoixel=3
ds.BitsAllocated=8
ds.BitsStored=8
ds.HighBit=7
ds.PixelRepresentation=0
ds.PhotometricInterpretation=“RGB”
ds.行=高度
ds.列=宽度
image=bob_ross_magic()
ds.PixelData=确保偶数(image.tobytes())
image.save(“output.png”)
ds.save_as(“output raw.dcm”,write_like_original=False)#文件正常
#
#创建压缩图像
#
输出=io.BytesIO()
image.save(输出,格式=“JPEG”)
ds.PixelData=确保偶数(output.getvalue())
ds.photommetricinterpretation=“YBR\u FULL\u 422”
ds.file_meta.TransferSyntaxUID=JPEG扩展
ds.save_as(“输出jpeg.dcm”,像_original=False一样写入)#文件已损坏
最后,我尝试创建压缩DICOM:我尝试设置各种传输语法,使用PIL进行压缩,但没有成功。我认为生成的DICOM文件已损坏。如果要将原始DICOM文件转换为使用gdcm工具压缩的JPEG:

$ gdcmconv -J output-raw.dcm output-jpeg.dcm
通过对该转换文件执行
dcmdump
,我们可以看到一个有趣的结构,我不知道如何使用pydicom进行复制:

$ dcmdump output-jpeg.dcm

# Dicom-File-Format

# Dicom-Meta-Information-Header
# Used TransferSyntax: Little Endian Explicit
(0002,0000) UL 240                                      #   4, 1 FileMetaInformationGroupLength
(0002,0001) OB 00\01                                    #   2, 1 FileMetaInformationVersion
(0002,0002) UI =SecondaryCaptureImageStorage            #  26, 1 MediaStorageSOPClassUID
(0002,0003) UI [1.2.826.0.1.3680043.8.498.57577581978474188964358168197934098358] #  64, 1 MediaStorageSOPInstanceUID
(0002,0010) UI =JPEGLossless:Non-hierarchical-1stOrderPrediction #  22, 1 TransferSyntaxUID
(0002,0012) UI [1.2.826.0.1.3680043.2.1143.107.104.103.115.2.8.4] #  48, 1 ImplementationClassUID
(0002,0013) SH [GDCM 2.8.4]                             #  10, 1 ImplementationVersionName
(0002,0016) AE [gdcmconv]                               #   8, 1 SourceApplicationEntityTitle

# Dicom-Data-Set
# Used TransferSyntax: JPEG Lossless, Non-hierarchical, 1st Order Prediction
...
... ### How to do the magic below?
...
(7fe0,0010) OB (PixelSequence #=2)                      # u/l, 1 PixelData
  (fffe,e000) pi (no value available)                     #   0, 1 Item
  (fffe,e000) pi ff\d8\ff\ee\00\0e\41\64\6f\62\65\00\64\00\00\00\00\00\ff\c3\00\11... # 4492, 1 Item
(fffe,e0dd) na (SequenceDelimitationItem)               #   0, 0 SequenceDelimitationItem
我尝试使用pydicom,但我认为它主要用于读取数据,而不是编写。还有谁知道如何处理这个问题,如何创建/编码这些
PixelSequence
s?希望在纯Python中创建JPEG压缩的DICOM,而无需运行外部工具。

DICOM需要压缩的像素数据(请特别参阅表格)。获得压缩图像数据后,可以使用该方法创建适合像素数据使用的
字节

从pydicom.encaps导入封装
#封装()需要字节列表,每帧一项
ds.PixelData=封装([确保偶数(output.getvalue())])
#需要设置此标志以指示像素数据已压缩
ds['PixelData']。是否未定义长度=真
ds.photommetricinterpretation=“YBR\u FULL\u 422”
ds.file_meta.TransferSyntaxUID=JPEG扩展
ds.另存为(“输出jpeg.dcm”,像原始文件那样写入=False)

尝试@scaramallion提供的解决方案,并提供更多细节:

import numpy as np
from PIL import Image
import io

# set some parameters
num_frames = 4
img_size = 10

# Create a fake RGB dataset
random_image_array = (np.random.random((num_frames, img_size, img_size, 3))*255).astype('uint8')
# Convert to PIL
imlist = []
for i in range(num_frames):   # convert the multiframe image into RGB of single frames (Required for compression)
    imlist.append(Image.fromarray(tmp))

# Save the multipage tiff with jpeg compression
f = io.BytesIO()
        imlist[0].save(f, format='tiff', append_images=imlist[1:], save_all=True, compression='jpeg')
# The BytesIO object cursor is at the end of the object, so I need to tell it to go back to the front
f.seek(0)
img = Image.open(f)

# Get each one of the frames converted to even numbered bytes
img_byte_list = []
for i in range(num_frames):
    try:
        img.seek(i)
        with io.BytesIO() as output:
            img.save(output, format='jpeg')
            img_byte_list.append(output.getvalue())
    except EOFError:
         # Not enough frames in img
         break

ds.PixelData = encapsulate([x for x in img_byte_list])
ds['PixelData'].is_undefined_length = True
ds.is_implicit_VR = False
ds.LossyImageCompression = '01'
ds.LossyImageCompressionRatio = 10 # default jpeg
ds.LossyImageCompressionMethod = 'ISO_10918_1'
ds.file_meta.TransferSyntaxUID = '1.2.840.10008.1.2.4.51'

ds.save_as("output-jpeg.dcm", write_like_original=False)

你能通过PyDicom读取JPEG压缩图像吗?是的,我当然能解压并读取它。当然,您需要安装一些额外的库,以下是可能的组合:这个用例是否每次都得到解决?我很想自己看一些关于它的文档。这很有效,但只适用于单帧jpeg。有人知道如何对多帧jpeg进行编码吗?每个帧都需要单独编码,然后用
封装([frame1,frame2,…])封装所有帧。