質問: cv2.FONT_HERSHEY_SIMPLEX cv2.putText(frame,text,(20,400),font,1,(0,255,0),2,cv2.LINE_AA) #フレームに表示 cv2.imshow('frame',frame) cv2.waitKey(1) # 撮影用オブジェクトとウィンドウの解放 movie.release() ``` ### 質問 Q1:上のコードでまず、疑問に感じていることを教えてください (1)20行目の“detframe”で画像処理を行う範囲を指定しているのでしょうか? (2)21行目は、画像処理を行う範囲を見やすいように赤枠で囲んでいるだけでしょうか? Q2:本題ですが、私は入力角に応じて画像処理範囲を変えたいです。そこで、下の画像(写真)のように、範囲を変えることは可能でしょうか?(ついでに、処理をしている範囲を赤枠で囲みたいのですが、これも可能でしょうか?) ![1](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/c68535baa2cc84d5cb4c87e2fe55198c.jpeg) 各座標の求め方は 入力角=φとすると、 θA1=∠COA1 θB1=∠COB1 任意の点A=(r1cos(90+θA1+φ)+a, r1sin(90+θA1+φ)+b)) 任意の点B=(r2sin(90-θB1+φ)+a, r2sin(90-θB1+φ)+b)) で求まると思います。 Q3:Q2が可能だった場合、フレームからはみ出した画像処理範囲はどうなるのでしょうか?きちんと、フレームの中のみ処理を行ってくれるのでしょうか? それとも、エラーになってしまうのでしょうか? ![2](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/ca7935ed65ad867c0e7d36ecc91320db.jpeg)
回答: > > Q1:上のコードでまず、疑問に感じていることを教えてください > > (1)20行目の“detframe”で画像処理を行う範囲を指定しているのでしょうか? > > > 画像を対象の領域で切り抜いて、その後の処理を行うことで実質的に範囲指定と同じことをやっています。 > > (2)21行目は、画像処理を行う範囲を見やすいように赤枠で囲んでいるだけでしょうか? > > > はい > > Q2:本題ですが、私は入力角に応じて画像処理範囲を変えたいです。そこで、下の画像(写真)のように、範囲を変えることは可能でしょうか?(ついでに、処理をしている範囲を赤枠で囲みたいのですが、これも可能でしょうか?) > > (ついでに、処理をしている範囲を赤枠で囲みたいのですが、これも可能でしょうか?) > > > 背景差分のアルゴリズム自体には範囲を指定する機能はありません。 対象範囲が長方形であれば、画像を切り抜けばいいですが、質問の場合はそうはいかないので、対象範囲以外を黒で塗りつぶしてからその後の処理に移行すればいいと思います。 以下はイメージです。 質問に記載されている式で画像のうち、検出したい範囲のピクセルとそれ以外のピクセルを判定できると思いますので、それで検出対象以外の画素を塗りつぶします。 !イメージ説明 > > Q3:Q2が可能だった場合、フレームからはみ出した画像処理範囲はどうなるのでしょうか?きちんと、フレームの中のみ処理を行ってくれるのでしょうか? > > > ピクセル単位で検出対象の画素とそうでない画素を定義するので、Q3の問題は発生しません。 サンプル 参考 OpenCV - 背景差分で物体を検出する方法について - pystyle 今回は簡単な例として、検出範囲を円とした場合のサンプルを記載しました。 「検出対象の画素が255、そうでない画素は0のマスクを作成する」部分は質問者さんのほうで適宜変更してください。 ``` import cv2 import numpy as np cap = cv2.VideoCapture("vtest.avi") width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) wait_secs = int(1000 / cap.get(cv2.CAP_PROP_FPS)) model = cv2.bgsegm.createBackgroundSubtractorMOG() # 検出対象の画素が255、そうでない画素は0の roi を定義する。 roi = np.zeros((height, width), dtype=np.uint8) cx, cy = width // 2, height // 2 cv2.circle(roi, (cx, cy), 200, 255, -1) while True: ret, frame = cap.read() if not ret: break # roi に基づき、検出対象外の画素を黒にする masked_frame = frame.copy() masked_frameroi == 0] = 0 # 背景差分結果 fgmask = model.apply(masked_frame) # 検出領域をわかりやすいように可視化 cv2.circle(frame, (cx, cy), 200, (0, 0, 255), 2) cv2.circle(masked_frame, (cx, cy), 200, (0, 0, 255), 2) cv2.circle(fgmask, (cx, cy), 200, 255, 2) cv2.imshow("fgmask", frame) cv2.imshow("frame", fgmask) cv2.imshow("masked_frame", masked_frame) cv2.waitKey(wait_secs) cap.release() cv2.destroyAllWindows() ``` ![イメージ説明