在 R 中将 32 位浮点栅格转换为 16 位

Convert 32-bit float raster to 16-bit in R

我有大约 100 个不同的 4 波段卫星图像 .tif 栅格,它们具有浮点 32 位深度。我需要在 R 中将这些转换为 16 位无符号,同时缩放像素值(不仅仅是破坏高值),但我不知道从哪里开始,即使是单个栅格,更不用说整个批次了。任何帮助将不胜感激!

使用更多信息进行编辑:我在光栅包文档中搜索了位、像素和深度关键字,但运气不佳。根据在 dataType() 下找到的 min/max 像素值信息判断,我想从 FLT4S(32 位浮点)转到 INT2U(16 位)。我尝试使用 writeRaster() 设置数据类型,如示例所示,但输出只是黑白图像而不是普通卫星图像。

image
class      : RasterStack 
dimensions : 4300, 8909, 38308700, 4  (nrow, ncol, ncell, nlayers)
resolution : 3, 3  (x, y)
extent     : 691032, 717759, 57492, 70392  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=17 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
names      :        image.1,        image.2,        image.3,        image.4 
min values : 7.244503e-02, 8.278998e-02, 2.286164e-05, 8.571137e-02 
max values :    0.5347134,    0.3522218,    0.4896736,    0.7308348 

dataType(image) #[1] "FLT4S" "FLT4S" "FLT4S" "FLT4S"
image2 = writeRaster(image, 'new.tif', datatype='INT2U', overwrite=TRUE, format="GTiff")
dataType(image2) #[1] "INT2U"

image2
class      : RasterBrick 
dimensions : 4300, 8909, 38308700, 4  (nrow, ncol, ncell, nlayers)
resolution : 3, 3  (x, y)
extent     : 691032, 717759, 57492, 70392  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=17 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : new.tif 
names      : new.1, new.2, new.3, new.4 
min values :     0,     0,     0,     0 
max values :     1,     0,     0,     1 

在您的示例中,您有 0 到 1 之间的实数值。通过写入整数类型,这些都被截断为 0。如果您想写入 INT2U(无符号字节),您可以先将值缩放为介于 0 和 255 之间。

示例数据

library(raster)
b <- brick(system.file("external/rlogo.grd", package="raster"))
image <- clamp(b/255, 0, 0.6)
#class      : RasterBrick 
#dimensions : 77, 101, 7777, 3  (nrow, ncol, ncell, nlayers)
#resolution : 1, 1  (x, y)
#extent     : 0, 101, 0, 77  (xmin, xmax, ymin, ymax)
#crs        : +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
#source     : memory
#names      : red, green, blue 
#min values :   0,     0,    0 
#max values : 0.6,   0.6,  0.6 

你做什么(截断)

fname <- paste0(tempfile(), ".tif")      
x <- writeRaster(image, fname, datatype='INT2U', overwrite=TRUE)
x
#min values : 0, 0, 0 
#max values : 1, 1, 1 

但是注意四舍五入的区别

fname <- paste0(tempfile(), ".tif")      
y <- round(image)
z <- writeRaster(y, fname, datatype='INT2U', overwrite=TRUE)

s <- stack(x[[1]], z[[1]]) 
plot(s)

现在有一些缩放

maxv <- 65535
r <- round(image * maxv)
fname <- paste0(tempfile(), ".tif")
s <- writeRaster(r, fname, datatype='INT2U', overwrite=TRUE)

#s
#min values :     0,     0,     0 
#max values : 39321, 39321, 39321 

根据您的数据,您将获得

的最大值
round(maxv * c(0.5347134, 0.3522218, 0.4896736, 0.7308348 ))
#[1] 35042 23083 32091 47895

您还可以选择将所有层的最大值设置为 maxv,以保持更多变化(但使这些值不再与其他数据具有可比性)---如果您使用的是更相关较小的范围,例如 0-255.

ss <- round(maxv * image / maxValue(image))
#names      :   red, green,  blue 
#min values :     0,     0,     0 
#max values : 65535, 65535, 65535 

以上有效是因为最低值为零;如果你有负值你会做

ss <- image - minValue(image)
ss <- round(maxv * ss / maxValue(ss))

在其他情况下,您可能需要使用 clamp。所以你需要决定如何缩放

我展示的是线性缩放。还有其他方法。例如,还有 scale 方法,以改善数字的统计分布。 可能相关;但这取决于你的目标是什么。

注意。你不说你为什么这样做,那没关系。但是如果是为了节省硬盘space,可以用压缩代替(见?writeRaster