【问题标题】:fast Cartesian to Polar to Cartesian in PythonPython中的快速笛卡尔到极坐标到笛卡尔
【发布时间】:2012-04-13 00:38:16
【问题描述】:

我想将 Python 2d 数组/图像转换为极坐标,然后进行处理,然后将它们转换回笛卡尔坐标。以下是 ImajeJ Polar Transformer 插件的结果(在示例代码的同心圆上使用):

图像的数量和暗度非常大,所以我正在检查 openCV 是否有快速简单的方法来做到这一点。

我读过关于 cv. CartToPolarPolarToCart 但我没有使用它。我更了解LogPolar,其中输入和输出是数组,您可以在其中设置中心、插值和反转(即CV_WARP_INVERSE_MAP)。有没有办法以类似的方式使用 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()

这适用于断层扫描 (CT) 工作流程,如果环形伪影显示为线条,则可以更轻松地过滤掉它们。

【问题讨论】:

    标签: python image-processing opencv numpy


    【解决方案1】:

    更新:我正在寻找类似的东西,现在您可以使用 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)
    
    

    【讨论】:

      【解决方案2】:

      opencv 最新版本支持函数 cv2.linearPolar。 这可能是另一种不涉及使用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
      

      【讨论】:

      • 嗨亚历山德罗-我也尝试用这种方式解决这个问题,并且我编写了类似的代码,尽管我使用了循环而不是网格网格(我以前从未见过);你知道这表现如何吗?我的 VGA 图像大约需要 1 秒 - 太长了。
      • 好的,我已经测试了你的代码,与我的迭代解决方案相比,它非常快——而且我学到了一些新东西——非常感谢!
      【解决方案3】:

      这是使用 SciPy 实现的对数极坐标变换的示例:

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

      鉴于这只是一个坐标变换,应该比OpenCV版本更容易适应你的问题。

      【讨论】:

      • 亲爱的 Stefan,非常感谢您的反馈。在接下来的几天里,我会检查你的实现并进行基准测试。顺便说一句,我最终浏览了 Supreme,看起来很有趣。你发表过任何关于它的文章吗?
      • @Papado 我从来没有看到你的评论,但是是的——有一篇关于 arXiv 的论文和一篇论文。顺便说一句,现在可以使用 skimage.transform.warp 在 scikit-image 上用大约 5 行代码在 scikit-image 之上实现对数极坐标变换。
      【解决方案4】:

      CV 源代码提到了LinearPolar。它似乎没有记录,但似乎类似于LogPolar。你试过吗?

      【讨论】:

      • 非常感谢!确实LinearPolar 做到了它所说的。不幸的是,通过使用import cv 它不可用,但我尝试了from opencv import cv 然后cv.cvLinearPolar 并且工作。下几天我将尝试它在大型数据集中的性能。谢谢!
      • 酷。我想知道为什么它不可见?我会尝试提交错误报告。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      相关资源
      最近更新 更多