Comments (39)
Right now I am solving the problem by shelling out to dcmdjpeg
using this:
def load_dicom(input_file, force_decode=False, no_decompress=False):
assert not (force_decode and no_decompress)
import dicom
data = dicom.read_file(input_file)
if no_decompress or (not force_decode
and data is not None
and data.file_meta.TransferSyntaxUID in dicom.dataset.NotCompressedPixelTransferSyntaxes):
return data
with tempfile.NamedTemporaryFile(suffix=".dcm") as f:
# +cl --conv-lossy convert YCbCr to RGB if lossy JPEG
# +cn --conv-never never convert color space
# +px --color-by-pixel always store color-by-pixel
subprocess.check_output(['dcmdjpeg', '+cl', '+px', input_file, f.name])
data = dicom.read_file(f.name)
return data
from pydicom.
In a post[1] on the pydicom google group, cardioninja shared some concise code which can decompress 8-bit jpeg, if libjpeg-turbo and its cffi interface jpeg4py are installed. This was confirmed to work on files from Philips Echocardiography machines - iE33 & Affinity. Cardioninja also comments that it would be trivial to use PIL or Pillow instead, but libjpeg-turbo was much faster. Cardioninja's code is replicated below. As a side note, it also uses mmap, which is related to #139.
I think it would be interesting to add "handlers" for various types of compressed images through a plug-in architecture -- in this case, if the code was registered as a handler for 8-bit jpeg, then anyone with the right libraries already installed could transparently read those images.
Handlers should check for their dependencies and only register for transfer syntaxes they can decompress given the libraries installed. Perhaps a call function could also determine which additional libraries could give more functionality, so that pydicom could point to them in the NotImplemented exception message. (e.g. 'pydicom cannot handle this image, but if you installed <name/hyperlink>
then it should be able to via plugin <plugin-name>
'). If multiple handlers could process the file, the message would list all such options, so that the user could choose the easiest one to install for their platform. Such a plugin framework could also work for @Korijn's gdcm-calling code.
Here is cardioninja's 8-bit jpeg code:
import os
import sys
import mmap
import numpy as np
import jpeg4py
def jpeg_extract(file_fl):
frames = []
with open(file_fl, "r+b") as dicom_f:
with mmap.mmap(dicom_f.fileno(), 0) as dicom_m:
i = 0
while 1:
start = dicom_m.find(b"\xff\xd8\xff\xe0", i)
if start == -1:
break
i = start
end = dicom_m.find(b"\xff\xd9", i)
if end == -1:
break
try:
jpg_data = np.fromstring(dicom_m[start: end+2], dtype=np.uint8)
jpeg4py.JPEG.clear() #needed as if it ever fails, it won't decode another frame without a reset
image_data = jpeg4py.JPEG(jpg_data.copy()).decode()
frames.append(image_data)
except Exception as e:
print(e)
i = end
return np.array(frames)
[1] https://groups.google.com/d/msg/pydicom/PJ9K37dsmBk/OXLJtprjCQAJ
from pydicom.
From [email protected] on October 11, 2008 17:17:50
More info: Most important ones to add first will be the ones that have not been
retired, and especially the default transfer syntaxes:
First, ultra-short first-line defaults list, then more details follow:
- JPEG Lossless, Non-Hierarch, 1st-Order Prediction (Process 14 [Selection Value
1]) -- Default for Lossless JPEG Image Compression - JPEG 2000 Image Compression (Lossless Only)
- JPEG Baseline (Process 1) -- Default for Lossy JPEG 8 Bit
- JPEG Extended (Process 4) -- Default for Lossy JPEG 12 Bit
- JPIP and JPIP deflate
- RLE
Full details
(clipped from UID_dict)
- 1.2.840.10008.1.2.4.50: JPEG Baseline (Process 1) -- Default Transfer Syntax for
Lossy JPEG 8 Bit Image Compression - 1.2.840.10008.1.2.4.51: JPEG Extended (Process 2 and 4) -- Default Transfer
Syntax for Lossy JPEG 12 Bit Image Compression (Process 4 only) - 1.2.840.10008.1.2.4.57: JPEG Lossless, Non-Hierarchical (Process 14)
- 1.2.840.10008.1.2.4.70: JPEG Lossless, Non-Hierarchical, First-Order Prediction
(Process 14 [Selection Value 1]) -- Default Transfer Syntax for Lossless JPEG Image
Compression - 1.2.840.10008.1.2.4.80: JPEG-LS Lossless Image Compression
- 1.2.840.10008.1.2.4.81: JPEG-LS Lossy (Near-Lossless) Image Compression
- 1.2.840.10008.1.2.4.90: JPEG 2000 Image Compression (Lossless Only)
- 1.2.840.10008.1.2.4.91: JPEG 2000 Image Compression'
- 1.2.840.10008.1.2.4.92: JPEG 2000 Part 2 Multi-component Image Compression
(Lossless Only) - 1.2.840.10008.1.2.4.93: JPEG 2000 Part 2 Multi-component Image Compression
- 1.2.840.10008.1.2.4.94: JPIP Referenced
- 1.2.840.10008.1.2.4.95: JPIP Referenced Deflate
- 1.2.840.10008.1.2.4.100:MPEG2 Main Profile @ Main Level
- 1.2.840.10008.1.2.5': RLE Lossless
Summary: Provide PixelData decompression (JPEG, RLE, MPEG, etc)
Labels: -Priority-Medium -Milestone-Release1.5 Priority-High Milestone-Release1.0
from pydicom.
From [email protected] on October 15, 2008 05:57:03
Tried to find JPEG libraries to decode pixel data (tried using PIL and libjpeg
directly) -- can do it for lossy 8-bit but other images tried (lossless, lossy
12-bit) did not work in PIL.
An alternative is to incorporate C code, but am trying to keep to pure python or
installation of one other package like PIL. So at this point, the amount of work
involved is not worth it, and not core to what pydicom is meant to do. Postponing
jpeg decompression for now.
Status: WontFix
from pydicom.
From [email protected] on May 24, 2009 19:26:28
Reopening this issue. Medical image format FAQ has good info on libraries available. http://www.dclunie.com/medical-image-faq/html/part7.html#SourceJPEG PVRG looks good (note link to PDF documentation in section linked to above, else is
latex docs with the libraries themselves). Perhaps could create a separate package to
wrap PVRG for python, have it as an optional install that pydicom could use if
available, maybe eventually merge it in (but would ideally like to keep pydicom as
pure python package; much simpler!).
Status: New
Owner: ---
Labels: -Priority-High Priority-Medium Difficulty-Hard
from pydicom.
From [email protected] on May 25, 2009 20:44:57
Found pure python Huffman encoding/decoding (part of JPEG process) at http://pypi.python.org/pypi/huffman%20encoder%20%26%20decoder/0.3 . Has detailed
explanation [1] and walk through of optimizing the code [2]. But is GPL (on PyPI
page), so inclusion in pydicom would limit the more-free MIT license.
His optimization didn't seem to look into Numpy at all, maybe there is more there.
Maybe PVRG (very open license) could be "converted" to python (using Numpy in an
optimized way to get reasonable speed).
[1] http://gpolo.ath.cx:81/misc/huffman/ [2] http://gpolo.ath.cx:81/texts/opc
from pydicom.
From [email protected] on May 25, 2009 21:08:05
More research: code for DCT (also needed for JPEG I believe): http://projects.scipy.org/scipy/ticket/733 -- proposed code for DCT using numpy fft http://whiter4bbit.blogspot.com/2008/11/dct-python-implementation-warning-code.html -
- DCT using Numpy; quite short.
from pydicom.
From [email protected] on January 05, 2010 07:46:54
Just a suggestion -- libjpeg is widely installed in Unix/Linux land and is available
for Windows (although it's not installed by default). Why not make pydicom JPG
decompression conditional on libjpeg?
The same goes for PNG/libpng.
from pydicom.
From [email protected] on January 05, 2010 16:28:23
Just a suggestion -- libjpeg is widely installed in Unix/Linux land and is available
for Windows (although it's not installed by default). Why not make pydicom JPG
decompression conditional on libjpeg?
I'd be happy to use it if it would work. I did look at this a long time ago (see
comment from Oct 15, 2008), and only got it to work for 8-bit lossy images which
isn't very complete given that 12 or 16 bit images are common, and there are many
lossless techniques. It's a long time ago that I looked at this, but IIRC there were
some newsgroup discussions about many issues that other libraries such as dcmtk
and PVRG have had to deal with. I believe dcmtk started with libjpeg but had to
modify it and add in other codes for the various JPEG flavours allowed by DICOM. It
may make more sense to adopt their C code if any.
from pydicom.
From [email protected] on September 12, 2010 19:02:59
For JPEG, how about the Jasper library? I believe that OsiriX (Mac OS X DICOM viewer) uses it, and it's licensed under the MIT license. http://www.ece.uvic.ca/~mdadams/jasper/
from pydicom.
From [email protected] on September 12, 2010 19:25:07
OsiriX also uses OpenJPEG, which is BSD licensed. Not sure why the need for both. http://www.openjpeg.org/
from pydicom.
From [email protected] on March 06, 2014 14:54:27
Any updates on this? I'm currently using pydicom mixed with GDCM, looking to help incorporate a purely python way to decompress JPG images within DICOM.
from pydicom.
From [email protected] on March 07, 2014 15:36:26
No sorry, no update. I wonder, though ... IIRC I looked at GDCM once (or was it dcmtk?) and i remember seeing that they handled compressed images by calling a command line routine to convert to non-compressed in a temporary file, and then load that.
It would be fairly easy to add a "hook" in pydicom to call something like dcmtk to convert the file and then load it in. Would that be helpful?
And ... I'd be interested to know which specific compressed files (transfer syntax) people are encountering in the real world.
from pydicom.
From [email protected] on March 07, 2014 15:39:56
I've used dcmtk in conjunction with pydicom. I frequently run into JPEG-LS and JPEG2000 variants. A downside to dmctk is that there is no free module for encoding/decoding JPEG2000. That being said, OsiriX ( https://github.com/pixmeo/osirix ) uses dcmtk and they have their own way of handling JPEG2000 which you can look at in the source.
from pydicom.
From [email protected] on March 07, 2014 16:32:05
I'll try to have a look at OsiriX and see if there might be a way to build a C extension. If so, I could see that as a separate pydicom library (to keep the core pydicom pure python).
Just by way of explanation for anyone stumbling on this thread...my take on this issue (as in issue 16 ) is that it seems like a large amount of work to try to add decompression into pydicom (or related package), which has always had the philosophy of being light and very easy to install. This is why I've avoided it and recommend people pre-process compressed files with dcmtk or others.
To me, if the pydicom user has to go through the work of a complex installation with multiple dependencies, compiling C extensions, etc., then they might as well do so with one of the existing packages that already have that all worked out.
If there were a way to provide decompression in pure python or with minimal C, then I think that would be more in the spirit of pydicom. My hope was to perhaps handle a few of the most common compression formats that way.
I welcome anyone's thoughts on this subject.
Having said all that, on a more positive note: the various comments in this issue do seem to be converging on OsiriX as a good source to model, if anyone had the ambition to try to take this on. Realistically, it's not something I can see getting around to anytime soon.
from pydicom.
From [email protected] on March 09, 2014 07:48:53
Darcy, I'm using pydicom and GDCM for my prototype webservice dcmdb ( http://dcmdb.org ), so you can see I'm attempting to capture as many transfer syntaxes as possible ( http://dcmdb.org/main/transfer_syntax ). Using GDCM I have not have a transfer syntax issue as of yet.
I really want a pure python way to get images out of DICOM files, I know Ruby DICOM ( http://dicom.rubyforge.org/ ) was able to accomplish that goal, so I'm going to start really investigating solutions to this problem ... if you have any documentation that would be helpful on this journey, please let me know.
from pydicom.
From [email protected] on March 09, 2014 11:50:00
Eric,
I'm a bit confused. you're already using GDCM. are you using its Python extension? if so, what is the reason for a "pure Python" implementation?
in any case, OpenJPEG is really the best library out there, so you would need to do one of two things
- link to it, and then wrap an extension around it. which is what GDCM does. this is not pure Python, but is still usable from Python.
- compile it for Python, similar to how kripken has compiled it to JS ( https://github.com/kripken/j2k.js ). this would be pure Python
HTH
from pydicom.
From [email protected] on March 09, 2014 14:57:30
First, thank you to everyone for the discussion. It's good to get these ideas out there and see what we can come up with.
@neurosnap: I found this comment on ruby dicom: https://groups.google.com/forum/#!topic/comp.protocols.dicom/NMdlfkzpaII in which the author says it relies on ImageMagick but it only handles a subset of the JPEG variants. That comment is almost a year old though, so perhaps it has changed?
@mjpan: do you know any more about how the conversion to JS? It mentions using Emscripten, which I see is an LLVM to JS compiler. Is there a similar package to convert for python? And is there any hope of any of this working at an acceptable speed?
To all: I've toyed with some ideas on pure python implementations, but if you start reading through libjpeg (libijg)code (which dcmtk's jpeg is based on) it is incredibly intertwined. It is so heavily optimized for speed (and memory use) that it is very difficult to follow or translate to another language. It has been around a long time, so it comes from an era where speed and memory were very important. Plus (IIRC) there were many workarounds for known poor implementations and such. It would be very hard to replicate this in other code; I think that is why no one (very few?) have succeeded in doing so. Everywhere I looked, I just saw the same libijg code copied and pasted and minimally modified. In terms of difficulty, Jpeg2000 may be a different situation; I haven't really looked into those codes.
from pydicom.
From [email protected] on March 09, 2014 18:06:30
Thanks for the response, ideally I would like a better mechanism to deploy my server, something that would be easier to install besides GDCM, but I may be out of luck. I'll investigate openJPEG.
from pydicom.
From [email protected] on March 10, 2014 13:48:20
Darcy,
I'm sure that compiling OpenJPEG to pure Python can be done via LLVM, but I don't think anyone has had the motivation to do so, as it's possible to run C/C++ code in Python via an extension, as opposed to Javascript, which requires JS code to run in the browser.
for anyone looking for Python -> OpenJPEG, I'd suggest checking out Glymur. https://glymur.readthedocs.org/en/latest/introduction.html although I can't imagine it being any easier than building the GDCM Python extension-- CMake really makes things easy, especially as you go across operation systems
from pydicom.
From [email protected] on March 17, 2014 17:40:30
I just had a go at using Glymur to try to get pixel data out of a 1.2.840.10008.1.2.4.91: JPEG 2000 Image Compression'. I suspect that I am going about the problems that I have encountered incorrectly. However I am posting this comment here in case anyone can point out my mistake, or it is of help to anyone else investigating Glymur.
From the initial error messages it seemed that there was no header data. This seems consistent with, Part 5 of the DICOM standard section A.4.4 (p77) http://medical.nema.org/Dicom/2011/11_05pu.pdf staes:
"The optional JP2 file format header shall NOT be included. "
So far I have found Annex I of ISO15444-1 http://www.jpeg.org/public/15444-1annexi.pdf . Hoping DICOM pixel data contained a Contiguous Codestream, I attempted to create the relevant headings such that it could be simply read by the Glymur command for opening JPEG2000 files.
import dicom
d = dicom.read_file("/usr/lib/python2.7/dist-packages/dicom/testfiles/JPEG2000.dcm")
pd = d.PixelData
f = open("jp2000.jp2", "w+b")
f.write(struct.pack(">I4s4s", 12, "jP ", "\r\n\x87\n"))
f.write(struct.pack(">I4s4sI4s", 20, "ftyp", "jp2 ", 0, "jp2 "))
f.write(struct.pack(">I4s", 45, "jp2h"))
f.write(struct.pack(">I4sIIHBbBB", 22, "ihdr", d.Rows, d.Columns, d.SamplesPerPixel, d.BitsAllocated - 1, 7, 1, 0))#Need to add 128 d.BitsAllocated - 1 if pixel data is signed
f.write(struct.pack(">I4sBBBI", 15, "colr", 1, 0, 0, 16))
f.write(struct.pack(">I4s", len(pd), "jp2c"))
f.write(pd)
f.flush()
f.close()
jp2 = glymur.Jp2k("jp2000.jp2")
/home/martin/.virtualenvs/anat/local/lib/python2.7/site-packages/glymur/jp2box.py:135: UserWarning: Unrecognized box (����) encountered.
warnings.warn(msg)
/home/martin/.virtualenvs/anat/local/lib/python2.7/site-packages/glymur/jp2box.py:147: UserWarning: ���� box has incorrect box length (2822332288)
warnings.warn(msg)
jp2.read()
Traceback (most recent call last):
File "", line 1, in
File "/home/martin/.virtualenvs/anat/local/lib/python2.7/site-packages/glymur/jp2k.py", line 672, in read
img = self._read_openjpeg(**kwargs)
File "/home/martin/.virtualenvs/anat/local/lib/python2.7/site-packages/glymur/jp2k.py", line 713, in _read_openjpeg
self._subsampling_sanity_check()
File "/home/martin/.virtualenvs/anat/local/lib/python2.7/site-packages/glymur/jp2k.py", line 684, in _subsampling_sanity_check
dxs = np.array(codestream.segment[1].xrsiz)
IndexError: list index out of range
from pydicom.
From agrothberg on July 02, 2014 16:31:22
If the image is showing a TransferSyntaxUID=1.2.840.10008.1.2.4.50 ( http://www.dicomlibrary.com/dicom/transfer-syntax/ ) is there any way I can get access to the raw data and just hand it to PIL to decode?
A naive call to: dicom.contrib.pydicom_PIL.show_PIL(dataset) did not work.
from pydicom.
If you have the python wrappers installed for GDCM, you can use
http://mudicom.dcmdb.org/ which has some helper functions for GDCM for
reading, writing, and extracting images from DICOM files.
On Wed Jan 14 2015 at 12:39:29 AM Alex Rothberg [email protected]
wrote:
Right now I am solving the problem by shelling out to dcmdjpeg using this:
def load_dicom(input_file, force_decode=False, no_decompress=False):
assert not (force_decode and no_decompress)import dicom data = dicom.read_file(input_file) if no_decompress or (not force_decode and data is not None and data.file_meta.TransferSyntaxUID in dicom.dataset.NotCompressedPixelTransferSyntaxes): return data with tempfile.NamedTemporaryFile(suffix=".dcm") as f: # +cl --conv-lossy convert YCbCr to RGB if lossy JPEG # +cn --conv-never never convert color space # +px --color-by-pixel always store color-by-pixel subprocess.check_output(['dcmdjpeg', '+cl', '+px', input_file, f.name]) data = dicom.read_file(f.name) return data
—
Reply to this email directly or view it on GitHub
#18 (comment).
from pydicom.
Here is some relevant discussion on what can and cannot be done from Python with GDCM
:
- http://stackoverflow.com/questions/27936581/opening-file-like-object-with-python-wrapper-of-gdcm-grassroots-dicom
- http://stackoverflow.com/questions/27936473/using-gdcm-grassroots-dicom-to-decompress-dicom-image-data
from pydicom.
I have a few comments on this.
1.) As noted, the simplest solution is to call the dcmtk tool "dcmdjpeg" whenever you encounter a compressed image. You then load the decompressed version. In my experience dcmdjpeg is very robust, and handles all the formats well. This is what many of the professional solutions do (e.g. Osirix). The only disadvantage is making this a lighter tool that is more portable. The dcmtk code is very robust but is quite complicated (they compile the same JPEG libraries multiple times for different precisions, etc)
2.) You could also use my dcm2niix (also on Github). This is written in C, but is much less complicated than dcmtk. This uses the following libraries:
a.) lossy JPEG: nanoJPEG (already ported to Python)
b.) lossless JPEG: my own code - this is only Huffman coding so should be easy to adapt the Python NanoJPEG to do this. Note that this lossless JPEG is arcane and specific to medical imaging - my implementation provides 8, 16 (and 3*8 = RGB) bit precision. The downside here is that it is probably not a good idea to use a lookup table (which is very efficient for 8bit data. The 16-bit support is required for DICOM. This is not a very efficient compression scheme, but is very popular in CT (the default output of dcmcjpeg).
c.) OpenJPEG for lossy and lossless JPEG2000. The OpenJPEG API has changed a lot between versions and is really very complex. Unfortunately, the easier to implement JasPer appears to have some issues with high precision medical images (see Wiki for an example).
I have simpler executables that I am happy to send you to demonstrate each standard. In theory, you could hive these off one at a time as you add Python support, or use them as test references for building Python versions.
from pydicom.
One other comment - in many cases you can decompress images by using the operating system APIs. This tends to be very efficient. However, at the moment these do not seem sufficient for medical imaging, for example OS X 10.10 (Yosemite) the command "imageRepsWithContentsOfFile" will open JPEG2000 images but they are ALWAYS down sampled to 8-bit precision. This is different from TIFF images where the precision is preserved. Therefore, we really need custom libraries.
from pydicom.
How about using Pillow? It seems to support the full list of formats? Or imageio wich also seems to support them all?
from pydicom.
I have not tried these libraries, but I assume they would need to be extended to support DICOM's very arcane lossless JPEG (again, not hard - this is the Huffman decoding without the DCT). Also, make sure they do not decode 16-bit precision to 8-bit.
from pydicom.
Unless something has changed, PIL (or pillow AFAIK) did not support 16-bit, which is what most dicom grayscale images would be.
For imageio (http://imageio.readthedocs.org/en/latest/format_dicom.html#dicom):
This format borrows some code (and ideas) from the pydicom project, and (to the best of our knowledge) has the same limitations as pydicom with regard to the type of files that it can handle.
from pydicom.
The discussion here may help: python-pillow/Pillow#625
from pydicom.
I think Pillow actually does support 16-bit currently: python-pillow/Pillow#730 (from @jrkerns link, thanks!).
from pydicom.
See #232!
from pydicom.
Thanks. Thats my code (cardioninja) - I only saw your reply and issue just now.
Agree it would be nice to add to pydicom. Would you be happy including ctypes wrapper (jpeg4py) in the pydicom code; that way to utilise the helper the user would only have to drop in the dll/dylib/so downloaded from the website in the application directory?
Sketching out the code - with the simplest boiler plate:
####This is an example class###
class jpeg_ninja():
@staticmethod
def check_works()
##Check if libraries are present etc.
return 1
@staticmethod
def get_formats()
return [“jpeg”]
@staticmethod
def convert_pixels(link_to_pixel_data)
return np.array([[1,2],[2,3]])
###Generate this from DICOM specifications / known formats
pixel_formats = [“jpeg”, “jpeg_2000”, “fancy_new_format_200”]
###This bit makes a look-up dictionary to associate formats with pixel_handlers
###These are the classes
pixel_handlers = [jpeg_ninja, fancy_ninja]
pixel_lookup = dict.fromkeys(pixel_formats)
for handler in pixel_handlers:
try:
flag = handler.check_works()
if flag:
formats = handler.get_formats()
for format in formats:
pixel_lookup[‘format’] = handler
except Exception as e:
print(e)
#Having read a dicom file and worked out the format.
#It is nice if either a mmaped handle is passed (with the caller to close).
#Or a sequence of bytes that has the find method on it is passed to it.
if pixel_lookup[format] is not None:
pixels = pixel_lookup[format].convert_pixels(link_to_pixel_data)
I guess you could have a init on the handler classes so that they can initialise and return success from the, and re-use the instance each time you need to decode a dicom file. May save a few ms.
How does this sound?
BW
Matt
from pydicom.
I've mentioned in a couple of issues some old code I had tinkered with before, but I never tracked it down or explained it. I thought I'd do that here because I had discussed the concepts in an earlier comment in this issue.
I tried this because dataset.py
was getting quite complex and more decompression codes were coming in, so I started looking at a general system of 'plug-in' image handlers:
The config idea can be seen in https://github.com/pydicom/pydicom/blob/feaIture/image-handlers/pydicom/config.py#L63
From line 63 to 83 to about line 83 sets up a system to allow the user to choose at run-time, which handler routines to try, and in which order.
image_handlers = ['standard_handler', 'gdcm_handler'] # jpgls_handler, pil_handler
"""Image handlers for converting pixel data. These are tried in order
until one can provide the pixel data. The code is in the 'handlers' subdir.
Change the order if needed to force using a specific handler, e.g. for speed.
Handlers may require installation of dependencies. If dependencies are not
installed, the handler will not attempt conversion, and the next handler
would be called. If none can convert, the handlers will provide messages
on what dependencies are needed.
"""
Each handler should be split out into its own import
able file.
I started that at
https://github.com/pydicom/pydicom/tree/feature/image-handlers/pydicom/handlers, but it was left in a mess.
I was trying a couple of different 'api's of sorts, looking back now the easier one is a process' method, as in
standard_handler.py`:
def process(ds):
"""Return a numpy array of pixel data for the given data.
Returns:
-------
pixel_array: None, or numpy array
If unable to process the pixel data, returns None.
message: str
If unable to process, a message explaining libraries to install,
or reason it cannot be processed.
So each handler "answers" back with either the pixel data, or with None and a message. Note that even non-compressed images are handled this way -- so if someone wants, e.g. to use gdcm for all images, compressed or not, they can do so by changing the config order.
I think I had started trying to refactor pixel_array()
to use these modules, but can't find that code right now. Basically it called load_image_handler_modules()
to get the plugins, then called them in order until one worked. As they were called, messages were collected in a list. If none worked, then the list of messages was raised in an Exception.
from pydicom.
i try use python install model
pip install PyExecJS to run js,exp jpeg file,My English is bad sorry!
https://github.com/rii-mango/JPEGLosslessDecoderJS
I try to export the dicom file as a jpeg or other picture。
my dicom file is :
MediaStorage is 1.2.840.10008.5.1.4.1.1.6.1 [Ultrasound Image Storage]
TransferSyntax is 1.2.840.10008.1.2.4.70 [JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1]): Default Transfer Syntax for Lossless JPEG Image Compression]
from pydicom.
@qile11, I don't understand your request. Have you been using pydicom, or are you looking for a way to use pydicom for converting dicom files to an image?
from pydicom.
I think this one has been implemented now by @darcymason and can be closed.
@qile11 - please check the documentation, especially the parts about "Working with Pixel Data" and "Handling of compressed image data" for getting started.
from pydicom.
Thank you
i look about "Working with Pixel Data" and "Handling of compressed image data" 。not found EXAMPLES!
i try #738 (comment)
is not work
from pydicom.encaps import encapsulate
ImportError: cannot import name 'encapsulate'
try:
import numpy
import PIL
import pydicom
from pydicom import dcmread
# from pydicom.encaps import encapsulate
dicom_file=r"D:\pythontest\simpleiktdemo\dcmfile\bc.dcm"
dicom = pydicom.read_file(dicom_file, force=False)
print(dicom.PixelData )
if dicom.file_meta.TransferSyntaxUID.is_compressed is True:
dicom.decompress()
Traceback (most recent call last):
File "D:/pythontest/simpleiktdemo/pydcmtest11.py", line 10, in
dicom.decompress()
File "C:\Users\85447\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pydicom\dataset.py", line 768, in decompress
self.convert_pixel_data()
File "C:\Users\85447\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pydicom\dataset.py", line 743, in convert_pixel_data
raise NotImplementedError(msg)
NotImplementedError: No available image handler could decode this transfer syntax JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1])
print(dicom.PixelData ) is:
8\xd8\xc6" \x0f{\xe4\x92G\xbd\xe05\xad\x8e8\xda\xd6\xb5\xad\x01\xadh\x08\x88\x88\x8a\xaa\xaa\xa0I$\x92\xcb,\xd3M4\xd3=\xefs\x9c\x03Z\xd6\xb5\xa0\x00\xaa\xa8\x88\xc61\xadk\x18\xc4D\x00\x05UD@\x15VI${\xde\x03\x18\xc8 \x828\xe3kZ\x88\x88\x88\x02\xaa\xb9\xce\x96Y^\xf7\xc9$\x8a\xaa\xe78\x061\x8cc\x11\x11U^\xf7\xc9$\x8f{\xd5U\xadk\x18\xc8 \x82\x08 \x82\x08+\xd7\xae\xc61\x11\x18\xc6C\x0c5j\xd5\xadZ\xb4\x10@\xc61UQ\x11Ue\x96Ye\x96Ye\xe4\xf9>L\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdc\xdc\xdc\x96Yg\x9eye\x95\xef{\x9c\xe9$\x92I$DJ\xd5\xabQ\xa3F\xa5J\x95\xeb\xd7\x02I$\x96YlX\xb1$\x92\x00\xd6\xb4\x079\xca\xaa\xf7\xbd\xcer\xaa\xa2 \x009\xceUP\x18\xc65\xadkZ\x88\x88\x88\xaa\xaa\xaa\xaa\xa8\x88\xd6\xb5\x11\x18\xc61\x8c\x01\xadkZ\xd4Ds\x9c\xe7:\xcd\x9b7\xaf^\xbf~\xfe\x9e\x9e\x9e\x86\x86\x85\xabV\xa5\x96[\x16,[\xb7m\xces\x9c\xe8\xa2\x8a\x18a\x8e8\xda\xd6\x80\x88\x8a\xaa\x88\x88\x88\x88\x8a\xaa\x88\x8cc!\x86\x18 \x82\x08 \xadZ\xb4\x10A\x1cq\xc5\x14Q\xc7\x1c\x10A\x0c0\xc5\x14Q\xc7\x1a"*\xab\x9c\xe4D\x8e8\xe2\x8a&\xb5\xa8\x88\xaa\xaa\xaa\x00\x08\x88\xd6\xb5\x8cb"" \x00*\xaa\xaa\xb9\xce\x01\xadj"5\xadkZ\xf7\xbdUe\x96W9\xces\x91\x11\x11\x11\x10\x05U\x01\xcer\xaa\xaa\xa8\x0es\xa4\x92EUUP\x11\x11\x11\x1a\xd6\xb5\xad\x01\xef{\x9c\xe9$\x91\xcer"5\xad\x01\xef{\xde\xf5UUP\x00\x00\x00\x00UW\xbd\xees\x9c\xe7*\xaa\xaa\xb9\xce{\xde\xf7\xbd\xef{\xde\xf9e\x95\xcesZ\xd61\x91\xc7\x1bZ\xd61\x80\x00\xf7\xbei\xa6\xb9r\xe5\xabV\xac\xd9\xb3$\x92\x00\x88\x8a\xaa\x03Z\xd8\xe3\x8e\x18a\x86\x18c\x8e0\x1e\xf7\xcb,\xb2\xcb,\xb2\xca\x88\x91E\x15Z\xb5j\xd5\xabZ\xb5h\xa2\x89\x8ccZ\xd0\x1a\xd6\xb5\xadkZ\x88\x8dkQ\x11\xadj""#Z\xd4D\x01\x11\x18\xc6G\x1cqE\x14q\xc6\xd6\xb5\xces\xde\xf9e\x96Ye\x92I$\x92EUs\x9c\xf7\xbd\xef{\x9c\xe9$\x92I$\x96Y\\\xe7*\xacQE\x14QC\x0c,c\x18\xc65\xad\x01\xadh\x08\x88\x00\x005\xadkZ\xd6\xb5\x8ccZ\xd61\x88\x88\xd6\xb5\xadh\x08\x88\x02\xaa\x80\xaa\xa05\xadDEU{\xde\xe79\xcer\xaa\xb5\xadc\x19\x1cq\xb5\xadc\x18\xaa\xaes\x9e\xf7\xbd\xef\x01\xadk\x18\xc4DkZ\x02"\x00\x02\xaa\xa2#Z\xd0\x00\x01\xcer\xaa\x80\x88\x80*\xaa\xaa\xaa\xa8\x0es\x80\x92I\x1e\xf7\xcf<\xf3\xcf=\x8b\x16.\xdd\xbb~\xfd\xfd\x1d\x1d\x1d==;\xd7\xafh\xe8\xe8\xc5\x14T\xe9\xd3\xc7\xc7\xc7\xc5\xc5\xc5\xca\xca\xca\xa1B\x85z\xf5\xe0\x82\x06\xb5\xa8\x88\xc61\xadlq\xc6\xd6\xb5\x11\x11\x11UUUU@{\xdf$\x92=\xef{\xde\xf7\xbd\xadkZ\xd8\xa2\x89\xadlq\xc6\x88\x80"
....Omit.............
\x08\x88\xaa\xa0\x00\xe79\xces\xde\xf79\xca\xaa\xaa\xadkZ\xd6\xa2""\x00\x03\x9c\xe7\xbd\xea\xaa\x02"1\x8ckZ\x88\x805\xadDEUUW9\xca\xaa\xaa\xa0\x00\x02"*\xa8\rkb\x8a(\xe3\x8dU^\xf7\xcf<\xf2\xcb*\xaa\xa2""5\xadkZ\x02\xaa\xaa\xa8\n\xaa\xaa\xa0G\x1cq\xc7\x1cQE\x14Q1\x8cUW9\xcf{\xde\xf7\xb1\x8cc\x18\x03\xde\xf9$\x91\xcer\xaa\xb5\xad\x01\x11\x00\x028\xe3k[\x1cq\x80\xf7\xbeYes\x9c\x04q\xc6\xc628\xe3kZ\xe7:I$s\x9c\x88\x88\x88\x88\x8a\xaa\xe79\xef{\x9c\xe0\x11\x11\xadlq\xc6\xd6\xb5\xadj\xaa\xaa\xab\xde\xf7\xbd\xef{\xdc\xe7```\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xff\xd9 '
Traceback (most recent call last):
Is there a specific example file?
show me
from pydicom.
From the Handling of Compressed Images page in the docs you need to install GDCM or possibly Pillow to handle that transfer syntax.
If you want encapsulate
you should upgrade to the latest version.
from pydicom.
Related Issues (20)
- Comparing two codes where one is erroneously set as a SRT will throw KeyError
- Add support for encoding JPEG2000 and JPEG-LS
- ValueError: cannot reshape array of size HOT 13
- GDCM fails to decode JPEG-LS pixel data with bits stored 6 or 7 HOT 1
- Decoding failure for JPEG-LS pixel data when pixel representation is 1 and bits stored is less than bits allocated
- Decoding failure for JPEG-LS when Bits Allocated is 16 and Bit Stored <= 8 HOT 1
- The (0028,0101) 'Bits Stored' value (16-bit) doesn't match the JPEG 2000 data (14-bit) HOT 3
- Compressing PixelData does not change the VR from OW to OB HOT 1
- dicom saved can't match the plt.show HOT 1
- can pydicom realize dicom image registration HOT 1
- Return sequence items as a list? HOT 3
- Dataset decompress function does not update length of the pixel data HOT 1
- deepcopy on dataset with private block fails HOT 1
- Convenience function to get existing UID instance by string HOT 2
- Inconsistent color-space in `pixel_array` decompressed with `pylibjpeg` vs `gdcm` HOT 2
- Remaining Pixel Data work HOT 6
- Pillow unable to decode 9-bit J2K images correctly HOT 1
- Invoking pixel_array truncates valid data if NumberOfFrames is not defined HOT 4
- convert jpeg to dcm(c++) HOT 1
- J2K lossy decoding failures with Pillow on MacOS HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pydicom.