我有一些由1024 x 1024显微镜图像的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步骤中匹配。
确定音量。
我对第2步感到好奇,这是一种更快的方法吗?我尝试使用稀疏数组或使用np.in1d()
一次运行一个轮廓,但似乎运行速度都不快。我之前尝试过内置点对比工具的OpenCVs,它看起来并不是很快。
另外,有没有办法不必将40000x40000矩阵拉入RAM(因为需要大量的RAM)是否有合理而快速的方法来对这些列表进行分段?是否有一种聪明的方法来使用numpy来同时操作数组的某些部分而不是整个数组?有没有一种有效的方法暂时从RAM转储到磁盘上?这样我就可以在更多的计算机上同时运行它,大大减少了运行时间。
这是一个可以从numba的AutoJIT中受益的问题吗?还是Blaze?还是pypy?是否有一个我不知道的类似工具可以在这里工作?
更广泛地说,我在这里做些蠢事吗?我的方法是错误的方法来解决这个问题吗?
我有时会看到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)
(我的轮廓不是全长4,有些更少,但这应该足够接近演示)
然后我用大概代码将它们转储为数组:
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)
然后我使用上面在步骤2中列出的代码将列表一起转换(这是一个很慢的部分,是一个巨大的内存占用,如果你运行它可能会导致内存错误)并使用索引列表找出属于一起的轮廓对。
答案 0 :(得分:3)
以下是一些建议(基于我对您的问题的理解。如果这不是您想要的,请告诉我。)
cv2.matchShapes()
函数。