Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python OpenCV/numpy:使用numpy快速比较大量轮廓对象_Python_Arrays_Opencv_Numpy - Fatal编程技术网

Python OpenCV/numpy:使用numpy快速比较大量轮廓对象

Python OpenCV/numpy:使用numpy快速比较大量轮廓对象,python,arrays,opencv,numpy,Python,Arrays,Opencv,Numpy,我从1024x1024个显微镜图像的z堆栈中识别了许多轮廓对象。每个z步包含大约10000-40000个轮廓。轮廓平均为4像素 我想做的是确定哪些轮廓存在于多个z平面上(当图像重叠时它们相互接触),以及它们的三维区域是什么。我可以做到这一点(大约),但代码速度非常慢,内存非常大(我正在为一台32GB的RAM计算机加满内存) 我目前的做法如下: 将每个轮廓的所有内部点转储到一个庞大的列表中,并制作一个索引列表 对x和y进行二进制比较,如: x_intersections=np.array(np.e

我从1024x1024个显微镜图像的z堆栈中识别了许多轮廓对象。每个z步包含大约10000-40000个轮廓。轮廓平均为4像素

我想做的是确定哪些轮廓存在于多个z平面上(当图像重叠时它们相互接触),以及它们的三维区域是什么。我可以做到这一点(大约),但代码速度非常慢,内存非常大(我正在为一台32GB的RAM计算机加满内存)

我目前的做法如下:

  • 将每个轮廓的所有内部点转储到一个庞大的列表中,并制作一个索引列表

  • 对x和y进行二进制比较,如:

    x_intersections=np.array(np.equal(np.matrix(z1[:,0]).T,z2[:,0]))
    y_intersections=np.array(np.equal(np.matrix(z1[:,1]).T,z2[:,1]))
    intersections=x_intersections*y_intersections
    
  • 重新索引到原始列表,以确定哪些点在Z步之间匹配

  • 确定体积

  • 我对第二步很好奇,这是一种更快的方法吗?我尝试过使用稀疏数组或使用
    np.inad()
    一次运行一个轮廓,但两种方法都没有运行得更快。我以前尝试过OpenCVs内置的点比较工具,但速度似乎不是很快

    另外,是否有一种方法不必将40000x40000矩阵拉入RAM(因为它需要大量RAM)是否有一种合理且快速的方法来细分这些列表?有没有一种聪明的方法可以使用numpy同时对阵列的一部分而不是整个阵列进行操作?有没有一种有效的方法可以暂时从RAM转储到磁盘上?这将允许我同时在更多的计算机上运行它,从而大大减少运行时间

    这是一个可以从numba的AutoJIT中获益的问题吗?还是火焰?还是派比?有没有一个类似的工具,我不知道它会在这里工作

    更广泛地说,我是在做傻事吗?我的方法是不是对这个问题有错误的理解

    我有时有20个z步、3个通道和100多个图像,所以即使是每次比较需要10秒的代码,最终每个图像也需要一个小时(大约我现在的位置)。我可以将它分散到一些服务器上以加快速度,但我真的希望尽可能地降低速度

    下面是一些python代码,用于模拟近似情况:

    z1=[]
    i=0
    while i<20000:
        temp=np.array([[[1,1]],[[1,2]],[[2,1]],[[2,2]]])+np.round(np.random.rand(1,1,2)*1024)
        z1.append(temp.astype(int))
        i+=1
    z2=z1[1:10000]
    i=0
    while i<10000:
        temp=np.array([[[1,1]],[[1,2]],[[2,1]],[[2,2]]])+np.round(np.random.rand(1,1,2)*1024)
        z2.append(temp.astype(int))
        i+=1
    random.shuffle(z2)
    

    然后,我使用上面步骤2中列出的代码将这些列表组合在一起(这是一个速度慢且占用大量内存的部分,如果运行它,可能会导致内存错误),并使用索引列表找出属于一起的轮廓对。

    下面是一些建议(基于我对你问题的理解。如果这不是你想要的,请告诉我)

  • 要比较两个轮廓,可以使用OpenCV中的函数
  • 或者,您可以计算所有轮廓的某些特征,如面积、周长、质心等。然后首先比较它们。只有当它们匹配时,才比较整个轮廓。两个具有相同质心和面积的轮廓很可能是相同的轮廓,因此您可以将这些轮廓作为一个整体进行比较,其他的则可以忽略,这将提高您的速度
    这是有效的,在逐像素比较之前,我比较了质心,将列表预排序为更小的子集。谢谢!
    output=(0,0)
    index_list=(0,0)
    for itemsN,items in enumerate(z1):
        output=np.vstack([output,items.squeeze()])
        index_list=np.vstack([index_list,np.ones((len(items),1))*itemsN])
    output=np.delete(output,0,0)
    index_list=np.delete(index_list,0)