将开放曲线转换为有序像素列表:使用numpy的Python测试代码
我有一个numpy数组中的开放曲线的图像,我需要建立一个点坐标列表,这些点坐标按照它们在曲线上的位置排序。 我用numpy和mahotas写了一篇文章。它可能不是最优的 我知道OpenCV可以对闭合曲线执行此操作。OpenCV可以对开放曲线执行相同(更快)的操作吗 例如,如果原始曲线为:将开放曲线转换为有序像素列表:使用numpy的Python测试代码,python,numpy,shape,curve,Python,Numpy,Shape,Curve,我有一个numpy数组中的开放曲线的图像,我需要建立一个点坐标列表,这些点坐标按照它们在曲线上的位置排序。 我用numpy和mahotas写了一篇文章。它可能不是最优的 我知道OpenCV可以对闭合曲线执行此操作。OpenCV可以对开放曲线执行相同(更快)的操作吗 例如,如果原始曲线为: [[0 0 0 0 0 0 0] [0 1 0 0 1 0 0] [0 0 1 0 0 1 0] [0 0 0 1 1 0 0] [0 0 0 0 0 0 0]] 使用np.where(myarray
[[0 0 0 0 0 0 0]
[0 1 0 0 1 0 0]
[0 0 1 0 0 1 0]
[0 0 0 1 1 0 0]
[0 0 0 0 0 0 0]]
使用np.where(myarray==1)
,我可以得到像素的索引:
(array([1, 1, 2, 2, 3, 3]), array([1, 4, 2, 5, 3, 4]))
但这不是我需要的。我的脚本根据曲线上像素的顺序生成索引:
i= 0 ( 1 , 1 )
i= 1 ( 2 , 2 )
i= 2 ( 3 , 3 )
i= 3 ( 3 , 4 )
i= 4 ( 2 , 5 )
i= 5 ( 1 , 4 )
我想优化我的脚本。有什么想法吗?假设矩阵/图像中只有一条曲线,并且曲线上的每个点都有1到2个相邻点,下面的函数将提供您需要的结果 它的工作原理是取最靠近左上角的点,并通过迭代查找最近的点(在没有其他点之前尚未访问)形成点链。对于闭合曲线,链上第一个/最后一个点之间的平方欧氏距离将小于2
import numpy as np
def find_chain(mat):
locs=np.column_stack(np.nonzero(mat))
chain=[np.array([0,0])]
while locs.shape[0]>0:
dists=((locs-np.vstack([chain[-1]]*locs.shape[0]))**2).sum(axis=1)
next=dists.argmin()
if dists.min()<=2 or len(chain)==1:
chain.append(locs[next,:])
locs=locs[np.arange(locs.shape[0])!=next,:]
else:
chain=[chain[0]]+chain[1::][::-1]
return np.vstack(chain[1::]),((chain[1]-chain[-1])**2).sum()<=2
对于闭合曲线:
>>> mat2=np.array([[0, 0, 0, 0, 0],
... [0, 0, 1, 0, 0],
... [0, 1, 0, 1, 0],
... [0, 1, 0, 1, 0],
... [0, 0, 1, 0, 0],
... [0, 0, 0, 0, 0]])
>>> points,isclosed=find_chain(mat2)
>>> points
array([[1, 2],
[2, 1],
[3, 1],
[4, 2],
[3, 3],
[2, 3]])
>>> isclosed
True
以及起点(离原点最近的点)将曲线一分为二的曲线
>>> mat3=np.array([[0, 0, 0, 0, 0],
... [0, 1, 1, 1, 0],
... [0, 1, 0, 0, 0],
... [0, 1, 0, 0, 0],
... [0, 0, 0, 0, 0],
... [0, 0, 0, 0, 0]])
>>> points,isclosed=find_chain(mat3)
>>> points
array([[1, 3],
[1, 2],
[1, 1],
[2, 1],
[3, 1]])
>>> isclosed
False
我已经写了另一个版本:亲爱的,我已经写了一个处理闭合曲线的扩展:[link]谢谢。你的代码确实比我的更紧凑。仅仅依靠numpy也是一个优势。为了处理通过形态学细化获得的曲线,需要进行一些预处理,因为一个像素可以有三个邻居。
>>> mat3=np.array([[0, 0, 0, 0, 0],
... [0, 1, 1, 1, 0],
... [0, 1, 0, 0, 0],
... [0, 1, 0, 0, 0],
... [0, 0, 0, 0, 0],
... [0, 0, 0, 0, 0]])
>>> points,isclosed=find_chain(mat3)
>>> points
array([[1, 3],
[1, 2],
[1, 1],
[2, 1],
[3, 1]])
>>> isclosed
False