最近邻搜索对于多个数据来说太长了

Nearest Neighbor Search is too long for multiple datas

首先,我有一个我传递给参数的图像,我用 OpenCV(使用 cv.findContours 方法)检索他的所有轮廓。 我用我的 parseArray 方法解析这个列表,得到一个很好解析的 x,y 轮廓坐标列表 [(x1, y1), (x2, y2), ...] (这个列表的大小等于 24163 我的独角兽图像)

这是我的代码:

def parseArray(array):
    parsedArray = []
    for i in array:
        for j in i:
            parsedArray.append((j[0][0], j[0][1]))
    return parsedArray

def delItemList(index, list):
    del list[index: index + 1]

img = cv.imread(sys.argv[1])

canny = cv.Canny(img, 215, 275)
contours, hierarchies = cv.findContours(canny,cv.RETR_LIST, cv.CHAIN_APPROX_NONE)
parsedArray = parseArray(contours)

drawList = []

while (len(parsedArray) > 0):
    tmp = [(0,0)]
    tree = KDTree(parsedArray)
    dist, ind = tree.query(tmp, k=1)
    tmp[0] = parsedArray[int(ind)]
    drawList.append(parsedArray[int(ind)])
    delItemList(int(ind), parsedArray)

这里有一个 time :

我怎样才能大大减少我的循环时间(少于一秒),这可能吗?

我认为您大部分时间都花在了 while 循环中,所以我将重点关注这些行:

while (len(parsedArray) > 0):
    tmp = [(0,0)]
    tree = KDTree(parsedArray)
    dist, ind = tree.query(tmp, k=1)
    tmp[0] = parsedArray[int(ind)]
    drawList.append(parsedArray[int(ind)])
    delItemList(int(ind), parsedArray)

我的理解是,您想使用 KDTree 在轮廓点中找到点 [(0,0]] 最近的邻居,一旦找到,就将其从轮廓点中删除并重新开始。 这是昂贵的,因为您正在创建一个复杂的结构,该结构经过优化以仅对一个查询执行最近邻查询,然后您一次又一次地创建它。我可以建议你两个优化:

  1. 如果你出于任何原因想要保留KDTree,那么一次查询所有点:tree.query(tmp, k=len(parsedArray)) (c.f.scipy documentation)
  2. 计算 [(0, 0)] 和等高线每个点之间的距离,并按此距离对它们进行排序。您可以在其他线程上找到解决方案,例如