简体   繁体   English

在 Python 中快速笛卡尔到极坐标到笛卡尔

[英]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.我想将 Python 2d 数组/图像转换为极坐标,然后进行处理,然后将它们转换回笛卡尔坐标。 The following is the result from ImajeJ Polar Transformer plugin (used on the concentric circles of the sample code):以下是ImajeJ Polar Transformer插件的结果(用在示例代码的同心圆上):

在此处输入图片说明

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.图像的数量和暗度非常大,所以我正在检查 openCV 是否有一种快速而简单的方法来做到这一点。

I read about cv.我读过简历。 CartToPolar and PolarToCart but I failed to use it. CartToPolarPolarToCart但我没有使用它。 I understand better the LogPolar where the input and output are arrays, and where you can set the center, interpolation,and inversion (ie CV_WARP_INVERSE_MAP ).我更了解LogPolar ,其中输入和输出是数组,您可以在其中设置中心、插值和反演(即CV_WARP_INVERSE_MAP )。 Is there a way to use CartToPolar/PolarToCart in an similar fashion?有没有办法以类似的方式使用 CartToPolar/PolarToCart?

    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.这适用于断层扫描 (CT) 工作流程,如果环伪影显示为线条,则可以更轻松地过滤掉它们。

Latest versions of opencv supports a function cv2.linearPolar. 最新版本的opencv支持函数cv2.linearPolar。 This may be another solution that does not involve the use of opencv: 这可能是另一个不涉及使用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

Here's an example of the log-polar transform implemented using SciPy: 以下是使用SciPy实现的对数极坐标变换的示例:

https://github.com/stefanv/supreme/blob/master/supreme/transform/transform.py#L51 https://github.com/stefanv/supreme/blob/master/supreme/transform/transform.py#L51

Given that this is only a coordinate transformation, it should be easier to adapt to your problem than the OpenCV version. 鉴于这只是一个坐标转换,它应该比OpenCV版本更容易适应您的问题。

the CV source code mentions a LinearPolar . CV源代码提到了一个LinearPolar it doesn't seem to be documented, but appears to be similar to LogPolar . 它似乎没有记录,但似乎与LogPolar类似。 have you tried that? 你试过吗?

Update: I'm looking for something similar and now you can do it round trip with cv2 as follow:更新:我正在寻找类似的东西,现在您可以使用 cv2 进行往返,如下所示:

import cv2
import math

# img -> your image 
h, w = img.shape[:2]
img_center = (h/2, w/2)
img_radius = math.hypot(h/2, w/2)

cart_2_polar_flag = cv2.WARP_FILL_OUTLIERS
img_forth = cv2.linearPolar(img, img_center, img_radius, cart_2_polar_flag)


polar_2_cart_flag = cv2.WARP_INVERSE_MAP
img_back = cv2.linearPolar(img_forth, img_center, img_radius, polar_2_cart_flag)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM