OpenCV 入門 (8) - Webカメラの映像表示しながらキー状態を取得
OpenCVでWebカメラの映像表示しながらキー状態を取得する方法が、予想外にややこしかったのでメモ。
前回
1. Webカメラの映像表示しながらキー状態を取得
waitKey()だとキーリピートで途切れ途切れになるため、キー状態の取得はpygletを利用しました。ポイントは、Numpy配列の画像をテクスチャに変換して画面に表示する部分になります。
import pyglet
import cv2
import numpy as np
from pyglet.gl import *
from pyglet.window import key
# 定数
CAMERA_ID = 0 # カメラID
IMAGE_SIZE = 256 # 画像サイズ
# カメラの生成
camera = cv2.VideoCapture(CAMERA_ID)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, IMAGE_SIZE)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, IMAGE_SIZE)
# ウィンドウの生成
win = pyglet.window.Window(width=IMAGE_SIZE, height=IMAGE_SIZE, vsync=False)
key_handler = pyglet.window.key.KeyStateHandler()
win.push_handlers(key_handler)
win_img = None
# キー状態の取得
def get_key_state():
global key_handler
key_state = set()
win.dispatch_events()
for key_code, pressed in key_handler.items():
if pressed:
key_state.add(key_code)
return key_state
# 描画時の処理
@win.event
def on_draw():
win.clear()
if win_img != None:
win_img.blit(0,0)
# イメージのクロップ
def clop_image(image):
h, w, c = image.shape
size = int(min(w, h))
dx = int((w-size)/2)
dy = int((h-size)/2)
return image[dy : dy+size, dx : dx+size]
# 定期処理
def on_tick(dt):
global win_img
# イメージの更新
retval, img = camera.read()
img = clop_image(img)
img = np.flipud(img) # Webカメラの向きの調整
sy, sx, number_of_channels = img.shape
number_of_bytes = sy * sx * number_of_channels
img = img.ravel()
image_texture = (GLubyte * number_of_bytes)(*img.astype('uint8'))
win_img = pyglet.image.ImageData(sx, sy, 'BGR', image_texture,pitch=sx*number_of_channels)
# キー状態の取得
print('key_state:', get_key_state())
# アプリの開始
pyglet.app.platform_event_loop.start()
pyglet.clock.schedule_interval(on_tick, 0.1)
pyglet.app.run()
次回
この記事が気に入ったらサポートをしてみませんか?