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

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

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

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

Python

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

Q&A

解決済

1回答

12093閲覧

opencvにおける複数の領域検出から画像ファイルにして保存する方法

ring_2380

総合スコア11

OpenCV

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

Python

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

0グッド

0クリップ

投稿2019/05/19 07:55

前提・実現したいこと

以下の画像に対して、大きい枠ではなく小さい枠の抽出を行い、抽出できたものを別画像ファイルにして保存したいです。イメージ説明
具体例としては、以下のように赤い部分を検出して別画像ファイルにして保存するということです。イメージ説明

現状のプログラムだと、線を全部赤色にしてしまいます。そこで、小さい枠のみ検出し、別の画像として保存できる方法を教えてください。よろしくお願いいたします。

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

小さい枠の画像のみを検出する方法
複数の画像を切り出して別画像ファイルにして保存する方法

該当のソースコード

#モジュールインポート import cv2 as cv2 import numpy as np import matplotlib.pyplot as plt # ファイルを読み込み img = cv2.imread('img/img.jpg', cv2.IMREAD_COLOR) # グレースケール化 img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) #二値化 img_niti = cv2.adaptiveThreshold(img_gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,9) #二値化した画像を保存 cv2.imwrite('img/niti/img_niti.jpg', img_niti) #輪郭検知 img_1, contours, hierarchy = cv2.findContours(img_niti, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) img = cv2.drawContours(img, contours, -1, (0,0,255), 3) #結果を保存 cv2.imwrite('img/result/niti_result.jpg', img)

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

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

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

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

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

can110

2019/05/19 10:56

コメント部分が太字になってそのまま実行できないのでソースはコードブロック```で囲んでください。 また、欲しい矩形についてですが、例で示された赤色の線が太くて分からないので教えてください。 3つの黒い太線で囲まれた領域のうち、欲しいのは内側ですか、それとも太線も含めた外側ですか? (内側なら比較的簡単に求めることができます)
ring_2380

2019/05/19 11:38

ありがとうございます。内側で今のところ判別を考えています。
ring_2380

2019/05/19 11:53

切り出す方法ですが、for文の中にあるidxを基準にして、順番に保存していくような感じになるのでしょうか? img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),1)とある下に同じインデントで作成しているのですが、img_1= img[y:y+h, x:x+w]だと一枚しか保存されないので、img_1の部分をimg_ str(idx)にすればよいのでしょうか?
can110

2019/05/19 11:56

同じインデントでよいです。その際は都度img_1を別ファイル名で保存する必要があります。 なお、こちらは質問への修正依頼欄なので回答へコメント投稿するほうがよいです。
guest

回答1

0

ベストアンサー

findContoursの戻り値hierarchyには領域の包括関係(ツリー構造)に関する情報が含まれているので、これより欲しい領域群を特定、取得します。

  • 太線の内側であれば最内接
  • 太線の外側であれば最内接の親

となります。あとはboundingRectで各領域に外接する矩形を求めればよいかと思います。

なお、当方環境ではOpenCVのバージョンが4系なので以下コードではfindContours関数の戻り値が質問の提示コードとは異なっています。ご自身の環境で試される場合は修正ください。
参考:OpenCV - findContours() による輪郭抽出

また

複数の画像を切り出して別画像ファイルにして保存する方法

については、すでに切り出すべき矩形座標は判明しておりそれほど難しくないと思いますのでご自身で実装してみてください。
参考:【Python/OpenCV】窓画像の作成(切り取り)

Python

1 2import cv2 as cv2 # 4.1.0 3import numpy as np 4 5img_src = cv2.imread('inp.png', cv2.IMREAD_COLOR) 6img = cv2.cvtColor(img_src, cv2.COLOR_RGB2GRAY) 7img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11,9) 8contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # OpenCV4での戻り値! 9 10img = img_src 11 12# 欲しい領域のインデックス群を取得 13idxs = [i for i,h in enumerate(hierarchy[0]) if h[2] == -1] # 太線の内側=最内接(=子供がない) 14#idxs = [h[3] for i,h in enumerate(hierarchy[0]) if h[2] == -1]# 太線の外側=最内接(=子供がない)の親 15for idx in idxs: 16 cnt = contours[idx] 17 x,y,w,h = cv2.boundingRect(cnt) # 外接矩形を得る(回転は考慮しない) 18 img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),1) 19 20cv2.imwrite('out.png', img)

内側
イメージ説明
外側
イメージ説明

投稿2019/05/19 11:22

編集2019/05/19 11:44
can110

総合スコア38266

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

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

ring_2380

2019/05/19 12:00

申し訳ございません。初めて使うもので仕様の理解が追い付いていませんでした。 その場合の実装としては、 img_str(idx)= img[y:y+h, x:x+w] となるのでしょうか? それとも 別の変数から保存していくのでしょうか?
can110

2019/05/19 12:13

別変数img_out = img[y:y+h, x:x+w]なりでよいかと思います。
ring_2380

2019/05/19 12:21

何度も質問失礼します。 cv2.imwriteで保存する際に画像ファイル名を決めるときにおなじもので保存されるのですが、この場合はどうしたらよいでしょうか?
can110

2019/05/19 13:02

基礎的な事柄なのでヒントだけ。 idx変数を使うと被らないファイル名の文字列を作ることができそうです。
ring_2380

2019/05/20 10:18

ありがとうございます。 無事に実装できました。 また何かありましたらお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問