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

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

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

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

Python 3.x

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

Python

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

Q&A

解決済

3回答

3064閲覧

Python3+opencv3で矩形内のリアルタイム検知がしたいです

n-kk

総合スコア12

OpenCV

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

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2018/08/09 06:05

お世話になっております。

今回は、python3 + opencvにて以下のようなことをやりたいと考えているのですが
どのようにすれば実現できるのか分からない為、ご質問させて下さい。

(やりたいこと)
1.リアルタイムで動画をUSBカメラ撮影し、動画をグレースケール化したい。
2.1.のグレー動画のカメラの画角内に検知枠(四角形)を発生させたい
3.検知枠の中の「画素」に変化があったらカメラシャッターを切りたい
4.もし可能であれば検知枠をマウスでクリックしている間は好きな形状に可変させてみたい←可能ならです
※動画のシチュエーションはたくさんあり、それぞれ異なる環境です。
ex)ゴミ捨て場等で、誰かがゴミにいたずらした時に検知枠をゴミのある場所に設置しておき、その中に人や
動物が入れば階調に変化があったとみなし、写真撮影

OpenCVを使えば出来そうだと思っておりますが
OpenCVを殆ど使ったことがない為、どういった具合で処理をかけばいいのかさっぱり分かりません。
こんな関数あるよとか、こんなライブラリ使えば直ぐできるよとか、こんな参考HPあるよといった
ありましたら、ご教授頂ければと思います。

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

イメージ説明

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

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

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

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

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

guest

回答3

0

1と2に関してはコードで

tachikomaさんが先に回答されているのでこれも加味して、具体的なコードを掲示

python

1import cv2 2import numpy as np 3 4# VideoCaptureのインスタンスを作成する。 5cap = cv2.VideoCapture(0) 6 7while True: 8 # VideoCaptureから1フレーム読み込む 9 ret, frame = cap.read() 10 11 # 画像加工処理 12 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 13 img = cv2.rectangle(gray, (250,30), (450,200), (0,255,0), 5) 14 15 16 # 加工済の画像を表示する 17 cv2.imshow('gray Frame', img) 18 19 # キー入力を1ms待って、k が27(ESC)だったらBreakする 20 key = cv2.waitKey(1) 21 if key == 27: #escを押したら終了 22 break 23 if key == 13: #Enterを押したらシャッターを切る 24 filename = "shot.jpg" 25 cv2.imwrite(filename, img) 26 27# escを押した時の終了処理 28cap.release() 29cv2.destroyAllWindows()

3.検知枠の中の「画素」に変化があったらカメラシャッターを切りたい

画素の変化といってもいろいろあるので処理の方法は答えきれません。そのあたりの要望によって検出精度を高める工夫もできます。また、ノイズや光の当たり方などによって画素の値は常に変化していると思ったほうがいいと思います。そうなってしまうと常にシャッターを切ってしまうような動作になります。

可能であれば検知枠をマウスでクリックしている間は好きな形状に可変させたい

これに関しては要望と違うかもしれませんが似たようなコードを公開しているサイトがあったので載せておきます
https://qiita.com/otakoma/items/04e525ac74b7191dffe6

投稿2018/08/09 08:30

Ryupe

総合スコア426

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

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

n-kk

2018/08/10 00:25

Ryupe様。早急なご回答をいただきありがとうございます。 また、お返事が遅れてしまい申し訳御座いません。 3.ですが、環境によって誤検知が発生してしまうとのアドバイス、誠にありがとうございます。 度々、恐縮なのですが、一般的にはどういった形で閾値を定めているのでしょうか。 tachikoma様が申していたフレーム差分でヒストグラム(輝度?)を作成し定めると言った手法でしょうか。
Ryupe

2018/08/10 01:01

誤認知については極端なことを言っていました。 前フレームとの値の差分を取るのが一般的だと思います。 ヒストグラムとはグラフの種類の一つだと思ってください。手法とは少し意味合いが違うと思います。 今回の感じですと、グレースケールの画像を扱うことになりそうなので画素に含まれる値は0〜255範囲の「輝度」1パラメータのみです。枠内の輝度の平均値を前フレームと比較してX分変わった時にシャッターを切るといった条件分岐を与えてやると良いかもしれません。 「動体検出」が今回の目的に近いキーワードです。
n-kk

2018/08/10 02:31

