引数hierarchy の構造
抽出された輪郭 contours が N 個であった場合、hierarchy は (1, N, 4) の numpy 配列で、輪郭 contours[i] の階層情報は hierarchy[0, i] に格納されています。4つの要素は、[次のインデックス、前のインデックス、最初の子のインデックス、親のインデックス] で、次、前、子、親が存在しない場合は -1 が入っています。
サンプルコード
抽出された輪郭点及び階層構造を可視化するコードを貼ります。
python
1import matplotlib.pyplot as plt
2import numpy as np
3import cv2
4import networkx as nx
5
6def draw_contours(axes, img, contours):
7 from matplotlib.patches import Polygon
8 axes.imshow(img)
9 axes.axis('off')
10 for i, cnt in enumerate(contours):
11 cnt = np.squeeze(cnt)
12 # 点同士を結ぶ線を描画する。
13 axes.add_patch(Polygon(cnt, fill=None, lw=2., color='b'))
14 # 点を描画する。
15 axes.plot(cnt[:, 0], cnt[:, 1],
16 marker='o', ms=4., mfc='red', mew=0., lw=0.)
17 # 輪郭の番号を描画する。
18 axes.text(cnt[0][0], cnt[0][1], i, color='orange', size='20')
19
20
21# 画像を読み込む。
22img = cv2.imread('test.png')
23
24fig, axes = plt.subplots(figsize=(6, 6))
25
26# 輪郭を抽出する。
27gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
28_, contours, hierarchy = cv2.findContours(gray, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
29
30# 抽出した輪郭を表示する。
31axes.set_title('cv2.RETR_EXTERNAL')
32draw_contours(axes, img, contours)
33plt.show()
34
35# 階層構造をグラフで作成する。
36graph = nx.DiGraph()
37for my_no, info in enumerate(hierarchy[0]):
38 next_no, prev_no, first_child_no, parent_no = info
39 if parent_no == -1:
40 graph.add_edge('root', my_no)
41 else:
42 graph.add_edge(parent_no, my_no)
43 print('contour {} (next: {}, previous: {}, first_child: {}, parent: {})'.format(my_no, *info))
44
45pos = nx.spring_layout(graph)
46nx.draw_networkx_nodes(graph, pos, node_size=400, node_color='#3ddb94')
47nx.draw_networkx_labels(graph, pos)
48nx.draw_networkx_edges(graph, pos)
49plt.axis('off')
50plt.show()
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/09/18 06:09