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

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

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

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

Python

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

Q&A

解決済

2回答

6594閲覧

findContoursの戻り値contoursのリストを見ると2重カッコになっている

MeloStark

総合スコア1

OpenCV

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

Python

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

0グッド

0クリップ

投稿2021/06/09 00:14

前提・実現したいこと

python 3.7.3
opencv 3.4.2
numpy 1.19.5

python、opencvを用いて下記のテスト画像から輪郭の座標リストを出力しようとしています。
出力されたリストが、二重かっこになっているため、この後の処理で不都合が生じています。

イメージ説明

発生している問題・エラーメッセージ

python

1import cv2 2import numpy as np 3 4print(cv2.__version__) 5# -> 3.4.2 6print(np.__version__) 7# -> 1.19.5 8 9img = cv2.imread('test.png',0) 10__, th = cv2.threshold(img,127,255,0) 11__, cnt, hierarchy = cv2.findContours(th,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) 12 13print(len(cnt)) 14print('cnt: ', cnt)

output

1cnt [[[0 0]] 2 3 [[0 1]] 4 5 [[0 2]] 6 7 ... 8 9 [[3 0]] 10 11 [[2 0]] 12 13 [[1 0]]]

試したこと

二値化は固定のまま、findContoursの第2引数(ex:RETR_EXTERNAL)のみ他の変数に変更しましたが、変化はありませんでした。
opencvの日本語公式リファレンスを参照、また、OpenCVでcv2.findContoursするとリストが二重かっこになるを参照しましたが、解決しませんでした。

私の至らない部分が多々あるのかもしれません。
何か、お気づきの点やアドバイスなどありましたら、コメント頂けますと幸いです。

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

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

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

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

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

guest

回答2

0

ベストアンサー

~~OpenCVでcv2.findContoursするとリストが二重かっこになるに書かれている通り、一つの輪郭は平面上の点である一次元配列の列である二次元配列となり、輪郭が複数あるので、三次元のndarryで返す仕様です。
~~
contours は輪郭のリストです。各輪郭は、(点の数, 1, 2) の ndarrayという仕様でした。
これを関数のオプションで変更して、二次元にしたいというのは無理だと思います。

~~この後の処理で不都合が生じています。

とのことですので、不都合が生じないように「この後の処理」の方を変更するのでしょう。~~

私のところのcv2はバージョン4.5.1です。findContoursの仕様が変更されていて、戻り値は2個となっています。

あとで、結果画像を表示するつもりです。

輪郭線は、結果として得られる点をつないだものです。
今回の画像では以下の結果が得られました。
イメージ説明
頂点の数は79個でした。

投稿2021/06/09 00:34

編集2021/06/09 02:59
ppaul

総合スコア24666

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

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

MeloStark

2021/06/09 01:36

ご回答ありがとうございます。 リストのかっこの意味はよく理解することができました。 今回の結果を見ると、輪郭が点として抽出されているために[ [ [0,0] ], [ [0,1] ]...] のようになっていると理解しました。 つまり、二値化を行った後の画像が何かおかしいために、輪郭が点として抽出されていると考えられるという事でよろしいでしょうか。
MeloStark

2021/06/09 11:53

遅くなりましたが、追加検討ありがとうございます! まだこちらのプログラム確認できていないのですが、検証していただいた結果と照らし合わせてみます! ありがとうございます!
guest

0

点の座標(x, y)を表すのに一重カッコ、輪郭は複数の点で構成されるのでさらにもう一重カッコ、そして輪郭のリストなのでもう一重カッコで計三重カッコになります。
cnt[0]とすると最初の輪郭に関する情報が得られます。
全ての輪郭について処理したい場合はforループを使えばいいです。

投稿2021/06/09 00:29

fukatani

総合スコア626

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

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

MeloStark

2021/06/09 01:31

ご回答ありがとうございます。リストのかっこの意味が理解できたように思います。 上記の例でいうと、まず、[0,0]という点があり、 それ以外には「輪郭に当たる点がない」ため、[ [0,0] ]となっている。 そういった輪郭(点)が複数存在しているため、[ [ [0,0] ] , [ [0,1] ], ... ]と続いている という理解でよろしいでしょうか? 普通(チュートリアルなど)では、[ [ [0,0], [0,1], ... ], [ [1,0], [1,1], ... ], ...]の様な形になっていて、cnt[0] = [ [0,0], [0,1], ...] の要素が取り出されるため、輪郭を表す点の集合であることが分かります。 つまり、今回私が行ったfindContoursの変数に入れた画像が都合が悪く、輪郭をうまく抽出できていないという事になるという事でしょうか。 試しに、他の画像で輪郭抽出しているプログラムをそのまま動作させてみます。
fukatani

2021/06/09 01:44

輪郭抽出するには画像を二値化(真っ白と真っ黒のみの状態)する必要があるのでそれができてないのかもしれません。 cnt[0]の中に普通は複数の点列が含まれるはずです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問