我正在尝试在Python中实现一种称为迟滞的算法。我将尽力解释它。
首先将具有2个阈值( t1 和 t2 ,其中t2> t1)的分段过程应用于填充了0到255之间的整数的3D矩阵。这样就生成了3D矩阵,其中所有
每个值等于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并行性。