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.
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With