cgohlke / imagecodecs

Image transformation, compression, and decompression codecs
https://pypi.org/project/imagecodecs
BSD 3-Clause "New" or "Revised" License
111 stars 21 forks source link

Not get compression ratio of 10:1 #85

Closed teknasd closed 8 months ago

teknasd commented 8 months ago

JPEG 2000 Lossless typically achieves compression ratios of 10:1 to 20:1. Lossy compression allows higher compression ratios i.e. 50:1 up to 100:1

I tested the imagecodecs lib to compress the image data inside dicom file used for medical imaging. I am getting compression ratio or 2.5:1 only.

Code to encode file

import io
from PIL import Image
frame_data = []
dicom = dcm.dcmread("AA001.dcm")
image = Image.fromarray(dicom.pixel_array)
with io.BytesIO() as output:
    encoded = jpeg2k_encode(dicom.pixel_array, level=0)
    frame_data.append(encoded)
encapsulated_data = encapsulate(frame_data)
dicom.PixelData = encapsulated_data
from pydicom.uid import JPEG2000
dicom.file_meta.TransferSyntaxUID = JPEG2000
dicom.save_as("compressedAA001.dcm")

Code for comparison -


download = dcm.dcmread("compressedAA001.dcm")
sys.getsizeof(download.PixelData) / sys.getsizeof(orignal.PixelData) 

0.4395263580869234```

Is this the right way to call jpeg2k_encode function ?
[files.zip](https://github.com/cgohlke/imagecodecs/files/13040846/files.zip)
cgohlke commented 8 months ago

JPEG 2000 Lossless typically achieves compression ratios of 10:1 to 20:1

I don't think that applies to mathematical lossless, maybe visual . The ~2.3 compression ratio looks reasonable.

These are 14-bit data, not 16-bit, so use jpeg2k_encode(dicom.pixel_array, level=0, bitspersample=14)

The transfer syntax would need to be JPEG2000Lossless, no?