Python open jp2 images médicales - Scipy, glymur

j'essaie de lire et de carreler un fichier image jp2. L'image est rgb 98176 x 80656 pixels (il s'agit de données d'image médicale).

en essayant de lire l'image avec glymur je reçois cette erreur:

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

je comprends que l'image est trop grande. Ce dont j'ai besoin, c'est de lire les données d'image par tuiles et de les sauvegarder ailleurs et dans un autre format.

Glymur me permet de lire l'en-tête en utilisant python, donc par exemple, le flux de code est:

>>> 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))

Carrelage ne marche pas, la méthode de lecture ne fonctionne pas.

Edit:

j'ai essayé aussi Scipy qui est capable de lire l'en-tête mais la même chose, les erreurs qui surgissent sont:

>>> 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

y a-t-il un moyen de transférer les données de l'image dans un autre type de conteneur pour que le nombre d'indices ne pose pas de problème et me permette de le traiter?

10
demandé sur Zloy Smiertniy 2017-04-19 10:58:18

4 réponses

la norme pour lire d'énormes images médicales est openslide, j'essaierais d'abord. Je ne suis pas sûr qu'il lira jp2 directement, mais en supposant qu'il s'agit d'un scanner de diapositives, peut-être pourriez-vous sauvegarder dans l'un des formats qui openslide prend en charge?

ImageMagick chargera des sections de grandes images jp2 via OpenJPEG, bien que ce ne soit pas particulièrement rapide. J'ai un 10 km x 10 k jp2 image ici, par exemple, et si je convertir des fichiers JPG que je vois:

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

Si j'essaie d' découpe un petit morceau, c'est à peine plus rapide, suggérant que IM décode toujours toute l'image:

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

Mais si je ne le récolte au cours de la charge, il accélère:

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

pas génial, mais ça pourrait marcher si vous êtes patient.

4
répondu user894763 2017-04-20 13:14:41

je suis confronté aux mêmes problèmes à ces moments en utilisant des fichiers d'un scanner de diapositives. Ce que j'ai trouvé utile était de coller l'image en utilisant vips et openslide avec la commande suivante:

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

ceci affichera des tuiles de niveau 0 (pleine résolution) de l'image source avec la taille de tuile de votre choix et un pixeloverlap de 0 dans le répertoire tartget.

j'Espère que cela est de toute aide. Mario

4
répondu Mario Kreutzfeldt 2017-05-22 10:54:45

essayez-vous avec openslide?

import openslide
from openslide.deepzoom import DeepZoomGenerator
osr=openslide.OpenSlide('JP2.svs')
im=osr.get_thumbnail((200,200))
im.save('test.jpg')
3
répondu Anas Mubarak 2017-05-24 06:59:04

vous pouvez utiliser le module glymur en python pour accéder facilement à chaque tuile de l'image en pleine résolution

0
répondu Francisco Cunha 2017-05-02 17:54:49