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

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

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

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

Python

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

Q&A

解決済

1回答

6558閲覧

OpenCVでマスク画像を作成する方法

fia

総合スコア57

OpenCV

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

Python

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

0グッド

0クリップ

投稿2020/02/01 07:01

編集2020/02/01 14:52

発生している問題

マスク画像を作成したいが、マスクしたい物体の一部が以下のように画像からがはみ出ているときに塗りつぶしできない。
最終的には黒線も入るようなマスク画像を作成したい。

左から入力画像、現状の状態、最終的な理想
イメージ説明  イメージ説明  イメージ説明

該当のソースコード

python

1import cv2 2import numpy as np 3 4def edges_img(img): 5 canny_img = cv2.Canny(image=img, threshold1=127, threshold2=127) 6 7 kernel = np.ones((3, 3), np.uint8) 8 dilation = cv2.dilate(canny_img,kernel,iterations = 1) 9 #dilation=~dilation 10 11 contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_NONE) 12 mask = np.zeros((img.shape[0],img.shape[1])) 13 14 for i in range(len(contours)): 15 if hierarchy[0][i][3] == -1: 16 cv2.drawContours(mask, contours, i, 255, -1) 17 18 return mask 19 20if __name__=='__main__': 21 img=cv2.imread('sample.png') 22 img=edges_img(img) 23 cv2.imwrite("hoge.png",img)

試したこと

contoursに底辺の座標を追加
塗りつぶしの仕方を変更

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

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

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

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

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

tiitoi

2020/02/01 13:54

質問のコードで、左の赤い矩形が含まれる画像が sample.png で、実行すると、右側の画像が現状では生成されるということでしょうか? 理想としてる出力画像はどのようなものなのでしょうか。
fia

2020/02/01 14:49

右の状態は手動で作った最終理想の形です。 現状を実行したものを加筆しておきます。
guest

回答1

0

ベストアンサー

例えば、一番下端に1ピクセルの白い線を入れといて、輪郭抽出した際に1つの長方形の輪郭として取れるようにするとかどうでしょうか。

python

1import cv2 2import numpy as np 3 4 5def edges_img(img): 6 canny_img = cv2.Canny(img, threshold1=127, threshold2=127) 7 8 kernel = np.ones((3, 3), np.uint8) 9 dilation = cv2.dilate(canny_img, kernel, iterations=1) 10 11 # 追加した部分 12 dilation[-1:, ...] = 255 13 14 contours, hierarchy = cv2.findContours( 15 dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE 16 ) 17 mask = np.zeros((img.shape[0], img.shape[1])) 18 19 for i in range(len(contours)): 20 if hierarchy[0][i][3] == -1: 21 cv2.drawContours(mask, contours, i, 255, -1) 22 23 return mask 24 25 26if __name__ == "__main__": 27 img = cv2.imread("sample.png") 28 img = edges_img(img) 29 cv2.imwrite("hoge.png", img)

イメージ説明

出力結果

投稿2020/02/01 15:04

tiitoi

総合スコア21956

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

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

fia

2020/02/01 15:57

回答ありがとうございます。 1つ質問なのですが、今回は、はみだしている部分が下だとわかっていたので、下に線を入れて対応できますが、4辺のどこがはみ出てるかわからないとき、4辺とも対応させるにはどうすればよいのでしょうか。 今回の方法で4辺とも白線を入れると画像全体を抽出して画像が真っ白になってしまいました。
tiitoi

2020/02/01 16:07 編集

Canny でエッジ抽出して輪郭抽出でマスク画像を作成する部分は必須でしょうか? 白以外の部分がマスク対象ならば、輪郭抽出しないで、cv2.inRange() など使って、色ベースで白以外の部分 (長方形の部分) をマスクしてしまえばいいような気がします。
fia

2020/02/02 00:38

今回のはサンプルなのでいいですが、実際は写真などに対応しようと思っていました。
fia

2020/02/02 00:40

1辺を白くしてマスクすることを複数回行って画像をマージすることで対応できることに気づきました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問