Python中的快速连接组件标签

时间:2013-11-20 17:43:03

标签: python performance matlab image-processing

我正在尝试识别图像堆栈中像素的连接区域。由于它是一个堆栈,输入非常大(大约1000万像素,尽管只有大约100万个是明亮的),并且逐像素地循环它是非常慢的。尽管如此,我的第一次尝试如下:

1)检查当前像素是否亮,如果是,请转到2.如果没有,请转到4。

2)获取包含所有26个邻居的图像切片。将尚未扫描的所有邻居设置为黑暗。将落在图像之外的所有邻居(例如-1的索引)设置为暗。将当前像素设置为暗。

3)如果切片中的所有像素都是暗的,则为当前像素分配新标签。如果切片中只有一个像素是亮的,则将当前像素标签设置为等于此亮像素的标签。如果多个像素是明亮的,则将当前像素设置为亮像素标签中的最低像素,并记录这些标签的等效性。

4)前进一排。扫描列中的所有行后,前进一列。扫描切片中的每个像素后,在堆叠中前进一个切片。扫描整个图像后,前进到5。

5)遍历等效列表,在输出中重新分配标签。

我不认为步骤2和3中的处理比其他类似算法慢得多,但我可能错了。我认为主要的瓶颈是简单地循环每个像素。我知道瓶颈不是#5因为我从来没有耐心地达到那个步骤。即使用print语句循环遍历图像索引也非常慢。我知道使用相同的数据我可以快速进行这种分析,所以我怀疑必须采用一种更聪明的方法来采用一种非常不同的方法。我读过一些关于进行扩张和使用交叉点的模糊内容,但我无法想象它们所暗示的机制是什么。

那里有什么快速而聪明的东西,或者这基本上是唯一的方法吗? MATLAB算法如何更快?

for i in xrange(0,nPix):
for j in xrange(0,nPix):
    for k in xrange(0,nFrames):
        if img[i,j,k] != 0: #If the current pixel is bright
            #Construct an array of already scanned
            #neighbors. Pixels are scanned first in z, then y,
            #then x.
            #Construct indices allowing for periodic boundary
            ir = np.array(range(i-1,i+2)).reshape(-1,1,1)%nPix
            jr = np.array(range(j-1,j+2)).reshape(1,-1,1)%nPix
            kr = np.array(range(k-1,k+2)).reshape(1,1,-1)%nFrames
            pastNeighbors = img[ir,jr,kr] #Includes i-1:i+1
            #Set all indices outside image and "future neighbors" to 0 
            pastNeighbors[2,:,:] = 0
            pastNeighbors[1,2,:] = 0
            pastNeighbors[1,1,2] = 0
            pastNeighbors[1,1,1] = 0 #Pixel itself; not a neighbor
            #Eliminate periodic boundary
            if i-1 < 0: pastNeighbors[0,:,:] = 0
            if i+1 == nPix: pastNeighbors[2,:,:] = 0
            if j-1 < 0: pastNeighbors[:,0,:] = 0
            if j+1 == nPix: pastNeighbors[:,2,:] = 0
            if k-1 < 0: pastNeighbors[:,:,0] = 0
            if k+1 == nFrames: pastNeighbors[:,:,2] = 0
            if np.count_nonzero(pastNeighbors) == 0: #If all dark neighbors
                label = label + 1 #Assign new label to pixel
                out[i,j,k] = label
            elif np.count_nonzero(pastNeighbors) == 1: #One bright neighbor
                relX, relY, relZ = np.nonzero(pastNeighbors)
                relX = relX - 1
                relY = relY - 1
                relZ = relZ - 1
                out[i,j,k] = out[i + relX, j + relY, k + relZ]
            else: #Mutliple bright neighbors
                relX, relY, relZ = np.nonzero(pastNeighbors)
                relX = relX - 1
                relY = relY - 1
                relZ = relZ - 1
                equiv = out[i + relX, j + relY, k + relZ]
                out[i, j, k] = np.min(equiv) #Assign one of the
                                             #multiple labels
                for i in xrange(0,equiv.size):
                    equivList = np.append(equivList, [[np.min(equiv),equiv[i]]], axis = 0)

0 个答案:

没有答案