Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fast Cartesian to Polar to Cartesian in Python

I want to transform in Python 2d arrays/images to polar, process then, and subsequently transform them back to cartesian. The following is the result from ImajeJ Polar Transformer plugin (used on the concentric circles of the sample code):

enter image description here

The number and dims of the images is quite large so I was checking whether openCV has a fast and simple way to do this.

I read about cv. CartToPolar and PolarToCart but I failed to use it. I understand better the LogPolar where the input and output are arrays, and where you can set the center, interpolation,and inversion (i.e CV_WARP_INVERSE_MAP). Is there a way to use CartToPolar/PolarToCart in an similar fashion?

    import numpy as np
    import cv

    #sample 2D array that featues concentric circles
    circlesArr = np.ndarray((512,512),dtype=np.float32)
    for i in range(10,600,10): cv.Circle(circlesArr,(256,256),i-10,np.random.randint(60,500),thickness=4)

    #logpolar
    lp = np.ndarray((512,512),dtype=np.float32)
    cv.LogPolar(circlesArr,lp,(256,256),100,cv.CV_WARP_FILL_OUTLIERS)

    #logpolar Inverse
    lpinv = np.ndarray((512,512),dtype=np.float32)
    cv.LogPolar(lp,lpinv,(256,256),100, cv.CV_WARP_INVERSE_MAP + cv.CV_WARP_FILL_OUTLIERS)

    #display images
    from scipy.misc import toimage
    toimage(lp, mode="L").show()
    toimage(lpinv, mode="L").show()

This is for a tomography (CT) workflow where rings artifacts can be filtered out easier if they appear as lines.

like image 801
Papado Avatar asked Mar 29 '12 11:03

Papado


2 Answers

Latest versions of opencv supports a function cv2.linearPolar. This may be another solution that does not involve the use of opencv:

def polar2cart(r, theta, center):

    x = r  * np.cos(theta) + center[0]
    y = r  * np.sin(theta) + center[1]
    return x, y

def img2polar(img, center, final_radius, initial_radius = None, phase_width = 3000):

    if initial_radius is None:
        initial_radius = 0

    theta , R = np.meshgrid(np.linspace(0, 2*np.pi, phase_width), 
                            np.arange(initial_radius, final_radius))

    Xcart, Ycart = polar2cart(R, theta, center)

    Xcart = Xcart.astype(int)
    Ycart = Ycart.astype(int)

    if img.ndim ==3:
        polar_img = img[Ycart,Xcart,:]
        polar_img = np.reshape(polar_img,(final_radius-initial_radius,phase_width,3))
    else:
        polar_img = img[Ycart,Xcart]
        polar_img = np.reshape(polar_img,(final_radius-initial_radius,phase_width))

    return polar_img
like image 62
alessandro.ferrari Avatar answered Oct 20 '22 05:10

alessandro.ferrari


the CV source code mentions a LinearPolar. it doesn't seem to be documented, but appears to be similar to LogPolar. have you tried that?

like image 41
andrew cooke Avatar answered Oct 20 '22 03:10

andrew cooke