【问题标题】:Matlab / Octave bwdist() in Python or CPython 或 C 中的 Matlab / Octave bwdist()
【发布时间】:2011-07-12 17:26:31
【问题描述】:

有谁知道 Matlab / Octave bwdist() 函数的 Python 替代品?此函数返回每个单元到给定矩阵的最近非零单元的欧几里得距离。我看到了一个 Octave C 实现,一个纯 Matlab 实现,我想知道是否有人必须在 ANSI C(不包含任何 Matlab / Octave 头文件,因此我可以轻松地从 Python 集成)或纯 Python 中实现它。

我提到的两个链接如下:

C++

Matlab M-File

作为测试,Matlab 代码/输出如下所示:

bw= [0   1   0   0   0;
     1   0   0   0   0;
     0   0   0   0   1;
     0   0   0   0   0;
     0   0   1   0   0]

D = bwdist(bw)

D =

   1.00000   0.00000   1.00000   2.00000   2.00000
   0.00000   1.00000   1.41421   1.41421   1.00000
   1.00000   1.41421   2.00000   1.00000   0.00000
   2.00000   1.41421   1.00000   1.41421   1.00000
   2.00000   1.00000   0.00000   1.00000   2.00000

我在 Python 中测试了一个推荐的 distance_transform_edt 调用,结果如下:

将 numpy 导入为 np 从 scipy 导入 ndimage

a = np.array(([0,1,0,0,0],
              [1,0,0,0,0],
              [0,0,0,0,1],
              [0,0,0,0,0],
              [0,0,1,0,0]))

res = ndimage.distance_transform_edt(a)
print res

[[ 0.  1.  0.  0.  0.]
 [ 1.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  1.]
 [ 0.  0.  0.  0.  0.]
 [ 0.  0.  1.  0.  0.]]

此结果似乎与 Octave / Matlab 输出不匹配。

【问题讨论】:

    标签: python matlab image-processing numpy scipy


    【解决方案1】:

    【讨论】:

    • 根据@jetxee 的评论,我更改了代码并且此调用有效。
    【解决方案2】:

    虽然 Matlab bwdist 返回到最近的非零单元的距离,但 Python distance_transform_edt 返回“到最近的背景元素”的距离。 SciPy 文档并不清楚它认为是什么“背景”,它背后有一些类型转换机制;实际上0 是背景,非零是前景。

    所以如果我们有矩阵a:

    >>> a = np.array(([0,1,0,0,0],
                  [1,0,0,0,0],
                  [0,0,0,0,1],
                  [0,0,0,0,0],
                  [0,0,1,0,0]))
    

    然后要计算相同的结果,我们需要用 0 替换 1,用 1 替换 0,例如考虑矩阵1-a:

    >>> a
    array([[0, 1, 0, 0, 0],
           [1, 0, 0, 0, 0],
           [0, 0, 0, 0, 1],
           [0, 0, 0, 0, 0],
           [0, 0, 1, 0, 0]])
    >>> 1 - a
    array([[1, 0, 1, 1, 1],
           [0, 1, 1, 1, 1],
           [1, 1, 1, 1, 0],
           [1, 1, 1, 1, 1],
           [1, 1, 0, 1, 1]])
    

    在这种情况下,scipy.ndimage.morphology.distance_transform_edt 给出了预期的结果:

    >>> distance_transform_edt(1-a)
    array([[ 1.        ,  0.        ,  1.        ,  2.        ,  2.        ],
           [ 0.        ,  1.        ,  1.41421356,  1.41421356,  1.        ],
           [ 1.        ,  1.41421356,  2.        ,  1.        ,  0.        ],
           [ 2.        ,  1.41421356,  1.        ,  1.41421356,  1.        ],
           [ 2.        ,  1.        ,  0.        ,  1.        ,  2.        ]])
    

    【讨论】:

      【解决方案3】:

      无需执行 1-a

      >>> distance_transform_edt(a==0)
          array([[ 1.        ,  0.        ,  1.        ,  2.        ,  2.        ],
                 [ 0.        ,  1.        ,  1.41421356,  1.41421356,  1.        ],
                 [ 1.        ,  1.41421356,  2.        ,  1.        ,  0.        ],
                 [ 2.        ,  1.41421356,  1.        ,  1.41421356,  1.        ],
                 [ 2.        ,  1.        ,  0.        ,  1.        ,  2.        ]])
          

      【讨论】:

        【解决方案4】:

        我认为您可以使用 OpenCV 中的distanceTransform() 计算源图像的每个像素到最近的零像素的距离。

        查看此链接:https://docs.opencv.org/3.4/d7/d1b/group__imgproc__misc.html#ga8a0b7fdfcb7a13dde018988ba3a43042

        【讨论】:

          猜你喜欢
          • 2017-04-30
          • 2014-07-13
          • 2017-02-16
          • 2014-10-03
          • 1970-01-01
          • 1970-01-01
          • 2012-05-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多