3

I have a series of tiff images to load in Python.

First I use:

im=Image.open(*)

It loads and displays properly.

>>> im
PIL.TiffImagePlugin.TiffImageFile image mode=I;16 size=1408x1044 at 0x116154050
>>> type(im)
instance
>>> im.size
(1408, 1044)

Then I use:

imarray=numpy.array(im)

where

>>> imarray.shape
()
>>> imarray.size
1
>>> type(imarray)
numpy.ndarray
>>>  imarray
array(PIL.TiffImagePlugin.TiffImageFile image mode=I;16 size=1408x1044 at 0x116154050, dtype=object)

I have read this previous post and followed the instructions there, but I can't get imarray.shape and im.size to match.

Community
  • 1
  • 1
Echo
  • 667
  • 3
  • 8
  • 19
  • 2
    This might have to do with your version of PIL. Have you tried the solutions suggested [here](http://stackoverflow.com/q/15284601/190597)? – unutbu Mar 18 '15 at 19:11
  • If you're planning on doing **any** type of image manipulation I would suggest using OpenCV. They have Python bindings and make your life a lot easier including automatically converting the images into numpy arrays. – James Mertz Mar 18 '15 at 19:15
  • @KronoS OpenCV is *massive* overkill for simple image I/O. [Pillow](https://pillow.readthedocs.org/) or even [matplotlib](http://stackoverflow.com/a/15293007/1461210) offer much more lightweight solutions. – ali_m Mar 18 '15 at 19:20
  • @ali_m I agree however if the OP is looking to do manipulation of the images, that's where the heavyweight of OpenCV comes into great usefulness. – James Mertz Mar 18 '15 at 19:23
  • @KronoS We don't yet know what the OP wants to actually do with the images, so I wouldn't jump straight to recommending OpenCV at this stage – ali_m Mar 18 '15 at 19:28
  • @unutbu: Thank you. I tried. Now it is working. Would installing a newer version of PIL solve this problem? It took a long time to load 800 images. I wonder if there is a faster way – Echo Mar 18 '15 at 21:40
  • @KronoS thank you. I will consider openCV, because I do need to do some image processing on these. Would it be faster to load in with matplotlib and manipulate with openCV, or should I use openCV straight away? – Echo Mar 18 '15 at 21:43
  • @Echo OpenCV straight up would be the best option. However as ali_m stated take caution that using OpenCV has a steep learning curve. If you're **seriously** interested in Image Processing I would look at the [course laid out here](https://www.pyimagesearch.com/practical-python-opencv/) I've recently purchased it and have learned a lot. It goes into detail on how to use and setup OpenCV. You might also find [this interesting](http://blog.kronoskoders.com/posts/256664-installing-opencv-and-ffmpeg-on-windows) in installing OpenCV – James Mertz Mar 18 '15 at 22:02
  • @Echo: I'm not sure. My guess is that installing the latest version of Pillow would be *a* way to solve your problem. But I don't know if that would be any faster than the matplotlib solution. I haven't tested it since I'm having trouble finding or generating a `TIFF` file that PIL opens in `I;16` mode. – unutbu Mar 18 '15 at 23:50

2 Answers2

3

Here is a solution that copies the data into the numpy array.

    from PIL import Image
    import numpy as np
    import ubelt as ub

    # Grab some test data
    fpath = ub.grabdata('http://www.topcoder.com/contest/problem/UrbanMapper3D/JAX_Tile_043_DTM.tif')

    # Open the tiff image
    pil_img = Image.open(fpath)

    # Map PIL mode to numpy dtype (note this may need to be extended)
    dtype = {'F': np.float32, 'L': np.uint8}[pil_img.mode]

    # Load the data into a flat numpy array and reshape
    np_img = np.array(pil_img.getdata(), dtype=dtype)
    w, h = pil_img.size
    np_img.shape = (h, w, np_img.size // (w * h))
Erotemic
  • 4,806
  • 4
  • 39
  • 80
  • Thank you, this helped a lot. Please take into consideration that the `dtype` conversion dict is only partial, and may raise a `KeyError` in special cases. For example, my image's "mode" was "I;16", which translates to `np.uint16`. – Shovalt Jun 19 '20 at 05:40
  • 1
    Yes, hence the "may need to be extended" comment. – Erotemic Jun 19 '20 at 18:08
3

For TIFF image, you can simply use imageio

im = imageio.imread('filename')

Sometimes you might further need

im = np.array(im)

Panfeng Li
  • 3,321
  • 3
  • 26
  • 34