区分R中栅格中的内部和外部NA
Make distinction between inner and outer NA's in a raster in R
在 R 中,我如何区分内部和外部 NA
的栅格,其形状在周围和内部都有 NA
?
在下面的示例中,例如 select 我如何才能仅在 R 徽标之外显示 NA
(即,我如何制作徽标圆圈中包含的所有内容显示为白色)?
library(raster)
r <- raster(system.file("external/rlogo.grd", package="raster"))
r[r>240] = NA
par(mfrow=c(1,2))
plot(r, main='r')
plot(is.na(r), main="is.na(r)")
你真的没有太多选择。这种类型的分析通常需要一些更精细的方法。然而,这是一个使用 clump
函数的简单解决方法:
#your inital code
library(raster)
r <- raster(system.file("external/rlogo.grd", package="raster"))
rna <- rc <- r
rna[r>240] = NA
par(mfrow=c(2,2))
#reclass values <=240 to NA (needed for clump function.
#Here, NAs are used to seperate clumps)
rc[r<=240] <- NA
rc <- clump(rc)
#what you get after applying the clump function
#are homogenous areas that are separated by NAs.
#Let's reclassify all areas with an ID > 8.
#In this case, these are the areas inside the ring.
rc_reclass <- rc
rc_reclass[rc_reclass>8] <- 100
#let's do some plotting
plot(r, main='r')
plot(is.na(rna), main="is.na(r)")
plot(rc, main="clumps")
plot(rc_reclass, main="clumps reclass")
我同意@maRtin,这有点棘手。不仅没有专门的NoData值,而且图像有点脏
尽管如此,我认为我找到了一种比clump
更好的方法,它使用空间域来分隔区域:
首先,我得到像素邻域的焦点值:
#make copy
r2 <- r
# focal values
fv <- getValuesFocal(r2,ngb = c(3,3))
然后我首先排除邻域值大于242.8的所有像素。这纯粹是反复试验,但它给出了一个很好的结果。
ix <- rowMeans(fv,na.rm = T) > 242.8
r2[ix] <- NA
您实际上可能已经认为这是可以接受的。唯一的问题是,值区域周围有一个小边框,应该是 NA。
所以我需要以某种方式摆脱剩余的 NA 像素。我尝试通过迭代排除来做到这一点。对于每次迭代,我都会查看是否有像素仍然具有 NA 值并且最大值低于某个阈值。同样,这涉及到很多尝试,我想你可以获得比这更好的结果,但我想这是一个可行的方法。
while (TRUE){
fv <- getValuesFocal(r2,ngb = c(3,3))
ix <- apply(fv,1,function(x) max(x,na.rm=T)) > 243 & rowSums(is.na(fv)) > 0
if (any(ix)){
r2[ix] <- NA
} else {
break
}
}
经过几次迭代,我得到了这个:
显然已经有一些不应该消失的像素消失了,也许可以通过更多的摆弄来完成。
另一个有趣的想法是查看所有三个频道。如果你用 brick
加载图像,你可以获得 RGB 通道。我已经尝试了一些方法,例如最大值、平均值、模式、标准差等,但都无济于事。
在 R 中,我如何区分内部和外部 NA
的栅格,其形状在周围和内部都有 NA
?
在下面的示例中,例如 select 我如何才能仅在 R 徽标之外显示 NA
(即,我如何制作徽标圆圈中包含的所有内容显示为白色)?
library(raster)
r <- raster(system.file("external/rlogo.grd", package="raster"))
r[r>240] = NA
par(mfrow=c(1,2))
plot(r, main='r')
plot(is.na(r), main="is.na(r)")
你真的没有太多选择。这种类型的分析通常需要一些更精细的方法。然而,这是一个使用 clump
函数的简单解决方法:
#your inital code
library(raster)
r <- raster(system.file("external/rlogo.grd", package="raster"))
rna <- rc <- r
rna[r>240] = NA
par(mfrow=c(2,2))
#reclass values <=240 to NA (needed for clump function.
#Here, NAs are used to seperate clumps)
rc[r<=240] <- NA
rc <- clump(rc)
#what you get after applying the clump function
#are homogenous areas that are separated by NAs.
#Let's reclassify all areas with an ID > 8.
#In this case, these are the areas inside the ring.
rc_reclass <- rc
rc_reclass[rc_reclass>8] <- 100
#let's do some plotting
plot(r, main='r')
plot(is.na(rna), main="is.na(r)")
plot(rc, main="clumps")
plot(rc_reclass, main="clumps reclass")
我同意@maRtin,这有点棘手。不仅没有专门的NoData值,而且图像有点脏
尽管如此,我认为我找到了一种比clump
更好的方法,它使用空间域来分隔区域:
首先,我得到像素邻域的焦点值:
#make copy
r2 <- r
# focal values
fv <- getValuesFocal(r2,ngb = c(3,3))
然后我首先排除邻域值大于242.8的所有像素。这纯粹是反复试验,但它给出了一个很好的结果。
ix <- rowMeans(fv,na.rm = T) > 242.8
r2[ix] <- NA
您实际上可能已经认为这是可以接受的。唯一的问题是,值区域周围有一个小边框,应该是 NA。
所以我需要以某种方式摆脱剩余的 NA 像素。我尝试通过迭代排除来做到这一点。对于每次迭代,我都会查看是否有像素仍然具有 NA 值并且最大值低于某个阈值。同样,这涉及到很多尝试,我想你可以获得比这更好的结果,但我想这是一个可行的方法。
while (TRUE){
fv <- getValuesFocal(r2,ngb = c(3,3))
ix <- apply(fv,1,function(x) max(x,na.rm=T)) > 243 & rowSums(is.na(fv)) > 0
if (any(ix)){
r2[ix] <- NA
} else {
break
}
}
经过几次迭代,我得到了这个:
显然已经有一些不应该消失的像素消失了,也许可以通过更多的摆弄来完成。
另一个有趣的想法是查看所有三个频道。如果你用 brick
加载图像,你可以获得 RGB 通道。我已经尝试了一些方法,例如最大值、平均值、模式、标准差等,但都无济于事。