Search code examples
rmagick

Trying to crop out center circle from polar coordinate picture


I've been struggling through a few iterations of solutions, trying to get a photo that's been converted to polar coordinates (originally rectangular hemispherical photo) to crop out areas outside of the circle. Initially following this [StackOverflow post]R magick: Square crop and circular mask with no luck. Here's the image I'm working with (in reality there are thousands I must process): Hemispherical photo rectangle

Here's the function I made:

 hemi_rect_to_polar <- function(hemi_rect_image){
  
  hemi_polar <- image_distort(hemi_rect_image,
                                   "Polar",
                                   c(0),
                                   bestfit = TRUE)
  
  min_dim <- min(image_info(hemi_rect_image)[2])
  
  figure <- image_draw(image_blank(min_dim,min_dim))
  symbols(min_dim/2, 
          min_dim/2, 
          circles = (min_dim/2), 
          fg = 'black', 
          add = TRUE)
  
  dev.off()
  
  return(hemi_polar)
}

and the output I got from that function, which has continued colors past the circular boundary that I need to get rid of for later analysis:

polar coordinates, stretched past bounding circle

I'm not sure why it keeps stretching the polar coordinates past the bounding circle.


Solution

  • I'm not sure if this is very efficient, but it works. Since this uses scaling, you only need to make one mask, then scale it to the image regardless of the image size. If the images are all the same size, then all you have to do is the composition.

    library(magick)
    
    path = "https://i.sstatic.net/XBDRI.jpg"
    img <- image_read(path)
    
    hemi_rect_to_polar <- function(hemi_rect_image){
      hemi_polar <- image_distort(hemi_rect_image,
                                  "Polar",
                                  c(0),
                                  bestfit = TRUE)
      return(hemi_polar)
    }
    
    he = hemi_rect_to_polar(img)
    
    # make the mask
    png(tf <- tempfile(fileext = "png"), 736, 736)
    par(mar = rep(0,4), yaxs="i", xaxs="i")
    plot(0, type = "n", ylim = c(0,1), xlim=c(0,1), axes=F, xlab=NA, ylab=NA)
    plotrix::draw.circle(.5,0.5,.5, col="black")
    
    # dump the temp file
    dev.off()
    
    # read in the plot as an image to use as a mask
    mask <- image_read(tf)
    # scale the mask for the image size
    mask <- image_scale(mask, as.character(image_info(he)$width))
    
    # crop the image
    image_composite(mask, he, "plus")
    

    enter image description here