R栅格包中的波段交叉

时间:2011-04-08 17:13:20

标签: r image-processing intersection raster

我的输入栅格由多个图层组成,每个图层区域都有一个没有数据值的图像区域。这些层不完全重叠,我试图输出一个文件,该文件只包含所有波段的交集(任何层上没有NoData值的区域)。

以下适用于几个图层,但不适用于我的真实文件中的50+(至少3000x3000像素):

library(raster)

fin = "D:\\temp\\all_modes.pix"
fout = "D:\\temp\\test.pix"

inbands = stack(fin, bands = c(3:20))
NAvalue(inbands) = 0

# Not great:
#out = all(is.na(inbands) == FALSE) * inbands
#writeRaster(out, filename=fout, format="PCIDSK", dtype="INT2U", overwrite=TRUE, NAflag=0)

# A little better:
#mymask = all(as.logical(inbands))
#mask(inbands, mymask, filename=fout, format="PCIDSK", dtype="INT2U", overwrite=TRUE, NAflag=0)

# Even better, don't need to keep everything (but still not efficient):
#trim(all(as.logical(inbands)) * inbands, filename=fout, format="PCIDSK", dtype="INT2U", overwrite=TRUE, NAflag=0)

# Even better, calculations get smaller as we progress (is it possible to do even better?)
for(i in 1:nlayers(inbands)){
 band_i = subset(inbands, i)
 inbands = trim(as.logical(band_i) * inbands)
}
writeRaster(inbands, filename=fout, format="PCIDSK", dtype="INT2U", overwrite=TRUE, NAflag=0)

有关如何更有效地执行此操作的任何想法/使其与大量图层一起使用?

3 个答案:

答案 0 :(得分:2)

我首先提出这个:

x <- trim(inband, filename='fout')

但我现在意识到这不会得到你想要的东西,因为它会返回至少一个层的值不是NA的区域(行/列);而不是所有值都不是NA的区域。

以下可能有效。具有至少一个NA值的所有单元格将变为带总和的NA(默认情况下,na.rm = FALSE)。

x <- sum(inband)
x <- trim(x)
r <- crop(inband, x)

可能接着是

r <- mask(r, x)

如果在x中为NA,则将r中的所有单元格设置为NA

答案 1 :(得分:1)

感谢您的回答,他们给了我很好的想法。我想出了这个,这要快得多:

myraster = stack(fn, bands) # You get the idea
NAvalue(myraster) = 0

# Tranform to 1 where there is data    
logical_raster = as.logical(myraster)

# Make a raster with 1 in the zone of intersection
a = subset(myraster, 1)
values(a) = TRUE
for(i in 1:nlayers(myraster)) {
  a = a & logical_raster[[i]]
}

# Apply the "mask" and trim to intersection extent
myraster = myraster * a
intersect_only = trim(myraster)

答案 2 :(得分:0)

我发现all / any是在长列表中进行逻辑AND / OR的方法。这里展示了两个相同的图,可以实现小栅格的目标。

#dummy data
m1 = cbind(matrix(NA, nrow = 4, ncol = 2), matrix(1, nrow = 4, ncol = 2))
m2 = t(m1)
m3 = matrix(rep(c(1, NA), 8), nrow = 4)
inbands = stack(lapply(list(m1, m2, m3), raster))

# first method, using & operator 
plot(inbands[[1]] & inbands[[2]] & inbands[[3]])

# second method, using `all`
plot(all(inbands))

在我的系统上有警告强制数字到逻辑。以下两种方法可以避免警告,但可能会更慢?它们在逻辑上是等价的,但你可能会将它们相互对抗,而不是上面的第二种方法。

plot(all(!is.na(inbands)))
plot(!any(is.na(inbands)))