I'm reading a .TIF image using GDAL in Python, but when I re-plot the image it is significantly darker than the original image.
Additionally, it seems as though there are some intensity values in the 2D arrays that are over 255. Here's the code:
import gdal
import numpy as np
import matplotlib.pyplot as plt
tf = "pic.TIF"
img = gdal.Open(tf)
image_DN = np.zeros((img.RasterYSize, img.RasterXSize, img.RasterCount))
for band in range(img.RasterCount):
imgband = img.GetRasterBand(band + 1)
image_DN[:, :, band] = imgband.ReadAsArray()
# an array with the max value in each channel
maxes = np.zeros(img.RasterCount)
for i in range(img.RasterCount):
maxes[i] = np.amax(image_DN[:, :, i])
img_RGB_DN = np.rollaxis(np.asarray([1 / maxes[0] * image_DN[:, :, 0], \
1 / maxes[1] * image_DN[:, :, 1], \
1 / maxes[2] * image_DN[:, :, 2]]), 0, 3)
plt.figure(1)
plt.imshow(img_RGB_DN)
plt.title('original DN')
plt.show()
I am a beginner at image processing, so any details would be greatly appreciated.
Check the dtype of image_DN
You will likely see that this is not in uint8 format. Probably uint16 or float16/32. Hence the values can be much larger than 255. You can bruteforce convert the array to uint8 by using
image_DN = image_DN.astype(uint8)
If you like to rescale it to to the 0-255 integer range, you should convert the image to 8-bit. You can either do this manually using numpy using np.interp like this
image_DN = np.interp(image_DN, (minval, maxval), (0, 255)).astype(np.uint8)
Then it is a question of choosing a minval
and maxval
which makes sense.
GDAL can also solve this for you with gdal.Translate
like this
img = gdal.Translate('',
'pic.TIF',
options='-ot Byte -scale minval maxval -of MEM')