在3D矩阵中并行查找邻居

时间:2020-08-28 21:32:39

标签: python matrix multidimensional-array python-multiprocessing

我正在尝试在Python中实现一种称为迟滞的算法。我将尽力解释它。

首先将具有2个阈值( t1 t2 ,其中t2> t1)的分段过程应用于填充了0到255之间的整数的3D矩阵。这样就生成了3D矩阵,其中所有 t2值都更改为255。

每个值等于0表示黑色,255 白色和所有其他值灰色,第二步可以通过以下伪指令来解释-代码:

do while grey voxels remain:
   for any single grey voxel having non-grey neighbors:
      if it has more white neighbors than black neighbors:
         paint it in white (i.e. 255)
      else:
         paint it in black (i.e. 0)

简而言之,我们可以通过遍历每个灰色体素(是的,可以通过仅检查那些具有白色/黑色邻居的灰色体素)并检查其邻域(26个连接)来改善细分后的数据。如果有很多白人邻居,则体素将变为白色;如果有很多黑人邻居,则体素将变为黑色;否则,它将保持灰色。我们经历了这个循环,直到无法进行进一步的更改为止(此时,我们进入下一步,通过硬币翻转做出决定)。

这是此算法针对701x900x719矩阵(x,y,z)的顺序实现,并且任意地t1 = 90,t2 = 150:

def get_neighbors(index):
    for relative_index in product((-1, 0, 1), repeat=3):
        if not all(relative_element == 0 for relative_element in relative_index):  # check for (0,0,0)
            yield tuple(element + relative_element for element, relative_element in zip(index, relative_index))

def hysteresis(arr, t1=90, t2=150):
    aux_arr = arr.copy()  # a copy of the matrix to which we'll write
    grey_voxels, current_grey_voxels = 0, 0  # variables to hold grey voxel indices
    grey_amount, current_grey_amount = 0, -1  # counters to reference the amount of grey voxels to process

    while True:
        if grey_amount != current_grey_amount:
            grey_voxels = current_grey_voxels if current_grey_amount != -1 \
                else np.nonzero((aux_arr >= t1) & (aux_arr <= t2))  # grey voxel indices
            grey_amount = len(grey_voxels[0])  # amount of voxels to process
            for voxel in zip(*grey_voxels):
                black_counter = white_counter = grey_counter = number_neighbors = 0
                neighbors = get_neighbors(voxel)
                for neighbor in neighbors:
                    z, x, y = neighbor
                    if not any(element == -1 for element in neighbor) \
                            and z < 719 \
                            and x < 701 \
                            and y < 900:
                        aux = arr[neighbor]
                        number_neighbors += 1
                        if aux == 255:
                            white_counter += 1
                        elif aux == 0:
                            black_counter += 1
                        else:
                            grey_counter += 1
                if grey_counter < ceil(number_neighbors / 2):
                    if white_counter > black_counter:
                        aux_arr[voxel] = 255
                    elif black_counter > white_counter:
                        aux_arr[voxel] = 0
            current_grey_voxels = np.nonzero((aux_arr >= t1) & (aux_arr <= t2))
            current_grey_amount = len(current_grey_voxels[0])
        else:
            break

    return aux_arr

如预期的那样,此实现花费的时间太长,无法使用。我一直在尝试并行化该算法,但没有成功。

本质上,问题是“如何并行查找3D矩阵的邻域?”。

第二,如果有一种更好的方法来进行这种计算,即Python与Numba,PyCUDA,CuPy或其他工具的多处理与GPU并行性。

0 个答案:

没有答案
相关问题