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

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

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

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

OpenCV

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

Python

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

Q&A

解決済

3回答

9689閲覧

[opencv]ある一定の面積以下を消すようなノイズの除去方法はありませんか?

oinari03

総合スコア59

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

OpenCV

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

Python

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

0グッド

1クリップ

投稿2020/11/12 01:16

やりたいこと

pythonのopncvを使って以下の画像の外側にある白色の部分を消去したいと考えました。
中央の円以外は黒にしたいです。
イメージ説明

やったこと

medianBlurを使ってある程度ノイズを消したのが上記の写真になっています。
一応ソースコードを貼ります。not_img_mask.pngというのが上記の写真です。

import cv2 import numpy as np #imread img = cv2.imread('sample.jpg') # grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # THRESH_BINARY:THを超えた値を255(白)にする th = 55 th, im_th_otu = cv2.threshold(gray, th, 255,cv2.THRESH_BINARY) print(th) # ノイズ処理:medianBlur ksize = 125 img_mask = cv2.medianBlur(im_th_otu,ksize) not_img_mask = cv2.bitwise_not(img_mask) cv2.imshow('image',not_img_mask) cv2.waitKey(0) cv2.destroyAllWindows()

考え

上記ソースコードのksizeを奇数でかなり増やしてみたりしましたがksize=105~125くらいがきれいな円として残り、それ以上にすると輪郭が崩れてしまいます。
そのためある一定の面積以上(または以下)を消すという処理がないかと、考えましたがその方法がわかりません。

どうか以上のようなことを踏まえてアドバイスをしていただけないでしょうか。
初心者ながらわからないことがあると思いますので、不明の点はお知らせくださいませ。

どうかよろしくお願いします。

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

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

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

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

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

q_sane_q

2020/11/12 08:07

やりたいことの本質がつかめていないのですが、単純に「中央部以外を黒く塗りつぶす」ではいけませんか?
oinari03

2020/11/12 09:55

はい。その通りです。 そのやり方がわからないのです。
guest

回答3

0

「要らない物が画像の外周部に出てくる」とわかっている状況なのであれば,
外周を含む領域を棄却すれば良いだけに思えますが,そういう話ではない?
(簡単には,白色で画像の外周に沿う幅1pixelの矩形を描画してやって,そこを黒色でFloodFillしてやれば,外周に接する不要領域を巻き込んで黒にできる(外周から1画素だけ離れてたやつも巻き込まれるけどね))

あと,(元画像が不明なので何とも言えませんが)
外周部に要らん物が残ったり,2値画像に対してやたらでかいMedianフィルタを使ったりとかすることになった要因というのが
「前段の2値化処理の良く無さ」にあるのであれば,そもそも後段でごちゃごちゃ対処することを考えるよりも,前段処理側を直すという方向の話も有り得るように思えますが,どうなんでしょう?

投稿2020/11/13 02:21

編集2020/11/13 03:20
fana

総合スコア11658

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

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

0

ベストアンサー

求められていることがこれかわかりませんが、ノイズ云々より塗りつぶしに近い操作なのではないかと思います
とりあえず思いつくものを3つ書いてみます。

1つ目は、何も考えず左右上下の端付近を黒い四角形で上塗りすることです。

Python

1height, width = gray.shape #サイズを取得 2 3cv2.rectangle(gray, (0, 0), (100, height), 0, thickness=-1) #左 4cv2.rectangle(gray, (width - 100, 0), (width, height), 0, thickness=-1) #右 5cv2.rectangle(gray, (0, 0), (width, 100), 0, thickness=-1) #上 6cv2.rectangle(gray, (0, height - 100), (width, height), 0, thickness=-1) #下 7# ↑の塗りつぶし幅などは必要に応じて変えてください 8 9cv2.imshow('image', gray) 10cv2.waitKey(0) 11cv2.destroyAllWindows()

2つ目は、黒塗りの画像(データ)を作成してから残したい部分を白くくり抜いて被せることです。

Python

1mask = np.zeros(gray.shape, np.uint8) # 黒塗りのブランク画像的な配列データ 2cv2.rectangle(mask, (300, 100), (1100, 900), 255, thickness=-1) # 残す場所を白い四角でくり抜く。 3# くり抜きサイズの取得は必要に応じて行ってください 4 5dist = cv2.bitwise_and(gray, mask) # 重ねる 6 7 8cv2.imshow('image', dist) 9cv2.waitKey(0) 10cv2.destroyAllWindows()

3つ目は、輪郭の検出をして黒く塗りつぶすところを選択することです。

Python

1mask = np.ones(gray.shape, np.uint8) * 255 # 白塗りのブランク画像的な配列データ 2 3# 輪郭抽出。 各パラメータの意味は調べてください 4this_image, contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 5 6# OpenCV 3.0以降では無い場合はこっち 7#contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 8 9for cnt in contours: 10 if cv2.contourArea(cnt) < 30000: # 塗りつぶし対象を塊の大きさで判別。 11 cv2.drawContours(mask, [cnt], 0, 0, thickness=-1) # 対象の塊を黒く塗りつぶす 12 13dist = cv2.bitwise_and(gray, mask) # 重ねる 14 15cv2.imshow('image', dist) 16cv2.waitKey(0) 17cv2.destroyAllWindows()

投稿2020/11/12 12:43

編集2020/11/12 12:44
q_sane_q

総合スコア610

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

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

0

OpenCVはあまり使ったことがなくてキーワードで検索した程度ですが、
Remove spurious small islands of noise in an image - Python OpenCV
この辺りは参考になりそうでしょうか。

投稿2020/11/12 07:42

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2020/11/13 03:00

外側から走査して、白から始まって黒に変わる領域を見つけるのはいかがでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問