Search code examples
rraster

How to find bounding boxes of objects in raster?


I have a binary raster consisting of objects (1) and background (0). How can I find bounding boxes of objects? Each object should have its own bouding box.

Input:

library("raster")

mat = matrix(
  c(0, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 0, 0,
    0, 0, 1, 1, 1, 0,
    0, 0, 0, 0, 0, 0,
    0, 0, 1, 1, 0, 0,
    0, 1, 1, 1, 1, 0,
    0, 0, 1, 1, 0, 0,
    0, 0, 0, 0, 0, 0), 
  ncol = 6, nrow = 8, byrow = TRUE
  )

ras = raster(mat)

I expect this result:

result = raster(matrix(
  c(0, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 0,
    0, 1, 1, 1, 1, 0,
    0, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 0,
    0, 1, 0, 0, 1, 0,
    0, 1, 1, 1, 1, 0,
    0, 0, 0, 0, 0, 0), 
  ncol = 6, nrow = 8, byrow = TRUE
))

Solution

  • Here in an approach

    Example data

    library(raster)
    mat = matrix(
      c(0, 0, 0, 0, 0, 0,
        0, 1, 1, 1, 0, 0,
        0, 0, 1, 1, 1, 0,
        0, 0, 0, 0, 0, 0,
        0, 0, 1, 1, 0, 0,
        0, 1, 1, 1, 1, 0,
        0, 0, 1, 1, 0, 0,
        0, 0, 0, 0, 0, 0), 
      ncol = 6, nrow = 8, byrow = TRUE )
    
    ras <- raster(mat)
    

    Solution

    f <- function(r) {
        x <- reclassify(ras, cbind(0,NA))
        y <- rasterToPolygons(x, dissolve=TRUE)
        z <- disaggregate(y)    
        e <- sapply(1:length(z), function(i) extent(z[i,]))
        p <- spPolygons(e)
        r <- rasterize(p, r)
        d <- boundaries(r)
        reclassify(d, cbind(NA, 0))
    }
    
    r <- f(res)
    
    as.matrix(r)
    #     [,1] [,2] [,3] [,4] [,5] [,6]
    #[1,]    0    0    0    0    0    0
    #[2,]    0    1    1    1    1    0
    #[3,]    0    1    1    1    1    0
    #[4,]    0    0    0    0    0    0
    #[5,]    0    1    1    1    1    0
    #[6,]    0    1    0    0    1    0
    #[7,]    0    1    1    1    1    0
    #[8,]    0    0    0    0    0    0
    

    It is of course possible that bounding boxes of objects overlap, in which there is no solution, I suppose.