Python填洪

2024-04-24 14:33:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我对洪水填充算法完全不熟悉。我在维基百科上查过了。但并没有变得那么聪明。我试着在以下情况下使用它。我有一个矩阵:

matrix = [["a", "a", "b", "a", "a", "b"],
          ["a", "b", "b", "a", "b", "b"],
          ["b", "a", "b", "a", "a", "b"],
          ["b", "a", "b", "a", "b", "b"],
          ["a", "a", "b", "a", "a", "a"],
          ["a", "b", "b", "a", "a", "b"]]

然后让用户从矩阵中决定一个点。如果给定点是"b",则不执行任何操作。在另一种情况下,如果给定的点是"a",我想在洪水填充算法的帮助下,将该给定点和"a"的所有周围或连接点更改为“c”。

例如,假设用户决定矩阵[0][0]。新矩阵是:

matrix = [["c", "c", "b", "a", "a", "b"],
          ["c", "b", "b", "a", "b", "b"],
          ["b", "a", "b", "a", "a", "b"],
          ["b", "a", "b", "a", "b", "b"],
          ["a", "a", "b", "a", "a", "a"],
          ["a", "b", "b", "a", "a", "b"]]

让我们继续这个例子,假设用户决定了新的点,矩阵[3][1]。然后我们会:

matrix = [["c", "c", "b", "a", "a", "b"],
          ["c", "b", "b", "a", "b", "b"],
          ["b", "c", "b", "a", "a", "b"],
          ["b", "c", "b", "a", "b", "b"],
          ["c", "c", "b", "a", "a", "a"],
          ["c", "b", "b", "a", "a", "b"]]

我正在尝试构建一个函数floodfill(matrix,x,y),到目前为止我已经想到了:

def floodfill(matrix, x, y):
    if matrix[y][x] == "b":
        return matrix
    elif matrix[y][x] == ".":
        stack = []

你有办法引导我继续吗?试图寻找洪水填充在这里的例子,但他们似乎不适合我的情况。至少我不能将这些示例应用到我的代码中。洪水泛滥似乎不是这里的热门话题。。。但是,再次感谢您的帮助!


Tags: 函数用户算法returnifstackdef情况
2条回答

好吧,洪水泛滥的想法是:

  1. 检查点是否符合标准。
  2. 如果是,则将其更改为“c”(在您的情况下),并对周围的所有单元格调用flood fill。

类似python的伪代码:

def floodfill(matrix, x, y):
    #"hidden" stop clause - not reinvoking for "c" or "b", only for "a".
    if matrix[x][y] == "a":  
        matrix[x][y] = "c" 
        #recursively invoke flood fill on all surrounding cells:
        if x > 0:
            floodfill(matrix,x-1,y)
        if x < len(matrix[y]) - 1:
            floodfill(matrix,x+1,y)
        if y > 0:
            floodfill(matrix,x,y-1)
        if y < len(matrix) - 1:
            floodfill(matrix,x,y+1)

在Python的图像处理库中有几种洪水填充算法的实现。我知道有两个:skimage.segmentation.floodOpenCV's floodFill。前者是用Python实现的,使用的算法与上面amit的答案类似。后者在C++中使用概念上类似的算法,但没有递归,使它更有效(大约25x大图像)。

要使用OpenCV的floodFill,需要将矩阵转换为一个np.整数数组,具体操作如下:

import numpy as np
import cv2

matrix_np = np.asarray(matrix)
numeric_matrix = np.where(matrix_np=="a", 255, 0).astype(np.uint8)
mask = np.zeros(np.asarray(numeric_matrix.shape)+2, dtype=np.uint8)
start_pt = (y,x)
if matrix_np[start_pt]:
  cv2.floodFill(numeric_matrix, mask, start_pt, 255, flags=4)
mask = mask[1:-1, 1:-1]
matrix_np[mask==1] = "c"
matrix = matrix_np.tolist()

使用上面给出的示例矩阵和x,y=(0,0),这将把matrix设置为

[['c', 'c', 'b', 'a', 'a', 'b'],
 ['c', 'b', 'b', 'a', 'b', 'b'],
 ['b', 'a', 'b', 'a', 'a', 'b'],
 ['b', 'a', 'b', 'a', 'b', 'b'],
 ['a', 'a', 'b', 'a', 'a', 'a'],
 ['a', 'b', 'b', 'a', 'a', 'b']]

相关问题 更多 >