import numpy as np
def Connection_List(data):
"""
:param data: 三维 numpy 数组
:return: 返回相同连通域编号及pixel个数,同时返回pixel位置
"""
I, J, K = np.shape(data) # rows, cols, Z
label_table = np.zeros((I, J, K))
# Connected Components Iteration
def CCIteration(i, j, k, mask, CCListPosition):
# 判断是否越界,是否已经递归,
if i < 0 or i >= I or j < 0 or j >= J or k < 0 or k >= K or label_table[i, j, k] != 0 or data[i, j, k] != 1:
return 0
label_table[i, j, k] = mask
ret = 1
# three dim to search
x = [i, i + 1, i - 1]
y = [j, j + 1, j - 1]
z = [k, k + 1, k - 1]
# cases: 3*3*3,三个维度递归遍历
for xi in range(3):
for yi in range(3):
for zi in range(3):
# if xi != 0 and yi != 0 and zi != 0: # 加此判断不包含斜对角, 不加则斜对角也算同一连通域
ret += CCIteration(x[xi], y[yi], z[zi], mask, CCListPosition) # 递归
# 列表保存,
if mask not in CCListPosition.keys():
CCListPosition[mask] = [(i, j, k)]
else:
CCListPosition[mask].append((i, j, k))
return ret
########################################################################################
mask = 1
CCListNum = {}
CCListPosition = {}
for k in range(K):
for j in range(J):
for i in range(I):
if data[i, j, k] == 1 and label_table[i, j, k] == 0:
ret = CCIteration(i, j, k, mask, CCListPosition)
CCListNum[mask] = ret
mask += 1
return CCListNum, CCListPosition
if __name__ == "__main__":
rows = cols = Z_sizes = 5
metrix_sample = np.random.randint(0, 2, rows*cols*Z_sizes) # 生成0,1 ,n*n*n个随机整数
metrix_sample = np.reshape(metrix_sample, ((rows, cols, Z_sizes)))
CCListNum, CCListPosition = Connection_List(metrix_sample)