Python open jp2 medical images - Scipy, glymur
Asked Answered
A

4

10

I am trying to read and tile a jp2 image file. The image is RGB 98176 x 80656 pixels (it is medical image data).

When trying to read the image with glymur I get this error:

glymur.lib.openjp2.OpenJPEGLibraryError: OpenJPEG library error:  Prevent buffer overflow (x1: 80656, y1: 98176)

I understand the image is too big. What I need is to read the image data by tiles and save them elsewhere and in another format.

Glymur allows me to read the header using python, so for instance, the code stream is:

>>> print(codestream.segment[1])
SIZ marker segment @ (87, 47)
    Profile:  no profile
    Reference Grid Height, Width:  (98176 x 80656)
    Vertical, Horizontal Reference Grid Offset:  (0 x 0)
    Reference Tile Height, Width:  (832 x 1136)
    Vertical, Horizontal Reference Tile Offset:  (0 x 0)
    Bitdepth:  (8, 8, 8)
    Signed:  (False, False, False)
    Vertical, Horizontal Subsampling:  ((1, 1), (1, 1), (1, 1))

Tiling doesnt work, the read method doesn't work.

Edit:

I tried also Scipy which is able to read the header but the same thing, errors that arise are:

>>> import scipy.misc
>>> image=scipy.misc.imread('Sl0.jp2')
/home/user/anaconda2/lib/python2.7/site-packages/PIL/Image.py:2274: DecompressionBombWarning: Image size (7717166080 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
  DecompressionBombWarning)
