動画でやってみた。
今回は、OpenCVのチュートリアル「動画を扱う」を参考にした。
テンプレート画像として、"temp100.png" "temp200.png" "temp300.png"を用意。
Logicool c270から読み込んだ画像を処理する。
Raspberry Pi 2 Model Bの処理を考えて、サイズを320x240、フレームレート15を設定。
※注意※
自分の環境では1回目の実行は問題ないが、2回目の実行で"cap = cv2.VideoCapture(0)"が
正常に行われないようなので、"cap.get(cv2.CAP_PROP_FPS) == 0"で判定しながら
繰り返し処理を入れてあります。
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- import cv2
- import numpy as np
- import tkinter
- cap = cv2.VideoCapture(0)
- while(cap.get(cv2.CAP_PROP_FPS) == 0):
- cap.release()
- cap = cv2.VideoCapture(0)
- cap.set(3, 320)
- cap.set(4, 240)
- cap.set(5, 15.0)
- print(cap.get(3))
- print(cap.get(4))
- print(cap.get(5))
- grid_x = (25, 115, 205, 295)
- grid_y = (45, 95, 145, 195)
- fourcc = cv2.VideoWriter_fourcc(*"XVID")
- out = cv2.VideoWriter('output.avi', fourcc, 15.0, (320,240))
- while(True):
- res_100 = "???"
- res_200 = "???"
- res_300 = "???"
- text ="???"
- # Capture frame-by-frame
- ret, frame = cap.read()
- img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
- for temp_num in [100, 200, 300]:
- temp = cv2.imread("temp" + str(temp_num) + ".png", 0)
- result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED)
- min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
- if max_val > 0.8:
- b = 0
- g = 0
- r = 0
- if temp_num == 100:
- b = 255
- if temp_num == 200:
- g = 255
- if temp_num == 300:
- r = 255
- top_left = max_loc
- w, h = temp.shape[::-1]
- bottom_right = (top_left[0] + w, top_left[1] + h)
- res_x = []
- res_y = []
- for i in [0, 1, 2]:
- if top_left[0] >= grid_x[i] and top_left[0] < grid_x[i + 1]:
- if (i + 1 in res_x) == False:
- res_x.append(i + 1)
- for n in [0, 1, 2]:
- if top_left[1] >= grid_y[n] and top_left[1] < grid_y[n + 1]:
- if (n + 1 in res_y) == False:
- res_y.append(n + 1)
- #print("temp" + str(temp_num) + ".png = " + str(res_x[0]) + "-" + str(res_y[0]))
- if temp_num == 100:
- res_100 = str(res_x[0]) + "-" + str(res_y[0])
- if temp_num == 200:
- res_200 = str(res_x[0]) + "-" + str(res_y[0])
- if temp_num == 300:
- res_300 = str(res_x[0]) + "-" + str(res_y[0])
- text = str(res_x[0]) + "-" + str(res_y[0]) + "(" + str("{:.3}".format(max_val)) + ")"
- cv2.rectangle(frame, top_left, bottom_right, (b, g, r), 2)
- cv2.putText(frame, text, (top_left[0] - 5, top_left[1] - 5), cv2.FONT_HERSHEY_PLAIN, 0.8, (b, g, r), 1, cv2.LINE_AA)
- # Display the resulting frame
- # write the frame
- out.write(frame)
- cv2.imshow("frame", frame)
- key = cv2.waitKey(1)&0xff
- if key == ord("s"):
- label = tkinter.Label(None, text = "1 = " + res_100 + "\n2 = " + res_200 + "\n3 = " + res_300, font=("Times", "28"))
- label.pack()
- label.mainloop()
- cv2.imwrite("capture.png", frame)
- #break
- if key == ord("q"):
- break
- # When everything done, release the capture
- cap.release()
- out.release()
- cv2.destroyAllWindows()
上のコードでは、"s"キーが押された時に"tkinter"を使って検出対象の位置情報を表示させているが、
これは一例なので、検出結果から「ここで何かする」って意味になる。
更に別スレッド、別プロセスにすれば動画(画像)の取得を止めること無く「何かする」
が実行出きるので、実際の運用はそう言った使い方になる筈。
0 件のコメント :
コメントを投稿