Python: Read and write TIFF 16 bit , three channel , colour images

后端 未结 6 2048
眼角桃花
眼角桃花 2020-12-07 14:32

Does anyone have a method for importing a 16 bit per channel, 3 channel TIFF image in Python?

I have yet to find a method which will preserve the 16 bit depth per ch

相关标签:
6条回答
  • 2020-12-07 15:13

    I recommend using the python bindings to OpenImageIO, it's the standard for dealing with various image formats in the vfx domain (which usually are 16/32bit).

    import OpenImageIO as oiio
    input = oiio.ImageInput.open ("/path/to/image.tif")
    
    0 讨论(0)
  • 2020-12-07 15:18

    The answer by @Jaime works.

    In the mean time I managed to also solve the problem using cv2.imread in OpenCV.

    By default cv2.imread will convert a 16 bit, three channel image in a.tif to 8 bit as shown in the question.

    cv2.imread accepts a flag after the filename ( cv2.imread(filename[, flags]) ) which specifies the colour type of the loaded image cf. the documentation:

    1. >0 returns a 3 channel colour image. This results in conversion to 8 bit as shown above.
    2. 0 returns a greyscale image. Also results in conversion to 8 bit.
    3. <0 returns the image as is. This will return a 16 bit image.

    So the following will read the image without conversion:

    >>> im = cv2.imread('a.tif', -1)
    >>> im.dtype
    dtype('uint16')
    >>> im.shape
    (288, 384, 3)
    

    Note that OpenCV returns the R, G and B channels in reverse order so im[:,:,0] is the B channel, im[:,:,1] the G channel and im[:,:,2] is the R channel.

    I have also found that cv2.imwrite can write 16 bit, three channel TIFF files.

    >>> cv2.imwrite('out.tif', im)
    

    Checking the bit depth with ImageMagick:

    $ identify -verbose out.tif
      Format: TIFF (Tagged Image File Format)
      Class: DirectClass
      Geometry: 384x288+0+0
      Resolution: 72x72
      Print size: 5.33333x4
      Units: PixelsPerInch
      Type: TrueColor
      Base type: TrueColor
      Endianess: MSB
      Colorspace: sRGB
      Depth: 16-bit
      Channel depth:
        red: 16-bit
        green: 16-bit
        blue: 16-bit
      ....
    
    0 讨论(0)
  • 2020-12-07 15:24

    For me the previous alternatives did not work. I have used gdal successfully for reading a 16bit images of 1 GB.

    You can open an image with something like this:

    from osgeo import gdal
    import numpy as np
    ds = gdal.Open("name.tif")
    channel = np.array(ds.GetRasterBand(1).ReadAsArray())
    

    There is a list of supported diver that you can use to write the data.

    0 讨论(0)
  • 2020-12-07 15:29

    Just struggled considerably trying to read a multi-image TIFF with JPEG compression using Scikits-Image (skimage.io). Am using a Windows 10 distribution of Anaconda Python3; tifffile was installed through Anaconda Navigator or 'conda install'.

    Finally, uninstalled 'tifffile' with 'conda remove tifffile'. Next re-installed 'tifffile' with 'pip install tifffile'. This installed the latest 'tifffile' plugin - version 2020.5.5. Next installed image codecs with 'pip install imagecodecs'. And now the following code works:

    import skimage.io
    img = skimage.io.imread('picture.tiff', plugin='tifffile')
    

    Note this only works if the install of 'tifffile' and 'imagecodes' was done in the order outlined above (and the Anaconda 'tifffile' is first removed).

    0 讨论(0)
  • 2020-12-07 15:33

    It has limited functionality, especially when it comes to writing back to disk non RGB images, but Christoph Gohlke's tifffile module reads in 3 channel 16-bit TIFFs with no problems, I just tested it:

    >>> import tifffile as tiff
    >>> a = tiff.imread('Untitled-1.tif')
    >>> a.shape
    (100L, 100L, 3L)
    >>> a.dtype
    dtype('uint16')
    

    And Photoshop reads without complaining what I get from doing:

    >>> tiff.imsave('new.tiff', a)
    
    0 讨论(0)
  • 2020-12-07 15:34

    I found an additional alternative to the two methods above.

    The scikit-image package can also read 16 bit, three channel TIFF files using both tifffile.py and FreeImage and specifying them as the plugin to be used.

    While reading using tifffile.py is probably done more simply in the manner shown by @Jaime, I thought I would show how it is used along with scikit-image in case anyone wants to do it in this manner.

    For anyone using Ubuntu, FreeImage is available as libfreeimage3 using apt.

    If the tifffile.py plugin option is used the tifffile.py must be copied to the skimage/io/_plugins directory (f.ex. on Ubuntu the full path in my case was /usr/local/lib/python2.7/dist-packages/skimage/io/_plugins/).

    >>> import skimage.io
    >>> im = skimage.io.imread('a.tif', plugin='tifffile')
    >>> im.dtype
    dtype('uint16')
    >>> im.shape
    (288, 384, 3)
    >>> im = skimage.io.imread('a.tif', plugin='freeimage')
    >>> im.dtype
    dtype('uint16')
    >>> im.shape
    (288, 384, 3)
    

    Writing TIFF files:

    >>> skimage.io.imsave('b.tif', im, plugin='tifffile')
    >>> skimage.io.imsave('c.tif', im, plugin='freeimage')
    

    Checking the bitdepth of both b.tif and c.tif using ImageMagick shows that each channel in both images are 16 bit.

    0 讨论(0)
提交回复
热议问题