ご回答ありがとうございます。 アドバイスに基き検索致しました所、下記のソースコードがありました。 #フレーム間差分の二値化 def detector(cap, detect_rect): detect = False prev_frame = None crt_frame = None while True: start = time.time() # get frame #frame = get_frame(cap) crt_frame = get_gray_frame(cap) if prev_frame is not None: # diff frame diff_frame = cv2.absdiff(crt_frame, prev_frame) # binary frame diff_b_frame = cv2.threshold(diff_frame, 50, 255, cv2.THRESH_BINARY)[1] cv2.imshow('processing preview', diff_b_frame) detect, ratio = check_detect(diff_b_frame, detect_rect) if detect: # destroy window cv2.destroyAllWindows() return crt_frame # display frame cv2.imshow('camera preview', crt_frame) if cv2.waitKey(250) == 27: # wait 250 msec / finish by ESC key break prev_frame = crt_frame elapsed_time = time.time() - start sys.stdout.write('elapsed_time {:3.3f} [s] \r'.format(1 / elapsed_time)) sys.stdout.flush() # destroy window cv2.destroyAllWindows() return None #二値変化率の認識 def check_detect(b_frame, detect_rect): detect_rect.modify() window = b_frame[detect_rect.y : detect_rect.y + detect_rect.h, detect_rect.x : detect_rect.x + detect_rect.w] #check change ratio of binary values ratio = np.mean(window) / 255 if ratio > 0.2: return True, ratio return False, ratio こちらで試してみます。
guest

0

ベストアンサー

1から3については回答が既に付いているので、4だけ。

Python

1import cv2 2 3from util.callback import * 4from util.capture import * 5from util.window import * 6 7 8class Watcher: 9 WINDOW_NAME = 'img' 10 11 def __init__(self): 12 self._cap = cv2.VideoCapture(0) 13 14 self._window = cv2.namedWindow(self.WINDOW_NAME) 15 set_mouse_callbacks( 16 self.WINDOW_NAME, 17 mouse_clicked=self.mouse_clicked, 18 mouse_dragged=self.mouse_dragged, 19 ) 20 21 self._rect = [ 22 0, 0, *check_window_size(self._cap) 23 ] 24 25 def run(self): 26 draw_color_rectangle = make_draw_color_rectangle(color=(0, 0, 255), thickness=3) 27 28 while True: 29 self._img = read_gray_frame(self._cap) 30 31 cv2.imshow( 32 self.WINDOW_NAME, 33 draw_color_rectangle(self._img, *self._rect) 34 ) 35 36 k = cv2.waitKey(30) 37 if k == ord('q'): 38 break 39 40 cv2.destroyWindow(self.WINDOW_NAME) 41 self._cap.release() 42 43 @property 44 def boxed_img(self): 45 x1, y1, x2, y2 = self._rect 46 47 if x1 == x2: 48 return None 49 if y1 == y2: 50 return None 51 52 x1, y1, x2, y2 = rearrange_rect(x1, y1, x2, y2) 53 return self._img[y1:y2, x1:x2] 54 55 def mouse_clicked(self, x, y, param): 56 self._rect[:2] = x, y 57 self._rect[2:] = x, y 58 59 def mouse_dragged(self, x, y, param): 60 self._rect[2:] = x, y 61 62 63if __name__ == '__main__': 64 Watcher().run()

util/callback.py

Python

1import cv2 2 3 4def _stub(*args, **kwargs): 5 pass 6 7def set_mouse_callbacks( 8 window_name, param=None, *, 9 mouse_clicked=_stub, mouse_dragged=_stub, mouse_released=_stub): 10 11 def mouse_callback(event, x, y, flags, param): 12 if event == cv2.EVENT_LBUTTONDOWN: 13 mouse_clicked(x, y, param) 14 return 15 if event == cv2.EVENT_LBUTTONUP: 16 mouse_released(x, y, param) 17 return 18 19 if flags == cv2.EVENT_FLAG_LBUTTON: 20 mouse_dragged(x, y, param) 21 return 22 23 cv2.setMouseCallback(window_name, mouse_callback, param)

util/capture.py

Python

1import cv2 2 3 4def check_window_size(capture): 5 ret, img = capture.read() 6 assert ret 7 8 height, width, depth = img.shape 9 return width, height 10 11def read_gray_frame(capture): 12 ret, img = capture.read() 13 assert ret 14 15 return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

util/window.py

Python

1import cv2 2 3 4def rearrange_rect(x1, y1, x2, y2): 5 x1, x2 = sorted([x1, x2]) 6 y1, y2 = sorted([y1, y2]) 7 8 return x1, y1, x2, y2 9 10def make_draw_color_rectangle(*, color, thickness=1): 11 def draw_color_rectangle(img, x1, y1, x2, y2): 12 if img.ndim == 2: 13 img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) 14 15 cv2.rectangle( 16 img, (x1, y1), (x2, y2), color, thickness 17 ) 18 return img 19 20 return draw_color_rectangle

色々いじくって試してみると良いです。

投稿2018/08/09 09:16

編集2018/08/09 09:17
LouiS0616

総合スコア35658

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

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

0

1 - cvtColor
USBカメラのキャプチャの例 Getting Started with Videos

カラー変換【Python/OpenCV】グレースケール変換(cv2.cvtColor)

2 - rectangle

Python

1img = cv2.rectangle(img, (250,30), (450,200), (0,255,0), 5)

3 - 簡単な方法だと、直前のフレームとの差分のヒストグラム作って閾値処理する、とか

4 - インタラクティブな仕組みを作るのは少しだけハードルが高いのでパス。

投稿2018/08/09 07:10

tachikoma

総合スコア3601

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問