Saya mencoba membuat gambar DICOM terkompresi JPEG menggunakan pydicom . Bahan sumber yang bagus tentang gambar DICOM berwarna-warni dapat ditemukan di sini , tetapi sebagian besar teori dan C ++. Dalam contoh kode di bawah ini saya membuat ellipsis biru pucat output-raw.dcm
(tidak terkompresi) yang terlihat baik seperti ini:
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
Pada akhirnya saya mencoba membuat DICOM terkompresi: Saya mencoba mengatur berbagai sintaks transfer, kompresi dengan PIL, tetapi tidak berhasil. Saya percaya file DICOM yang dihasilkan rusak. Jika saya mengkonversi file DICOM mentah ke JPEG yang dikompres dengan gdcm-tools:
$ gdcmconv -J output-raw.dcm output-jpeg.dcm
Dengan melakukan dcmdump
pada file yang dikonversi ini kita bisa melihat struktur yang menarik, yang saya tidak tahu bagaimana cara mereproduksi menggunakan 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
Saya mencoba menggunakan modul encaps pydicom , tapi saya pikir itu sebagian besar untuk membaca data, bukan menulis. Adakah yang punya ide bagaimana menangani masalah ini, bagaimana membuat / menyandikan ini PixelSequence
? Ingin sekali membuat DICOM terkompresi JPEG dalam Python polos tanpa menjalankan alat eksternal.
Jawaban:
DICOM membutuhkan Data Pixel terkompresi untuk dienkapsulasi (lihat tabel khususnya). Setelah Anda memiliki data gambar terkompresi, Anda dapat menggunakan metode encaps.encapsulate () untuk membuatnya
bytes
cocok untuk digunakan dengan Pixel Data :sumber
encapsulate([frame1, frame2, ...])
Mencoba solusi dari @scaramallion, dengan tampilan yang lebih detail:
sumber