working with tiff files in python

19,742

Solution 1

The TIFF file format is very versatile. Yes, it can store pixels in float format, it can even store complex-valued pixels. In general. On the other hand, as far as I know, PIL is not directly able to handle float-valued image data. Even more, saving image data with float-valued pixels is somewhat exotic to most of the world so that only few programs are able to that. And PIL is not one of those. Even numpy / scipy might not be able to store arrays of e.g. dtype=float32 as TIFF. One trick would be to use the TIFFlib directly, e.g. via cython or one could use vigra numpy (http://ukoethe.github.io/vigra/doc-release/vigranumpy/index.html). But, as you have to stick to PIL, all these might not be an option.

On the other hand: Why is it necessary to store the pixels as float? I understand, your program generates pixel values. The common solution here is to scale your float values to the range of 0..255. Let's say, the minimum float value and maximum float value of you red channel are stored in

rmin, rmax

Then apply the following scaling:

ri = int(255 * (r - rmin) / (rmax - rmin) )

assuming that r is your float value. The same for the green and blue channels. This way, you generate an int-valued image.

Finally, I would recommend to store the image using PNG image format which is portable, uses lossless compression and can store 24bit colors (so called 'true color').

Solution 2

Using cv2

import cv2
import numpy as np
image = cv2.imread('tif_file.tif')
image = np.asarray(image,dtype = np.float64)
Share:
19,742
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    First are tiff's grayscale? As I understand how tiff's work they can accept floating point numbers as most other image types cannot. I am attempting to do a linear interpolation for smooth coloring and need to put the floating point rgb array into this tiff image. What is the proper way to do this? As of right now I am using PIL and two for loops to iterate over the width and height of the new created tiff to put the pixels there and then converting to CMYK format, but when opening in a program such as Ifran it shows an apparently grayscale image and it doesnt look like the full image got generated, as in only half of it appears in the full image.

  • Admin
    Admin about 9 years
    Right and I've seen examples like this on SO doing the same thing with numpy however I can't use numpy, and I thought they could just wanted to double check to make sure that that wasn't the cause of my grayscale TIFF. All I can use is PIL without external modules such as libtiff or tiffany or numpy. So is there no way to do this with a 2-D list of float values between 0 - 255? I don't understand why I can't just simply pass my array of floats to this TIFF image I'm doing the same thing for a PPM image except with integers and it works perfectly
  • nEO
    nEO about 9 years
    as far as I know, I don't think you can convert an image, once read using PIL, into an array just by using PIL. We can wait for some more comments. But why can't you use any external library?
  • Admin
    Admin about 9 years
    Portability. Hmm maybe I misworded or misunderstand your comment, rather than trying to comment I have a much more detailed semi different version of this post as one of my other question that might explain in much more detail what exactly I'm trying to do
  • nEO
    nEO about 9 years
    please post the link to the same, and let me know what's you are looking for. What I got from your q, I posted back.
  • Admin
    Admin about 9 years
  • Admin
    Admin about 9 years
    What I'm trying to do is to render the mandelbrot set which works. I'm using the smooth coloring algorithim off of wikipedia for smooth colors to eleminate banding however these returns float rgb values, and I can't use gifs etc because I'll get allocation errors. I can use a ppm image but then I have to use int rgb value throwing off my color scale defeating the purpose. TIFF is the only format I know of that accepts floating point values as image data. So, I need to find a way to put my interpolated color array of float rgb values into the image and be able to render it
  • Admin
    Admin about 9 years
    Everything I've tried so far doesn't work. Whenever I put the array in as above I get a very distored image, either a few black bands across the image and thats it or changing a few things that I just found out how to do a very distorted grayscale mandelbrot rendering that appears to only display half the image of the set