可视化RGBN图像的RGB波段

时间:2018-11-26 12:42:57

标签: image-processing neural-network python-imaging-library rgb image-scaling

我有一个PlanetScope的RGBN波段.tif卫星图像,我想对该图像进行神经网络预处理。当我在QGIS中查看图像时,会得到一个漂亮的RGB图像,但是当导入为numpy数组时,该图像非常轻。图片上的一些信息:

Type of the image :  <class 'numpy.ndarray'>

Shape of the image : (7327, 7327, 5)
Image Height 7327
Image Width 7327
Image Shape (7327, 7327, 5)
Dimension of Image 3
Image size 268424645
Maximum RGB value in this image 65535
Minimum RGB value in this image 1

图像为uint16类型。最后一个带(pic [:,:,5])在所有实例中仅显示一个奇异值(65535)。因此,我认为应该删除该频带,而保留RGBN频带,其信息如下:

Type of the image :  <class 'numpy.ndarray'>

Shape of the image : (7327, 7327, 4)
Image Height 7327
Image Width 7327
Image Shape (7327, 7327, 4)
Dimension of Image 3
Image size 214739716
Maximum RGB value in this image 19382
Minimum RGB value in this image 1

知道uint16图像的范围是0-65535,RGBN图像的最大值(19382)似乎很低。随后,函数“ skimage.io.imshow(image)”显示近乎白色的图像。我不明白为什么QGIS能够正确显示实色图像,而python无法显示。

通过pic = skimage.io.imread("planetscope_20180502_43.tif")

加载图像

我尝试过使用img_scaled = pic / pic.max()缩放图像并将其转换为uint8,然后使用img_as_ubyte(pic)查看图像但没有成功。我使用skimage.io.imshow(pic)查看图像。

如有必要,可以here下载图像。我合并该图像是因为以某种方式似乎无法使用某些软件包导入该图像(例如,Tifffile在此tif文件上不起作用)。

2 个答案:

答案 0 :(得分:1)

RGB通道的最大值低于N通道的最大值:

>>> pic.max(axis=(0,1))
array([10300,  7776, 11530, 19382, 65535], dtype=uint16)

但是看看RGB通道的平均值:它们远小于max / 2:

>>> pic.mean(axis=(0,1))
array([  439.14001492,   593.17588875,   542.4638124 ,  3604.6826063 ,
   65535.        ])

您在此处具有高动态范围(HDR)图像,并希望将其高范围压缩为8位以进行显示。最大值不会线性缩放,因为最高峰比平均图像值高一个数量级。绘制RGB值的直方图:

Histogram of RGB data

如果您使用某个比平均值高一些的因子进行线性缩放,而无视裁剪其余(现已曝光过度)的值,则可以显示它以查看是否有有效数据:

rgb = pic[..., :3].astype(np.float32) / 2000
rgb = np.clip(rgb, 0.0, 1.0)

但是要获得正确的图像,您将需要研究相机对数据的响应,以及通常如何将这些HDR图像压缩为8位以进行显示(我对卫星成像不熟悉)。 / p>

答案 1 :(得分:0)

谢谢您,我能够在此基础上加以解决。由于w-m已经很精巧地阐述了这个问题,所以我将在此处留下为解决该问题而编写的代码:

for i in range(0,4):
    min_ = int(np.percentile(image[:,:,i],2))
    max_ = int(np.percentile(image[:,:,i],98))

    np.maximum(image[:,:,i])
    np.minimum(image[:,:,i])

    image[:,:,i] = np.interp(image[:,:,i], image[:,:,i].min(), image[:,:,i].max(), (0,255))

image_8bit_scaled = skimage.img_as_ubyte(image)