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

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

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

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

2回答

2782閲覧

Python OpenCVを使って画像の輪郭を抽出し、条件に合う部分だけ塗りつぶしたい

SuzuAya

総合スコア71

OpenCV

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2019/06/22 10:23

編集2019/06/23 10:15

前提・実現したいこと

こちらの質問を参考に、画像の輪郭を抽出させ、それぞれの面積を表示させるコードを書きました。
そのコードに、「面積が100以上で白色(RGB(230,230,230以上)の場合、指定した色(RGB(16,16,16)で塗りつぶす」というコードを追記したですが、面積が100以上の部分以外も、白色(RGB(230,230,230以上)の部分は全て塗りつぶされてしまいます。https://teratail.com/questions/169498
お手数ですがコードの修正方法についてアドバイスをいただけますととても助かります。
どうぞよろしくお願いいたします。

該当のソースコード

Python

1import glob 2import os 3from PIL import Image 4import cv2 5import matplotlib.pyplot as plt 6from google.colab.patches import cv2_imshow 7 8 9input_dir = 'NORMAL_resize_copy_100_1_0506' # 画像があるディレクトリ 10output_dir = 'NORMAL_resize_pixel_100_1_0506' # 出力するディレクトリ 11 12os.makedirs(output_dir, exist_ok=True) # 保存するディレクトリ 13 14assert(os.path.exists(input_dir)), "directory '{}' not found".format(input_dir) 15for path in glob.glob(input_dir + "/*.jpeg"): 16 img = cv2.imread(path,0) 17 for i, cnt in enumerate(contours): 18 cnt = np.squeeze(cnt, axis=1) # (NumPoints, 1, 2) -> (NumPoints, 2) 19 # 輪郭の点同士を結ぶ線を描画する。 20 ax.add_patch(Polygon(cnt, color='b', fill=None, lw=2)) 21 # 輪郭の点を描画する。 22 ax.plot(cnt[:, 0], cnt[:, 1], 'ro', mew=0, ms=4) 23 # 輪郭の番号を描画する。 24 ax.text(cnt[0][0], cnt[0][1], i, color='orange', size='20') 25 area = cv2.contourArea(cnt) 26 print('contour: {}, area: {}'.format(i, area)) 27 #白色の面積が100以上かつRGBが(230,230,230以上)の場合、RGB(16,16,16)で塗りつぶす 28 if area > 100: 29 img[img >= 230] = 16 30 #plt.show() 31 name, ext = os.path.splitext(os.path.basename(path)) # 拡張子を除いたファイル名 32 save_path = os.path.join(output_dir, '{}_pixel.jpeg'.format(name)) # 保存するパス 33 cv2.imwrite(save_path, img) 34 35fig, ax = plt.subplots(figsize=(6, 6)) 36draw_contours(ax, img, contours) 37plt.show()

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

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

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

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

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

Q71

2019/06/22 12:38

とりあえず、ifブロックの中にprint文を入れるとか。areaが50を超える時のimgをprintしてみるとか。
SuzuAya

2019/06/23 10:16

>Q71様 ありがとうございます。色々試してみて、修正したコードを記載させて頂きました。もしお気づきの点がありましたら、お知らせ頂けますと幸いです。
Q71

2019/06/23 12:43

「if area > 100」のブロックの中の img は、「100以上の範囲のイメージ」ですか?イメージ全体ではないですか?
guest

回答2

0

ベストアンサー

原点に戻りますが、白い部分は、必ずそこにあるのでしょうか。
「必ずそのあたりにある」なら、気にすることはありません。むしろ、そこにないと困ります。
「周りのどこかに現れる(ことがある)」なら、中心だけ切り出してください。「上下だけ」「左右だけ」も同じです。

ちょっと検索してみてください。必ず切り抜いています。「周りを特定の色で塗る」というものはないはずです。なぜでしょうか。以前の問いでも「人工的な色に塗りつぶすより、切り取る方がよい」とアドバイスがありました。それが先人の知恵です。
もちろん、経験に学ぶことを止めるものではありません。その場合でも、「切り抜いて、単一の色に塗ってある別の絵に貼り付ける」という、より簡単な案を示しています。

経験的に、機械でも、人間の感覚的に簡単な特徴を抽出したがると感じています。ですから、「分類Aの画像は右上と左下に白い部分があるものが多い」なら、そのことを特徴として抽出しようとします(そういう学習をすることが多い)。ですから、230~255の範囲の色を、16一色にするのは、余計にまずいことをしようとしています。

投稿2019/06/23 13:00

Q71

総合スコア995

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

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

SuzuAya

2019/06/26 05:55

返信が遅れ申し訳ありません。 ご回答いただき、ありがとうございました。 matlabを使うことも検討しながら、いただいたアドバイスを参考にさせていただき進めていこうと思います。
guest

0

画像を扱う場合、検証を細かくしていく必要があります。
50以下の場合に他の色に書き換えられるかどうか試してみてください

if area > 50 and img == (245, 245, 245): img[:] = fill_color elif area < 50 and img == (245, 245, 245): img[:] = [1, 1, 1] # 別の色

あとは areaの値をprintfなどを使って確認してみると検証がしやすいかと思います!

投稿2019/06/22 19:06

Kazuyuki-T0806

総合スコア326

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

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

SuzuAya

2019/06/23 10:20

ご回答ありがとうございました!アドバイスをもとに検証してみたのですが、うまくいっていないようでしたので、コードを修正しました。面積が100以上の部分以外も、白色(RGB(230,230,230以上)の部分は全て塗りつぶされてしまうのですが、何かお気づきの点がありましたらご指摘頂けますと幸いです。 こちらのリンクも参考にしております。http://pynote.hatenablog.com/entry/opencv-findcontours
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問