数据空间变换——栅格影像值域映射到0-255范围

前一段时间把多波段影像输入到深度网络进行训练的时候,由于我的多波段影像是用arcgis的【波段合成工具】来合成的,只是把原本的RGB三个波段的影像又加入了近红外、NDVI两个波段。在使用torchvision.transforms.TOTensor()把我的影像转为Tensor(关于如何转换这部分可以移驾到我的另一篇博文),但我看了一下这个函数似乎对所有通道的数据都做了归一化处理,所以我的训练就出了问题,因为我的影像除了RGB通道的值域在【0,255】,近红外和NDVI波段的值域都不在此范围,所以这一步无法做归一化处理。
数据空间变换——栅格影像值域映射到0-255范围_第1张图片

所以今天要分享的就是如何把波段转换到0-255范围
方法非常简单,和做归一化处理是一样的,只不过不是把数据映射到【0,1】之间,而是映射到【0,255】的范围。

工具

工具一:【栅格计算器】

工具二:
arcpy.ExtractByAttributes()函数、
arcpy.GetRasterProperties_management()函数、arcpy.CalculateStatistics_management()函数

流程

1.计算栅格的最大值和最小值

# -*- coding:UTF-8 -*-
import arcpy
# 路径
path = r'C:\desktop\ndvi.tif'
# 计算栅格的统计数据
arcpy.CalculateStatistics_management(path, '', '', '', '', '')
# 获得栅格的最小值和最大值
max_min = ['MAXIMUM','MINIMUM']
for i in max_min:
	result = arcpy.GetRasterProperties_management(path, i, 'Band_1')
	mean = result.getOutput(0)
	print mean

在结果可以看到我的ndvi.tif的最大值和最小值
数据空间变换——栅格影像值域映射到0-255范围_第2张图片

2.利用【栅格计算器】把栅格的值域映射至【0,255】

先把栅格的负值去掉
数据空间变换——栅格影像值域映射到0-255范围_第3张图片
去掉负值后,利用公式tif = tif * (255 / tif.max) 就可以把栅格映射到【0,255】这个范围了。
数据空间变换——栅格影像值域映射到0-255范围_第4张图片
但我以为到这里就可以结束了,但是现实无情打了我的脸,再次检查数据的最大值和最小值发现,最小值变成了科学计数法,可能是因为小数点后后面的值太多了。当我处理别的波段的时候有时候会出现负值,因此,为了安全起见,我决定把栅格中的【0,255】范围的值提取出来,溢出此范围的数据就不要了。

数据空间变换——栅格影像值域映射到0-255范围_第5张图片

3.按值提取(arcpy.ExtractByAttributes()函数)

# -*- coding:UTF-8 -*-
import arcpy
from arcpy import env
from arcpy.sa import *
# 工作空间位置,过程数据也会生成在这个路径
env.workspace = r"工作空间路径"
attExtract = ExtractByAttributes("DSM_transf255.tif", "VALUE >= 0")
attExtract1 = ExtractByAttributes(attExtract, "VALUE <= 255")
# 保存路径
attExtract1.save(r"C:\Users\Alai\Desktop\simple\DSM_transf255.tif")

经过这一次处理后,终于成功把栅格影像的值域映射到【0,255】这个范围。

思考

在做这一步操作的时候,我感觉我的做法不太严谨,不能把单幅栅格图的最大值作为255,而应该是以波段的范围的最大值做255做变换。
打个比方,例如近红外的波段范围是0-50,但是近红外栅格图范围是1-30,我在做变换的时候应该使用50作为最大值才符合实际。我也想这样去操作,但是我把无人机的近红外栅格图导入到arcgis去看,最大值是2万多,所以我不知道近红外的波段的最大值是多少,无法做更有价值的变换,只能出此下策。希望有懂行的小伙伴和我探讨探讨!

你可能感兴趣的:(遥感影像处理,图像处理,python)