Tôi đang cố gắng tạo một hình ảnh DICOM nén JPEG bằng pydicom . Một tài liệu nguồn hay về hình ảnh DICOM đầy màu sắc có thể được tìm thấy ở đây , nhưng chủ yếu là lý thuyết và C ++. Trong ví dụ mã bên dưới, tôi tạo một dấu chấm lửng màu xanh nhạt bên trong output-raw.dcm
(không nén) trông giống như thế này:
import io
from PIL import Image, ImageDraw
from pydicom.dataset import Dataset
from pydicom.uid import generate_uid, JPEGExtended
from pydicom._storage_sopclass_uids import SecondaryCaptureImageStorage
WIDTH = 100
HEIGHT = 100
def ensure_even(stream):
# Very important for some viewers
if len(stream) % 2:
return stream + b"\x00"
return stream
def bob_ross_magic():
image = Image.new("RGB", (WIDTH, HEIGHT), color="red")
draw = ImageDraw.Draw(image)
draw.rectangle([10, 10, 90, 90], fill="black")
draw.ellipse([30, 20, 70, 80], fill="cyan")
draw.text((11, 11), "Hello", fill=(255, 255, 0))
return image
ds = Dataset()
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.SamplesPerPixel = 3
ds.BitsAllocated = 8
ds.BitsStored = 8
ds.HighBit = 7
ds.PixelRepresentation = 0
ds.PhotometricInterpretation = "RGB"
ds.Rows = HEIGHT
ds.Columns = WIDTH
image = bob_ross_magic()
ds.PixelData = ensure_even(image.tobytes())
image.save("output.png")
ds.save_as("output-raw.dcm", write_like_original=False) # File is OK
#
# Create compressed image
#
output = io.BytesIO()
image.save(output, format="JPEG")
ds.PixelData = ensure_even(output.getvalue())
ds.PhotometricInterpretation = "YBR_FULL_422"
ds.file_meta.TransferSyntaxUID = JPEGExtended
ds.save_as("output-jpeg.dcm", write_like_original=False) # File is corrupt
Cuối cùng, tôi đang cố gắng tạo DICOM nén: Tôi đã thử thiết lập các cú pháp chuyển, nén khác nhau bằng PIL, nhưng không gặp may. Tôi tin rằng tệp DICOM được tạo bị hỏng. Nếu tôi chuyển đổi tệp DICOM thô thành JPEG được nén bằng công cụ gdcm:
$ gdcmconv -J output-raw.dcm output-jpeg.dcm
Bằng cách thực hiện dcmdump
trên tệp được chuyển đổi này, chúng ta có thể thấy một cấu trúc thú vị mà tôi không biết cách tái tạo bằng 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
Tôi đã cố gắng sử dụng mô-đun đóng gói của pydicom , nhưng tôi nghĩ rằng nó chủ yếu để đọc dữ liệu, không phải viết. Bất cứ ai khác có bất kỳ ý tưởng làm thế nào để đối phó với vấn đề này, làm thế nào để tạo / mã hóa những PixelSequence
s này ? Rất thích tạo các DICOM nén JPEG bằng Python đơn giản mà không cần chạy các công cụ bên ngoài.