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?
Advertisement
Answer
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.