rimageimage-processingpolar-coordinatescartesian-coordinates

Mapping image from cartesian to polar coordinates with imageR


I am attempting to map a panoramic image into polar coordinates using imageR, but get strange results.

As an example, I would like to take a square panorama like this one (courtesy of Flickr user gadl (Alexandre Duret-Lutz) under CC BY-NC-SA and edited into a square):

square panorama

And remap it to something like this (which I've done in GIMP):

polar coordinate remapping of square panorama

I've gotten pretty close in imageR with this code:

library(imager)
pano <- mirror(load.image("pano_image.jpg"), "y") # mirroring the image to map to center
map.shift <- function(x,y) list(x = y*cos(x), y = y*sin(x)) # Here, y is the radius and x is theta
polar_pano <- imwarp(pano, map = map.shift)
plot(polar_pano)

But I get the strange result:

imager output of polar coordinate mapped panorama

I'm not sure why it is only mapping into one quadrant? (Note: I realize that the interpolation will be strange in this example--that is not the issue). To confirm that this should work, here is a toy example:

library(ggplot)
test <- data.frame("val" = rep(100:1, each = 99), theta = rep(1:100, 99), r = rep(1:100, each = 99))
ggplot(test, aes(x = theta, y = r, col = val)) + geom_point()

# Now converting from polar to cartesian
test$x <- test$r*cos(test$theta)
test$y <- test$r*sin(teast$theta)
ggplot(test_p2c, aes(x = x, y = y, col = val)) + geom_point()

Solution

  • Your result only has one quadrant because the resulting transformation has both negative and positive values.

    In your function, the result's top left is (-400, -400) and the bottom right is (400, 400). Halve and add 200 to make it (0, 0) and (400, 400).

    Scale the trig parameters to go from -pi to pi.

    For the bottom of the original image to become the center of the resulting circle, x needs to be the variable inside the trig functions.

    library(imager)
    
    pano <- load.image("pano_image.jpg")
    pano <- mirror(load.image("pano_image.jpg"), "y")
    
    map_shift <- function(x, y) {
      list(
        x = y * cos((x - 200) / 400 * 2 * pi) / 2 + 200,
        y = y * sin((x - 200) / 400 * 2 * pi) / 2 + 200
      )
    }
    
    polar_pano <- imwarp(pano, map = map_shift)
    plot(polar_pano)
    

    plot