Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert 16-bit Tiff image to 8-bit RGB

Tags:

python

tiff

I'm dealing with some satellite images, consisting of 16-bit .tiff images. The color is encoded as 16-bit per channel. I would like to know how I can convert these images to normal 8-bit RGB for further CNN processing.

I have tried OpenCV (cv2.read('file',-1)) and PIL (read('file')), but these two packages cannot recognize and read 16-bit tiff images.

like image 556
qqxlafk Avatar asked Dec 10 '22 02:12

qqxlafk


2 Answers

Generally, when you want to read or write images in Python — of any bit-depth and format — it is best to use ImageIO. As the name suggests, its singular goal is to input/output images. Only caveat: It may ignore the image's meta data. That is: It may not deal correctly with images defining a color space other than the standard sRGB, or it might fail to preserve the image's intended orientation.

You would read in the image, say example.tif, like so:

import imageio
image = imageio.imread('example.tif')

As for the conversion, that's just basic math. The data structure in which you'll receive the pixel data is a NumPy array. Introspect image.shape and image.dtype. You should expect your images to have a shape of (y, x, 3), where y is the number of pixels in the vertical, x in the horizontal direction, and 3 represents the three color channels: red, green, blue. Its dtype (data type) should be uint16, meaning unsigned 16-bit integers.

Side note: As there are three color channels, each sampled with a 16-bit resolution, the color depth of the image is more commonly described as "48 bits" (per pixel).

16-bit integer numbers range between 0 and 65535 (= 216−1). They need to be coerced to the 8-bit range: 0 to 255 (= 28−1). So divide by 256 (= 28):

image = image / 256

This will yield an array of floating-point pixel values. Its data type must be explicitly cast to 8-bit integer in order to drop any fractions.

image = image.astype('uint8')

Equivalently, and more efficiently, you may also bit-shift the 16-bit values 8 bits to the right:

image = (image >> 8).astype('uint8')

This makes the conversion faster (by a factor of 2 or so on modern hardware) as it skips the floating-point operations.

Then, either use the final image array for further processing, or save it to a new file:

imageio.imwrite('example.png', image)
like image 65
john-hen Avatar answered Jan 03 '23 14:01

john-hen


If all you want is to convert, your .tiff file's color space to RGB. Then Try:-

from PIL import Image

img = Image.open(r"Path_to_tiff_image")
img = img.convert("RGB")
img.save(r"path_of_destination_image")

The above code, first opens a .tiff image, then changes its color mode to RGB. And then saves it to the destination location.

like image 29
Vasu Deo.S Avatar answered Jan 03 '23 12:01

Vasu Deo.S