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