Python中的快速连接组件标记

2024-06-02 04:21:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试识别图像堆栈中像素的连接区域。因为它是一个堆栈,所以输入相当大(大约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)

Tags: in图像forifnp切片像素标签