質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

6497閲覧

OpenCVのfindcontours関数のhierarchyについて

Kohei_KESE

総合スコア41

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/09/17 02:44

編集2018/09/17 04:58

図

上記の画像に対して、RETR_CCOMPにしてfindcontours関数を適用したとき、len(hierarchy)が1になりました。中央の黒の穴は2つ目のhierarchyに該当すると思うのですが、何が問題なのかわからなかったので教えていただきたいです。宜しくお願いします。

Python

1import matplotlib.pyplot as plt 2import cv2 3import numpy as np 4%matplotlib inline 5 6#img = cv2.imread('JIS_kukkiri.png') 7img = cv2.imread('rei8.png') 8img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 9plt.imshow(img2, cmap='gray') 10plt.show() 11 12image, contours, hierarchy=cv2.findContours(img2, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE) 13print("{} contours.".format(len(contours))) 14print("{} hierarchy.".format(len(hierarchy))) 15 16 17

追記: RETR_CCOMPを用いて外側輪郭のみをdrawconterで描画したいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

引数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/17 10:53

編集2018/09/17 11:02
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kohei_KESE

2018/09/18 06:09

回答ありがとうございます。 自分がhierarchyについて勘違いしていたみたいです。 また、可視化コードは非常に便利で分かりやすいです。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問