Python递归DFS处理掩码图像时递归深度超限问题求助
解决递归DFS处理大像素簇时的递归深度超限问题
递归DFS遇到大像素簇时触发maximum recursion depth exceeded,核心原因是Python的递归调用栈存在长度限制——哪怕你调高sys.setrecursionlimit,当簇的最长连通路径超过该限制时仍会报错,而且递归本身在处理大规模数据时效率也远不如迭代方式。
直接把递归DFS改成迭代式DFS或者BFS就能彻底解决这个问题,下面是修改后的完整代码,同时修复了原代码里的几个隐性bug:
import numpy as np from PIL import Image def split_mask_into_x_biggest_clusters(input_mask, x): # 生成8连通的邻居坐标,修复原代码里的重复邻居问题 def generate_neighbours(point): neighbours = [ (-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1) ] for dx, dy in neighbours: yield (point[0] + dx, point[1] + dy) # 迭代式DFS替代递归,彻底避免栈溢出 def find_regions(start_point, points_set): region = [] stack = [start_point] points_set.remove(start_point) region.append(start_point) while stack: current = stack.pop() for neighbor in generate_neighbours(current): if neighbor in points_set: points_set.remove(neighbor) region.append(neighbor) stack.append(neighbor) return region # 提取白色像素点集合,修正原代码的坐标顺序错误 data = np.array(input_mask)[:, :, 0] y_coords, x_coords = np.where(data == 255) # numpy where返回(行,列)对应图像(y,x) points = set((x, y) for x, y in zip(x_coords, y_coords)) regions = [] while points: start = next(iter(points)) region = find_regions(start, points) regions.append(region) # 按簇大小降序排序 sorted_regions = sorted(enumerate(regions), key=lambda item: len(item[1]), reverse=True) # 生成前x个最大簇的掩码,优化赋值效率+取消硬编码尺寸 masks = [] mask_h, mask_w = data.shape for idx, region in sorted_regions[:x]: mask = np.zeros((mask_h, mask_w, 3), dtype=np.uint8) # 用numpy批量索引替代循环,大幅提升速度 xs, ys = zip(*region) mask[ys, xs] = [255, 255, 255] masks.append(Image.fromarray(mask)) return masks
关键修改说明:
- 替换递归为迭代DFS:用栈模拟递归调用过程,完全规避了Python递归深度限制,无论多大的像素簇都能稳定处理。
- 修复坐标顺序错误:原代码混淆了numpy数组的
(行,列)与图像的(x,y)坐标对应关系,导致生成的掩码位置偏移,现已修正。 - 优化邻居列表:删除原代码中重复的邻居坐标,改用标准8连通邻居定义。
- 提升掩码生成效率:用numpy批量索引赋值替代循环逐个修改像素,处理大簇时速度提升明显。
- 适配任意输入尺寸:取消原代码硬编码的512x512尺寸,自动匹配输入掩码的大小。
现在不需要再依赖sys.setrecursionlimit,直接删除相关代码即可正常运行。
内容的提问来源于stack exchange,提问作者Ben123
相关产品推荐
相关产品推荐

