三维矩阵连通域


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)
 

你可能感兴趣的:(python,算法)