Python OpenCV/numpy:使用numpy快速比较大量轮廓对象
我从1024x1024个显微镜图像的z堆栈中识别了许多轮廓对象。每个z步包含大约10000-40000个轮廓。轮廓平均为4像素 我想做的是确定哪些轮廓存在于多个z平面上(当图像重叠时它们相互接触),以及它们的三维区域是什么。我可以做到这一点(大约),但代码速度非常慢,内存非常大(我正在为一台32GB的RAM计算机加满内存) 我目前的做法如下: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
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
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中列出的代码将这些列表组合在一起(这是一个速度慢且占用大量内存的部分,如果运行它,可能会导致内存错误),并使用索引列表找出属于一起的轮廓对。下面是一些建议(基于我对你问题的理解。如果这不是你想要的,请告诉我)
这是有效的,在逐像素比较之前,我比较了质心,将列表预排序为更小的子集。谢谢!
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)