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

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

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

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

Python

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

Q&A

解決済

1回答

5913閲覧

回転を考慮した外接矩形の描画とノイズ除去

Taka11

総合スコア14

OpenCV

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

Python

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

0グッド

0クリップ

投稿2018/10/20 07:24

編集2018/10/20 07:27

実現したいこと

・回転を考慮した外接矩形の描画
・ノイズ除去

実現したいことは上記の2つです。
よろしくお願い致します。

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

ノイズ除去ができない。
元画像
イメージ説明

処理後画像
イメージ説明

該当のソースコード

python

1import cv2 2import numpy as np 3 4#画像の読み込み 5img =cv2.imread('C:/Users/ito/Anaconda3/envs/Sample/pic/testimg/IMG_0644.jpg') 6 7#画像のリサイズ 8img = cv2.resize(img, (1008,756)) 9 10#画像の大きさを取得 11height, width, channels = img.shape 12image_size = height * width 13 14#グレースケール化 15gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 16 17#二値化処理 18ret, dst = cv2.threshold(gray, 168, 255, cv2.THRESH_BINARY) 19 20#輪郭抽出 21imgEdge, contours, hierarchy = cv2.findContours(dst, 1, 2) 22 23#外接矩形 24recs = np.zeros((len(contours), 8), dtype=np.float32) 25for i, cnt in enumerate(contours): 26 rect = cv2.minAreaRect(cnt) 27 box = cv2.boxPoints(rect) 28 for j, _box in enumerate(box): 29 box[j] = list(map(int, _box)) 30 rec = np.array((box[0][0], box[0][1], box[1][0], box[1][1], 31 box[2][0], box[2][1], box[3][0], box[3][1])) 32 recs[i] = rec 33 34 area = cv2.contourArea(cnt) 35 #小さな輪郭の場合は除く 36 if area <800: 37 continue 38 39 #画像全体の占める領域は除外する 40 if image_size * 0.99 < area: 41 continue 42 43 44 rst = cv2.drawContours(img, contours, -1, (0,0,255), 2) 45print(recs) 46cv2.imwrite('C:/Users/ito/Anaconda3/envs/Sample/pic/result/minAR0644_168.jpg', rst)

開発環境

windows7 professional
python3.6.5
opencv3.3.1

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

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

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

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

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

guest

回答1

0

ベストアンサー

cv2.findContours() は値が0の画素を背景、値が0より大きい画素を前景と解釈するので、以下のように丸の部分が白になるように cv2.threshold() で2値化を行ったほうがよいです。

イメージ説明

輪郭抽出後は、面積を元に小さい輪郭を削除しましょう。
リストから指定した条件の要素のみ取り出す場合、filter() 関数が便利です。

contours = list(filter(lambda cnt: 1000 < cv2.contourArea(cnt), contours))

サンプルコード

python

1import cv2 2import numpy as np 3 4# 画像の読み込み 5img = cv2.imread('test.jpg') 6 7# リサイズ 8img = cv2.resize(img, dsize=None, fx=0.2, fy=0.2) 9 10# グレースケールに変換 11gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 12 13# 二値化 14ret, binary = cv2.threshold(gray, 166, 255, cv2.THRESH_BINARY_INV) 15 16#輪郭抽出 17_, contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 18 19# 面積が小さい輪郭削除 20area = img.shape[0] * img.shape[1] 21contours = list(filter(lambda cnt: 1000 < cv2.contourArea(cnt), contours)) 22 23# 外接矩形に変換 24# drawContours() に渡す輪郭は int 型である必要があるため、astype(int) でキャストすること。 25rects = [cv2.boxPoints(cv2.minAreaRect(cnt)).astype(int) for cnt in contours] 26 27# 外接矩形を描画 28cv2.drawContours(img, rects, -1, (0, 255, 0), 2) 29 30# 画像を保存 31cv2.imwrite('result.jpg', img)

イメージ説明

投稿2018/10/20 08:05

tiitoi

総合スコア21956

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

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

Taka11

2018/10/20 08:33

ご回答いただきありがとうございます! 2値化処理も正していただきありがたいです。 追加でひとつ質問なのですが、rectsに入っている矩形の情報は矩形の各頂点の座標という認識でよいのでしょうか?
tiitoi

2018/10/20 08:41

その認識であっています。print(rests) で確認してみてください。
Taka11

2018/10/20 08:46

ありがとうございます。確認しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問