【问题标题】:Connected componenet labeling using BFS使用 BFS 的连接组件标记
【发布时间】:2014-11-19 00:03:32
【问题描述】:

我正在使用 BFS 算法解决连接组件标记算法。原始图像 im 将被标记为 out image。

当 blob 很小时,此代码有效。但是,当我将起点更改为具有大 blob 时,代码要么达到最大递归深度,要么出现分段错误。如何避免这些问题?

import cv2
import numpy as np
from collections import deque
import sys
import copy

sys.setrecursionlimit(10000000)

def bfs(queue, im, out, label):
    if len(queue) > 0:
        pixel = queue.pop()
        print pixel
        out[pixel] = label

        M, N = im.shape
        for n in neighbors(pixel, M, N):
            if out[n] == 0 and im[n] == im[pixel]:
                queue.append(n)
        out = bfs(queue, im, out, label)
    return out

def neighbors(pixel, M, N):
    if pixel[0] == M - 1 and pixel[1] == N - 1:
        return [(M-2, N-1), (M-1, N-2)]
    elif pixel == (0,0):
        return [(0,1),(1,0)]
    elif pixel == (M - 1, 0):
        return [(M-1, 1), (M-2, 0)]
    elif pixel == (0, N - 1):
        return [(1, N-1), (0, N-2)]
    elif pixel[0] == 0:
        return [(1,pixel[1]), (0, pixel[1]-1), (0 ,pixel[1] + 1)]
    elif pixel[1] == 0:
        return [(pixel[0], 1), (pixel[0]-1, 0), (pixel[0] + 1, 0)]
    elif pixel[0] == M - 1:
        return [(pixel[0], pixel[1] + 1), (pixel[0] - 1, pixel[1]), (pixel[0], pixel[1] - 1)]
    elif pixel[1] == N - 1:
        return [(pixel[0] + 1, pixel[1]), (pixel[0], pixel[1] - 1), (pixel[0] - 1, pixel[1])]
    else: 
        return [(pixel[0] + 1, pixel[1]), (pixel[0], pixel[1] + 1),\
                (pixel[0] - 1, pixel[1]), (pixel[0], pixel[1] - 1)]


im = cv2.imread('33039.png', cv2.IMREAD_GRAYSCALE)
out = np.zeros(im.shape)

queue = deque()
queue.append((10,10))
out = bfs(queue, im, out, 1)

【问题讨论】:

    标签: python algorithm python-2.7 computer-vision graph-theory


    【解决方案1】:

    BFS 可以很容易地以迭代方式实现。以下是 CPP 中的示例:

    void
    bfs(const vector< vector<int> > &g)
    {
            // visit self, then neighbors, store neighbors using stack.
            vector<bool> visited(g.size(), false);
            vector<int> s;
            Queue Q;
            Q.enqueue(6);
            while (Q.size() > 0)
            {
                    int t = Q.dequeue();
                    if (!visited[t])
                    {
                            cout << "visit node: " << t << endl;
                            visited[t] = true;
                            for (int i = 0; i < g[t].size(); ++i)
                            {
                                    if (!visited[g[t][i]])
                                    {
                                            Q.enqueue(g[t][i]);
                                    }
                            }
                    }
            }        
    }
    

    【讨论】:

      【解决方案2】:

      就python解决方案而言,我经常使用这种非递归解决方案:

      def bfs(graph,start):
          # Breadth-first search to find pixels connected
          # graph is array with some pixels true and others false
          # start is x, y
          if not graph[start[0]][start[1]]:
              return
          visited = []
          w, h = len(graph)-1, len(graph[0])-1
          queue = [start]
          while queue:
              x, y = queue.pop(0)
              neighbors = []
              if x<w:
                  neighbors.append((x+1,y))
              if x>0:
                  neighbors.append((x-1,y))
              if y<h:
                  neighbors.append((x,y+1))
              if y>0:
                  neighbors.append((x,y-1))   
              for n in neighbors:
                  if n not in visited and graph[n[0]][n[1]]:
                      visited.append(n)
                      queue.append(n)
          return visited
      

      我为过去的项目编写的这个版本将二维 python 数组作为输入,并探索为真或一的相邻像素。为了在上下文中看到它,我为this 写了它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-31
        • 1970-01-01
        • 2021-10-11
        • 1970-01-01
        • 2010-11-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多