Python实现像素邻域分组:按连通性归类离散像素
按像素连通性分组的实现方案
刚好遇到过类似的图像像素分组需求,结合你提到的思路,这里整理出一个高效且易理解的实现方案:
核心思路
我们用**深度优先搜索(DFS)**来遍历并分组连通像素:
- 先把所有像素坐标转成集合,这样查找和删除操作会非常高效
- 每次从剩余的点里取一个作为起点,然后顺着它的8邻域(上下左右+四个对角线)递归查找所有连通点,把这些点归为一组
- 重复这个过程,直到所有点都被分到对应的组里
完整实现代码
def candidate_neighbors(node): # 生成当前点的8个邻域坐标 return ( (node[0]-1, node[1]-1), (node[0]-1, node[1]), (node[0]-1, node[1]+1), (node[0], node[1]-1), (node[0], node[1]+1), (node[0]+1, node[1]-1), (node[0]+1, node[1]), (node[0]+1, node[1]+1) ) def neighboring_groups(nodes): remain = set(nodes) # 集合存储剩余未分组点,提升操作效率 while len(remain) > 0: visit = [remain.pop()] # 取出一个起点,开始遍历连通区域 group = [] while len(visit) > 0: node = visit.pop() group.append(node) # 检查当前点的所有邻域 for nb in candidate_neighbors(node): if nb in remain: remain.remove(nb) visit.append(nb) yield tuple(group) # 用生成器返回分组,节省内存 # 测试示例 nodes = ((22, 23), (22, 24), (21, 23), (1, 5), (2, 6), (21, 22), (3, 5)) print(tuple(neighboring_groups(nodes)))
代码细节说明
candidate_neighbors:专门生成当前像素的8个邻点,确保不会漏掉任何连通的像素(如果只需要4连通,去掉对角线的四个坐标即可)neighboring_groups:- 用集合而非列表存储剩余点,因为集合的成员检查和删除操作是O(1),比列表的O(n)高效太多,处理大量像素时差异明显
- 用循环模拟DFS(避免递归深度过大导致栈溢出),每次处理一个连通区域,把所有连通点收集到一个组里
- 生成器的方式返回分组,不需要一次性把所有组都存在内存里,适合处理超大图像的像素列表
执行效果
运行测试代码后,会得到你期望的分组结果:
(((1, 5), (2, 6), (3, 5)), ((22, 24), (22, 23), (21, 22), (21, 23)))
同一连通区块的像素都被归到了同一个子结构里,内部顺序不影响后续使用。
内容的提问来源于stack exchange,提问作者Heath24
相关产品推荐
相关产品推荐

