gpt4 book ai didi

r - 识别R栅格数据包中的重叠区域

转载 作者:行者123 更新时间:2023-12-04 06:09:59 25 4
gpt4 key购买 nike

包裹:

  • raster

  • 数据:
  • 具有10个波段的rasterStack。
  • 每个波段都包含一个由NAs包围的图像区域
  • 频带是逻辑的,即图像数据为“1”,周围区域为“0”/NA
  • 每个波段的“图像区域”并不完全对齐,尽管大多数区域具有部分重叠

  • 客观的:
  • 编写一个快速函数,该函数可以为每个“区域”返回rasterLayer或像元编号,例如,仅包含来自波段1和2的数据的像素落入区域1,仅包含来自波段3和4的数据的像素落入区域2,等等。如果返回了rasterLayer,则稍后我需要能够将区域值与波段编号匹配。

  • 第一次尝试:
    # Possible band combinations
    values = integer(0)
    for(i in 1:nlayers(myraster)){
    combs = combn(1:nlayers(myraster), i)
    for(j in 1:ncol(combs)){
    values = c(values, list(combs[,j]))
    }
    }

    # Define the zone finding function
    find_zones = function(bands){

    # The intersection of the bands of interest
    a = subset(myraster, 1)
    values(a) = TRUE
    for(i in bands){
    a = a & myraster[[i]]
    }

    # Union of the remaining bands
    b = subset(myraster, 1)
    values(b) = FALSE
    for(i in seq(1:nlayers(myraster))[-bands]){
    b = b | myraster[[i]]
    }

    #plot(a & !b)
    cells = Which(a & !b, cells=TRUE)
    return(cells)
    }

    # Applying the function
    results = lapply(values, find_zones)

    我当前的函数需要很长时间才能执行。您能想到更好的方法吗?请注意,我不仅要知道每个像素有多少个波段有数据,还需要知道哪个波段。这样做的目的是事后对不同的区域进行不同的处理。

    还要注意,现实生活中的场景是3000 x 3000或更多的光栅,可能有10个以上的波段。

    编辑

    一些由10个偏移图像区域组成的样本数据:
    # Sample data
    library(raster)
    for(i in 1:10) {
    start_line = i*10*1000
    end_line = 1000000 - 800*1000 - start_line
    offset = i * 10
    data = c(rep(0,start_line), rep(c(rep(0,offset), rep(1,800), rep(0,200-offset)), 800), rep(0, end_line))
    current_layer = raster(nrows=1000, ncols=1000)
    values(current_layer) = data
    if(i == 1) {
    myraster = stack(current_layer)
    } else {
    myraster = addLayer(myraster, current_layer)
    }
    }
    NAvalue(myraster) = 0 # You may not want to do this depending on your solution...

    最佳答案

    编辑:答案使用Nick的技巧和矩阵乘法进行了更新。

    您可以尝试使用通过尼克的技巧和矩阵乘法优化的以下功能。瓶颈现在正在用不同的层填充堆栈,但是我想现在是时候了。内存使用量要少一些,但是考虑到您的数据和R的性质,我不知道您是否可以在不影响性能的情况下轻咬一下。

    > system.time(T1 <- FindBands(myraster,return.stack=T))
    user system elapsed
    6.32 2.17 8.48
    > system.time(T2 <- FindBands(myraster,return.stack=F))
    user system elapsed
    1.58 0.02 1.59
    > system.time(results <- lapply(values, find_zones))
    Timing stopped at: 182.27 35.13 217.71

    该函数返回具有绘图中存在的不同级别组合的rasterStack(不是所有可能的级别组合,因此您已经在其中有了一些增益),或者返回具有级别编号和级别名称的矩阵。这使您可以执行以下操作:
    levelnames <- attr(T2,"levels")[T2]

    获取每个单元点的级别名称。如下所示,您可以轻松地将该矩阵放入rasterLayer对象中。

    功能 :
     FindBands <- function(x,return.stack=F){
    dims <- dim(x)
    Values <- getValues(x)
    nn <- colnames(Values)

    vec <- 2^((1:dims[3])-1)
    #Get all combinations and the names
    id <- unlist(
    lapply(1:10,function(x) combn(1:10,x,simplify=F))
    ,recursive=F)

    nameid <- sapply(id,function(i){
    x <- sum(vec[i])
    names(x) <- paste(i,collapse="-")
    x
    })
    # Nicks approach
    layers <- Values %*% vec
    # Find out which levels we need
    LayerLevels <- unique(sort(layers))
    LayerNames <- c("No Layer",names(nameid[nameid %in% LayerLevels]))

    if(return.stack){
    myStack <- lapply(LayerLevels,function(i){
    r <- raster(nr=dims[1],nc=dims[2])
    r[] <- as.numeric(layers == i)
    r
    } )
    myStack <- stack(myStack)
    layerNames(myStack) <- LayerNames
    return(myStack)

    } else {

    LayerNumber <- match(layers,LayerLevels)
    LayerNumber <- matrix(LayerNumber,ncol=dims[2],byrow=T)
    attr(LayerNumber,"levels") <- LayerNames
    return(LayerNumber)
    }
    }

    使用RobertH的数据进行概念验证:
    r <- raster(nr=10, nc=10)
    r[]=0
    r[c(20:60,90:93)] <- 1
    s <- list(r)
    r[]=0
    r[c(40:70,93:98)] <- 1
    s <- c(s, r)
    r[]=0
    r[50:95] <- 1
    s <- (c(s, r))
    aRaster <- stack(s)


    > X <- FindBands(aRaster,return.stack=T)
    > plot(X)
    > X <- FindBands(aRaster,return.stack=F)
    > X
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
    [1,] 1 1 1 1 1 1 1 1 1 1
    [2,] 1 1 1 1 1 1 1 1 1 2
    [3,] 2 2 2 2 2 2 2 2 2 2
    [4,] 2 2 2 2 2 2 2 2 2 4
    [5,] 4 4 4 4 4 4 4 4 4 8
    [6,] 8 8 8 8 8 8 8 8 8 8
    [7,] 7 7 7 7 7 7 7 7 7 7
    [8,] 5 5 5 5 5 5 5 5 5 5
    [9,] 5 5 5 5 5 5 5 5 5 6
    [10,] 6 6 8 7 7 3 3 3 1 1
    attr(,"levels")
    [1] "No Layer" "1" "2" "3" "1-2" "1-3"
    "2-3" "1-2-3"

    > XX <- raster(ncol=10,nrow=10)
    > XX[] <- X
    > plot(XX)

    关于r - 识别R栅格数据包中的重叠区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5668596/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com