Search code examples
rimage-processingtransformationpolar-coordinatesatan2

Polar-transform image in R


I am trying to transform an image (represented as a matrix) in R, into polar coordinate space with the origin being 0,0 (top left corner). Given the 215x215 matrix x which looks like:

enter image description here

x0 = as.vector(col(x))
y0 = as.vector(row(x))

r = sqrt( (x0^2) + (y0^2)  )#x
a = atan(y0/x0)#y
m = as.matrix(data.frame(y=a, x=r))

m = round(m)
m[m>215] = NA
m[m==0] = NA

xn = x[m]
xn = matrix(xn, 215, 215)

However, xn just looks like:

enter image description here

When I expect this:

enter image description here

Any idea what i'm doing wrong?


Solution

  • There is a problem with the angle: atan returns an angle in radians. if you round it, there is not much information left...

    Try with:

    a = atan(y0/x0) * 215 / (pi/2)
    

    Transformed image

    It is not the image you expect, which is apparently the inverse transformation, with the center in the middle of the image.

    # Load the image
    library(png)
    library(RCurl)
    d <- readPNG( getBinaryURL( "https://i.sstatic.net/rMR3C.png" ) )
    image(d, col=gray(0:255/255))
    
    # Origin for the polar coordinates
    x0 <- ncol(d)/2
    y0 <- nrow(d)/2
    
    # The value of pixel (i,j) in the final image 
    # comes from the pixel, in the original image, 
    # with polar coordinates (r[i],theta[i]).
    # We need a grid for the values of r and theta.
    r <- 1:ceiling(sqrt( max(x0,nrow(d))^2 + max(y0,ncol(d))^2))
    theta <- -pi/2 + seq(0,2*pi, length = 200)
    r_theta <- expand.grid(r=r, theta=theta)
    
    # Convert those polar coordinates to cartesian coordinates:
    x <- with( r_theta, x0 + r * cos(theta) )
    y <- with( r_theta, y0 + r * sin(theta) )
    # Truncate them
    x <- pmin( pmax( x, 1 ), ncol(d) )
    y <- pmin( pmax( y, 1 ), nrow(d) )
    
    # Build an empty matrix with the desired size and populate it
    r <- matrix(NA, nrow=length(r), ncol=length(theta))
    r[] <- d[cbind(x,y)]
    image(r, col=gray(0:255/255))