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

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

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

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

Python

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

Q&A

解決済

1回答

4630閲覧

PythonとOpenCVを用いて物体を白色で抽出したい

takekoko

総合スコア13

OpenCV

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

Python

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

2グッド

4クリップ

投稿2017/10/07 17:30

###前提・実現したいこと
最近、趣味でプログラミングを始めました。
PythonとOpenCVを用いて何も映っていない背景と物体を映した前景で差分をとり、物体だけを白色で抽出したいです。

###発生している問題
しかし、背景や物体の色によって物体の色が黒になってしまうことがあり、うまくいきません。

Python

1diff = cv2.absdiff(pic,gray)

この命令でうまく物体だけを抽出できるかなと思い、使ってみたのですが、2値化するときの閾値によって色が変化してしまい、黒くなってしまうことが多々あります。

<<画像>>
これは手のみで、色のおかげか白で抽出できています。
イメージ説明

服の白い部分の一部と影になっている部分が黒くなっているのがわかると思います。
イメージ説明

###該当のソースコード

Python

1#coding:utf-8 2 3import os.path 4import numpy as np 5import cv2 6 7cam = cv2.VideoCapture(0) 8cam.set(3, 960) #width 9cam.set(4, 540) #heigh 10cam.set(5,25) #fps 11 12while True: 13 ret2,image = cam.read() 14 15 Key = cv2.waitKey(10) 16 if Key == 32: #space 17 cv2.imwrite("base.png",image) 18 19 if os.path.isfile("base.png"): 20 pic = cv2.imread('base.png',cv2.IMREAD_GRAYSCALE) #読み込み 21 gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY) #現在 22 diff = cv2.absdiff(pic,gray) #比較画像生成 23 diff2 = cv2.medianBlur(diff,ksize=3) #ブラー 24 twoc = cv2.threshold(diff2,40,255,cv2.THRESH_BINARY)[1] #2値化 25 cv2.imshow("base",diff) 26 cv2.imshow("image",diff2) 27 cv2.imshow("result",twoc) 28 else: 29 cv2.imwrite("base.png",image) 30 31 if Key == 27: #Esc 32 break 33cv2.destroyAllWindows() 34

###質問項目
0. この方法、考え方で目的は達成できるのか

  1. もっと効率的だったり、簡単な方法はないのか
  2. その他、このプログラムにおかしいところはないか

最近始めたばかりで、おかしなところが多くあると思いますが、回答よろしくお願い致します。

###補足情報(言語/FW/ツール等のバージョンなど)
Raspberry Pi 3
Python 2.7.9
OpenCV 3.1.0

LouiS0616👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

この回答は、この方針のまま改良する手段に関するものです。


隙間を埋めたいというなら、典型的にはクロージング処理を行うのかと思います。
OpenCV-Pythonチュートリアル >> OpenCVを使った画像処理 >> モルフォロジー変換

クロージング処理はオープニング処理の逆の処理を指し, 膨張の後に収縮 をする処理です.前景領域中の小さな(黒い)穴を埋めるのに役立ちます

カーネルサイズなどを実際の状況に応じて調整する必要があります。
適当にコードを書いてみました。

Python

1#coding:utf-8 2 3import os.path 4import numpy as np 5import cv2 6 7cam = cv2.VideoCapture(0) 8cam.set(cv2.CAP_PROP_FPS, 25) 9 10BASE_FILE_NAME = 'base.png' 11if os.path.isfile(BASE_FILE_NAME): 12 base = cv2.imread(BASE_FILE_NAME, cv2.IMREAD_GRAYSCALE) 13else: 14 _, base = cam.read() 15 cv2.imwrite(BASE_FILE_NAME, base) 16 17while True: 18 _, image = cam.read() 19 20 key = cv2.waitKey(10) 21 if key == 27: #Esc 22 break 23 if key == 32: #space 24 cv2.imwrite(BASE_FILE_NAME, image) 25 base = cv2.imread(BASE_FILE_NAME, cv2.IMREAD_GRAYSCALE) 26 27 gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 28 result = cv2.absdiff(base, gray) 29 result = cv2.medianBlur(result, ksize=3) 30 _, result = cv2.threshold(result, *(40, 255), cv2.THRESH_BINARY) 31 32 # ノイズ除去(closing) 33 result = cv2.morphologyEx(result, cv2.MORPH_CLOSE, kernel=np.ones((5,5),np.uint8)) 34 35 cv2.imshow('base', base) 36 cv2.imshow('image', image) 37 cv2.imshow('result', result) 38 39cv2.destroyAllWindows()

書き換えた点は、次の通りです。
・言うまでもないですが、ノイズ除去の処理を追加しています。
・base.pngの読み取りを一回に抑えています。毎回所在を確認するのは無駄です。
・(おそらく)camのフレームサイズを指定する必要はありません。
・その他、適当に変数の数を減らす工夫をしています。

実はPython2.7の環境にOpenCVを落とすのが面倒で、Python3.xでコーディングしています。
おそらく2.7でも問題なく動作すると思いますが、もし違ったらごめんなさいね。

あと、改善できるとしたら二値化の手法でしょう。
いろいろな手法が使えますので、試してみてください。
こちらが参考になるかと思います。Python版ではないですが、基本は一緒です。

投稿2017/10/07 21:30

LouiS0616

総合スコア35658

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

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

takekoko

2017/10/09 14:18

返信遅れて申し訳ないです。 プログラムとご指摘ありがとうございます。 これを参考にいろいろ試してみたいと思います。 申し訳ないのですが、いろいろな考え方を参考にしたいので、もう少しベストアンサーを先延ばしにさせてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問