我正在尝试识别图像堆栈中像素的连接区域。由于它是一个堆栈,输入非常大(大约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)