>>> scipy.misc.imwrite('/home/user/Documents/imageCfromjp2.tif',image)
/home/user/
AttributeError: 'module' object has no attribute 'imwrite'
>>> scipy.misc.imsave('/home/user/Documents/imageCfromjp2.tif',image)
/home/user/
  File "/home/user/anaconda2/lib/python2.7/site-packages/scipy/misc/pilutil.py", line 195, in imsave
    im = toimage(arr, channel_axis=2)
  File "/home/user/anaconda2/lib/python2.7/site-packages/scipy/misc/pilutil.py", line 287, in toimage
    raise ValueError("'arr' does not have a suitable array shape for "
ValueError: 'arr' does not have a suitable array shape for any mode.
>>> image2=image[0:500,0:500]
/home/user/
IndexError: too many indices for array
>>> image2=image[0:500]
/home/user/
ValueError: cannot slice a 0-d array

Is there any way to stream the image data into a different type of container so that the number of indices is not an issue and enables me to process it?

Adenoidectomy answered 19/4, 2017 at 7:58 Comment(0)
D
4

The standard thing for reading huge medical images is openslide, I'd try that first. I'm not sure it will read jp2 directly, but assuming this is from a slide scanner, perhaps you could save in one of the formats that openslide supports?

ImageMagick will load sections of large jp2 images via OpenJPEG, though it's not especially quick. I have a 10k x 10k jp2 image here, for example, and if I convert to JPG I see:

$ time convert sekscir25.jp2 x.jpg
real    0m25.378s
user    0m24.832s
sys 0m0.544s

If I try to crop out a small piece, it's hardly any quicker, suggesting that IM always decodes the entire image:

$ time convert sekscir25.jp2 -crop 100x100+0+0 x.png
real    0m19.887s
user    0m19.380s
sys 0m0.504s

But if I do the crop during load, it does speed up:

$ time convert sekscir25.jp2[100x100+0+0] x.png
real    0m7.026s
user    0m6.748s
sys 0m0.276s

Not great, but it might work if you're patient.

Darbee answered 20/4, 2017 at 10:38 Comment(4)
I tried some experiments and libvips sadly can't load images in sections via MagickCore, I'd forgotten that some issues with PingImage() make this impossible. I've changed my answer to point to crop-on-load in convert instead.Darbee
Hi. Thank you. I tried to work with OpenJPG before asking and I got: [INFO] Start to read j2k main header (85). [ERROR] Prevent buffer overflow (x1: 80656, y1: 98176) [ERROR] Marker handler function failed to read the marker segment ERROR -> opj_decompress: failed to read the header When working with convert I got: convert: no decode delegate for this image format JP2' @ error/constitute.c/ReadImage/501. convert: no images defined sdf.tiff' @ error/convert.c/ConvertImageCommand/3210. And I dont know how to install delegates.Adenoidectomy
I ended up loading it to matlab, sadly. I wanted to find a nice open way to not rely on private software. But I want to keep trying.Adenoidectomy
I tried openslide as well, but as you say it doesnt load jp2, but I could try and transform it to tiff and use openslide in my pipelineAdenoidectomy
S
5

I'm facing the same problems at them moment using files from a slide scanner. What I found useful was tiling the image using vips and openslide with the following command:

vips dzsave image.mrxs targetdirectoryname --depth one --tile-size 2048 --overlap 0

This will output tiles of level 0 (full resolution) of the source image with tile-size of your choosing and pixel overlap of 0 to the target directory.

Swifter answered 22/5, 2017 at 10:54 Comment(7)
This looks promising, thank you. What is the dzsave option for?Adenoidectomy
Sadly it doesn't work with jpeg 2000 but it is a starting point. My hope is to avoid using any private software and right now I use matlab to convert it from jp2 to tiff. But this is a great tool for DeepZoom.Adenoidectomy
Just out of curousity, which medical device outputs jp2 natively?Swifter
D-sight is the scanner our collaborators are using. But I would not recommend it. It has one heck of a compression though, but still, it is very hard to work with.Adenoidectomy
Thanks for the info. Didn't know this one. We are using the 3D Histech Pannoramic Flash 250 II. It's a great scanner, but the MRXS format is a pain to work with using open source tools.Swifter
Same thing here. Speaking from a person in the field to another, which image filetype would you recommend for use in histology?Adenoidectomy
I see a lot of people using aperio scanners. The API seems to be relatively open. The original publication of openslide has a nice summary of the current slide scanner formats link Currently, I am using a commercial software that opens all WSI formats without hassle. But it is very expensive and I'd like to move to open source. But it is not a trivial task.Swifter
D
4

The standard thing for reading huge medical images is openslide, I'd try that first. I'm not sure it will read jp2 directly, but assuming this is from a slide scanner, perhaps you could save in one of the formats that openslide supports?

ImageMagick will load sections of large jp2 images via OpenJPEG, though it's not especially quick. I have a 10k x 10k jp2 image here, for example, and if I convert to JPG I see:

$ time convert sekscir25.jp2 x.jpg
real    0m25.378s
user    0m24.832s
sys 0m0.544s

If I try to crop out a small piece, it's hardly any quicker, suggesting that IM always decodes the entire image:

$ time convert sekscir25.jp2 -crop 100x100+0+0 x.png
real    0m19.887s
user    0m19.380s
sys 0m0.504s

But if I do the crop during load, it does speed up:

$ time convert sekscir25.jp2[100x100+0+0] x.png
real    0m7.026s
user    0m6.748s
sys 0m0.276s

Not great, but it might work if you're patient.

Darbee answered 20/4, 2017 at 10:38 Comment(4)
I tried some experiments and libvips sadly can't load images in sections via MagickCore, I'd forgotten that some issues with PingImage() make this impossible. I've changed my answer to point to crop-on-load in convert instead.Darbee
Hi. Thank you. I tried to work with OpenJPG before asking and I got: [INFO] Start to read j2k main header (85). [ERROR] Prevent buffer overflow (x1: 80656, y1: 98176) [ERROR] Marker handler function failed to read the marker segment ERROR -> opj_decompress: failed to read the header When working with convert I got: convert: no decode delegate for this image format JP2' @ error/constitute.c/ReadImage/501. convert: no images defined sdf.tiff' @ error/convert.c/ConvertImageCommand/3210. And I dont know how to install delegates.Adenoidectomy
I ended up loading it to matlab, sadly. I wanted to find a nice open way to not rely on private software. But I want to keep trying.Adenoidectomy
I tried openslide as well, but as you say it doesnt load jp2, but I could try and transform it to tiff and use openslide in my pipelineAdenoidectomy
E
3

are you try it using openslide.

import openslide
from openslide.deepzoom import DeepZoomGenerator
osr=openslide.OpenSlide('JP2.svs')
im=osr.get_thumbnail((200,200))
im.save('test.jpg')
Ekaterinoslav answered 24/5, 2017 at 6:59 Comment(0)
D
0

You can use glymur module in python to easily access each tile of the full resolution image

Dexterous answered 2/5, 2017 at 17:54 Comment(4)
Here you can get useful info on how to install and use glymur [glymur.readthedocs.io/] Simply, let's say PATH is the path to my jp2 file. import glymur image=glymur.Jp2k(PATH) ` From here you will be able to read, for instance the first high resolution tile with the folllowing command: tile1=image.read(tile=0)Dexterous
You don't seem to understand the question. The image is too big. So no read method would work. glymur.lib.openjp2.OpenJPEGLibraryError: OpenJPEG library error: Prevent buffer overflow (x1: 80656, y1: 95680) OpenJPEG library error: Marker handler function failed to read the marker segmentAdenoidectomy
@ZloySmiertniy could you successfully finish the task? I am now facing similar problems with lack of support for jp2. Any idea about how to read and display such images using python for example?tksDexterous
@FranciscoCunha so far I have found GDAL so I will treat it as an image of GIS. #30466135Adenoidectomy

© 2022 - 2024 — McMap. All rights reserved.