0

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

编辑更多信息:我在光栅包文档中搜索了位、像素和深度关键字,但运气不佳。根据 dataType() 下的最小/最大像素值信息判断,我想从 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 
4

1 回答 1

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一种方法,可以改善数字的统计分布。这可能是相关的;但这取决于你的目标是什么。

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

于 2020-12-16T19:44:12.793 回答