我希望能在一个二进制的NxM矩阵中计算出形状的凸包。凸包算法需要一个坐标列表,因此我使用numpy.argwhere(im)获取所有形状点的坐标。然而,大多数这些点并没有对凸包产生贡献(它们位于形状内部)。由于凸包计算时间至少与输入的点数成比例,所以我想到了一个过滤无用点的方法,并且只传递那些跨越轮廓的点。这个想法非常简单,对于二进制NxM矩阵中的每一行,我只取最小和最大的索引。例如:
然后大纲应该以元组或5x2的numpy数组形式呈现(我不介意):
任何紧贴在这个形状 (im) 上的凸包,必须是这些点 (outline) 的子集。换句话说,如果 "somefunc()" 能有效地过滤内部点,则可以节省凸包计算时间。
我已经有了实现上述技巧的代码,但我希望有人能提供更聪明(即更快)的方法,因为我需要多次运行它。我拥有的代码如下:
我有一个想法是使用Python的reduce()函数,这样我只需要遍历一次坐标列表。但我很难找到一个好的缩减函数。
非常感谢您的任何帮助!
编辑
与此同时,我已经找到了一种更快的方法,可以直接从im转换到outline。至少对于大图片来说,这种方法显著更快。在没有外部解决方案的情况下,我将其作为该问题的解决方案。
如果有人知道更快的方法,请告诉我 :)
im = np.array([[1,1,1,0],
[1,0,1,1],
[1,1,0,1],
[0,0,0,0],
[0,1,1,1]], dtype=np.bool)
outline = somefunc(im)
然后大纲应该以元组或5x2的numpy数组形式呈现(我不介意):
[(0,0),(0,2),(1,0),(1,3),(2,0),(2,3),(4,1),(4,3)]
任何紧贴在这个形状 (im) 上的凸包,必须是这些点 (outline) 的子集。换句话说,如果 "somefunc()" 能有效地过滤内部点,则可以节省凸包计算时间。
我已经有了实现上述技巧的代码,但我希望有人能提供更聪明(即更快)的方法,因为我需要多次运行它。我拥有的代码如下:
# I have a 2D binary field. random for the purpose of demonstration.
import numpy as np
im = np.random.random((320,360)) > 0.9
# This is my algorithm so far. Notice that coords is sorted.
coords = np.argwhere(im)
left = np.roll(coords[:,0], 1, axis=0) != coords[:,0]
outline = np.vstack([coords[left], coords[left[1:]], coords[-1]])
我有一个想法是使用Python的reduce()函数,这样我只需要遍历一次坐标列表。但我很难找到一个好的缩减函数。
非常感谢您的任何帮助!
编辑
与此同时,我已经找到了一种更快的方法,可以直接从im转换到outline。至少对于大图片来说,这种方法显著更快。在没有外部解决方案的情况下,我将其作为该问题的解决方案。
如果有人知道更快的方法,请告诉我 :)