【问题标题】:Make distinction between inner and outer NA's in a raster in R在R中的栅格中区分内部和外部NA
【发布时间】:2017-11-07 16:00:21
【问题描述】:

在 R 中,我如何区分内部和外部 NA 的栅格,其中某种形状的周围和内部都有 NA

在下面的例子中,我怎样才能例如只选择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)")

【问题讨论】:

    标签: r r-raster no-data


    【解决方案1】:

    你真的没有太多选择。这种类型的分析通常需要一些更精细的方法。然而,这是一个使用clumpfunction 的简单解决方法:

    #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")
    

    【讨论】:

    • 谢谢 - 我也认为clump 是个好方法。从技术上讲,所需的输出在这里是rc_reclass = clump(is.na(r)),然后是rc_reclass[rc_reclass&gt;1]=NA,只选择外部NA,但因此您提供了一个足够的解决方案。谢谢!
    【解决方案2】:

    我同意@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 通道。我尝试了一些方法,例如 max、mean、mode、sd 等,但都无济于事。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      • 2011-07-22
      • 2019-06-26
      相关资源
      最近更新 更多