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):
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.
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
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With