Search code examples
rimagecropmask

R- How can i crop/mask a image to AOI - Ebimage


I have an image and I want to crop/mask/cut it - I don't know the "good" word in English. Till now i work with ebimage library. My Image has the follow dimensions:

  dim          : 768 512 

I want the Image from left: 200 right:250 bottom:100 top:150. How can i crop it to this extent?

library(EBImage)
f = system.file("images", "sample.png", package="EBImage")
img = readImage(f)
display(img)
#get new extend??**
writeImage(img, "new_extent.png")

I have to do this for several images... Thanks in advance ;)


Solution

  • Images in EBImage are simply arrays. To crop the image, you just subset the first and second dimension of the array (which could have more than 2 dimensions). In your example this subset would be:

      ix <- 200:250
      iy <- 100:150
      dim(img) # determine the dimensions, 2 in this case
      new_img <- img[ix, iy]
      plot(new_img)
      writeImage(new_img, "new_img.png")
    

    If you know the coordinates for each image, you simple create the index for each image as indicated above. However, if you want to select the portion of each image to crop, you can use locator() with the image plotted as a raster image.

    Here is an example of interacting with the image.

    # Starting with EBImage loaded
      f <- system.file("images", "sample.png", package="EBImage")
      img <- readImage(f)
      plot(img)
    
    # This call to locator selects two points and places a red mark at each
      p <- locator(2, type = "p", pch = 3, col = "red")
      print(p)
    > $x
    > [1]  62.35648 314.30908
    > 
    > $y
    > [1] 166.1247 316.4605
    

    Image with marks placed by locator()

    # Convert the pairs of coordinates into a index to subset the array
      p <- lapply(p, round)
      i <- lapply(p, function(v) min(v):max(v))
      new_img <- img[i$x, i$y]
      plot(new_img)
    

    Cropped image