# Visualization of 11-bit images

I'm trying to visualize a 11-bit TIFF image using matplotlib. To do it, I load the image using tifffile to obtain a 3D numpy array. Next, I have to down-sample the image because the array contains values beyond the range [0, 255]. Here is my code:

``````import tifffile as ti
from scipy.misc import bytescale

# transpose to make the shape [M, N, 3]
X = np.transpose(x_3band, (1,2,0))
X = bytescale(X)
plt.imshow(X)
plt.show()
``````

The problem is that the visualized picture is different with the picture visualized in QGIS (see the picture, the left picture is with matplotlib).

How can I show the picture like in QGIS?

QGIS is applying a contrast stretch.

A simple 2-98% stretch can be accomplished like this:

``````import numpy as np

def bytescale(data, in_min, in_max):

data = np.clip(data, in_min, in_max)
data = (data - float(in_min)) / float(in_max - in_min)
return np.array(data * 255, dtype=np.uint8)

in_min, in_max = np.percentile(data , (2,98))  # Where data = a single band
data = bytescale(data, in_min, in_max)
``````

Note this simple example doesn't handle NoData/Null/NaN values (hint: `np.nanpercentile`) and it is only scaling a single band/channel, you'll need to loop through each band, rescale/stretch and put the bands back together into a 3d array.

• It creates another image, but still it is very different from the image in QGIST. Here is the link: imgur.com/a/ScyC9UE – lenhhoxung Feb 13 at 16:35
• You can use other percentiles, or use a standard deviation stretch instead. Why not have a look at layer symbology in QGIS to see what stretch is being applied. – user2856 Feb 15 at 9:37