我正在使用BFS算法解决连通分量标记算法。原始图像im将被标记为图像。
当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)
答案 0 :(得分: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]);
}
}
}
}
}
答案 1 :(得分:0)
就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
我为过去的项目编写的这个版本使用2-d python数组作为输入,并探索True或One的相邻像素。为了在上下文中看到它,我为this编写了它。