Python遍历灰度图像中的连接组件

Rav*_*310 6 python numpy image python-imaging-library connected-components

我有一个灰度图像,其值介于 0(黑色)和白色(255)之间。我有一个target与灰度图像大小相同的矩阵。我需要从灰度图像中的一个随机像素开始,一次遍历图像一个像素(以深度优先搜索方式),将其值复制到target矩阵中的相应位置。我显然只需要对非白色像素执行此操作。我怎样才能做到这一点?本以为可以得到灰度图像的连通分量,将每个像素点一个一个地遍历,但是找不到合适的连通分量的实现。有任何想法吗?

例如,如果我的灰度图像是:

[[255,255,255,255,255,255,255]
[255,255, 0 ,10 ,255,255, 1 ]
[255,30 ,255,255,50 ,255, 9 ]
[51 ,20 ,255,255, 9 ,255,240]
[255,255,80 ,50 ,170,255, 20]
[255,255,255,255,255,255, 0 ]
[255,255,255,255,255,255, 69]]
Run Code Online (Sandbox Code Playgroud)

然后可能的遍历[0,10,50,9,170,50,80,20,51,30]后跟[1,9,240,20,0,69]to give [0,10,50,9,170,50,80,20,51,30,1,9,240,20,0,69]。不同对象之间的顺序无关紧要。

其他可能的遍历是: [1,9,240,20,0,69,0,10,50,9,170,50,80,20,51,30][1,9,240,20,0,69,0,10,50,9,170,50,80,20,30,51][1,9,240,20,0,69,10,50,9,170,50,80,20,30,0,51]

等等。

Myk*_*tko 15

您可以使用networkx

from itertools import product, repeat
import numpy as np
import networkx as nx

arr = np.array(
[[255,255,255,255,255,255,255],
 [255,255, 0 ,10 ,255,255, 1 ],
 [255,30 ,255,255,50 ,255, 9 ],
 [51 ,20 ,255,255, 9 ,255,240],
 [255,255,80 ,50 ,170,255, 20],
 [255,255,255,255,255,255, 0 ],
 [255,255,255,255,255,255, 69]])

# generate edges
shift = list(product(*repeat([-1, 0, 1], 2)))
x_max, y_max = arr.shape
edges = []

for x, y in np.ndindex(arr.shape):
    for x_delta, y_delta in shift:
        x_neighb = x + x_delta
        y_neighb = y + y_delta
        if (0 <= x_neighb < x_max) and (0 <= y_neighb < y_max):
            edge = (x, y), (x_neighb, y_neighb)
            edges.append(edge)

# build graph
G = nx.from_edgelist(edges)

# draw graph
pos = {(x, y): (y, x_max-x) for x, y in G.nodes()}
nx.draw(G, with_labels=True, pos=pos, node_color='coral', node_size=1000)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

# draw graph with numbers
labels = dict(np.ndenumerate(arr))
node_color = ['coral' if labels[n] == 255 else 'lightgrey' for n in G.nodes()]
nx.draw(G, with_labels=True, pos=pos, labels=labels, node_color=node_color, node_size=1000)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

# build subgraph
select = np.argwhere(arr < 255)
G1 = G.subgraph(map(tuple, select))

# draw subgraph
pos = {(x, y): (y, x_max-x) for x, y in G1.nodes()}
labels1 = {n:labels[n] for n in G1.nodes()}
nx.draw(G1, with_labels=True, pos=pos, labels=labels1, node_color='lightgrey', node_size=1000)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

# find connected components and DFS trees
for i in nx.connected_components(G1):
    source = next(iter(i))
    idx = nx.dfs_tree(G1, source=source)
    print(arr[tuple(np.array(idx).T)])
Run Code Online (Sandbox Code Playgroud)

输出:

[  0  10  50   9  50  80  20  30  51 170]
[  9   1 240  20   0  69]
Run Code Online (Sandbox Code Playgroud)

  • 看起来非常优雅! (3认同)