
こんにちは。
イノベーション本部の田中です。
皆さんは、コロナ前と現在で意識的に変えた事ってありますか?
私はお店での支払いのほとんどを、QR・バーコード決済に変えました。
現金に比べてスムーズに会計ができますし、紙幣や硬貨に直接触れなくてよいので衛生面でも安心ですよね。
キャッシュレス以外にも、コロナ禍の現在は『非接触』をキーワードにしたサービスをよく見かけますね。
というわけで、私もチャレンジです。
今回はPCのマウスを非接触で操作してみたいと思います。
どうやってマウス操作するの?
PC内蔵のカメラでハンドトラッキングをして、その位置情報を活用することでマウス操作をします。
①ハンドトラッキング
ハンドトラッキングには、MediaPipeを使います。
MediaPipeはストリーミングメディアに対して推論を実行するMLパイプラインを構築するためのフレームワークです。
これを利用することで、顔検出や物体検出などを簡単に行うことができます。
以前に「Google MediaPipeでMLアプリ開発の紹介」でもご紹介していますので、こちらも是非ご覧下さい。
②マウス制御
今回はpythonで動かしますので、マウス制御はPyAutoGUIを使用します。
PyAutoGUIは、PythonのRPA開発などでも使われるライブラリです。
1. 環境
- windows10
- python3.7
2. インストール
MediaPipe と PyAutoGUIを使用するために事前準備をします。
※描画にOpenCVを使うため、必要な場合はOpenCVもインストールします。
-
MediaPipe
pip install mediapipe
-
PyAutoGUI
pip install pyautogui
3. 実装
MediaPipeの公式サイトにPython用のサンプルコードがあるので、今回はこちらを利用させて頂きます。
静止画像用とカメラ用の二種類の入力方法がありますが、今回はカメラ用を使います。
import cv2
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
# For webcam input:
cap = cv2.VideoCapture(0)
with mp_hands.Hands(
min_detection_confidence=0.5,
min_tracking_confidence=0.5) as hands:
while cap.isOpened():
success, image = cap.read()
if not success:
print("Ignoring empty camera frame.")
# If loading a video, use 'break' instead of 'continue'.
continue
# Flip the image horizontally for a later selfie-view display, and convert
# the BGR image to RGB.
image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
# To improve performance, optionally mark the image as not writeable to
# pass by reference.
image.flags.writeable = False
results = hands.process(image)
# Draw the hand annotations on the image.
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp_drawing.draw_landmarks(
image, hand_landmarks, mp_hands.HAND_CONNECTIONS)
cv2.imshow('MediaPipe Hands', image)
if cv2.waitKey(5) & 0xFF == 27:
break
cap.release()
上記のサンプルコードに、マウスを制御するためのコードを追記していきます。
今回は以下のような制御を行います。
- 人差し指の座標値を使ってカーソル移動をする
- 人差し指を曲げ、指先が第二関節より下になった時にダブルクリックをする
import pyautogui
import time
image_width, image_height = image.shape[1], image.shape[0]
# 人差し指(指先)の座標値(x,y)をカメラでキャプチャした画像に合わせる
index_finger_tip_x = int(hand_landmarks.landmark[8].x * image_width)
index_finger_tip_y = int(hand_landmarks.landmark[8].y * image_height)
# 人差し指(第二関節)の座標値(x,y)をカメラでキャプチャした画像に合わせる
index_finger_pip_x = int(hand_landmarks.landmark[6].x * image_width)
index_finger_pip_y = int(hand_landmarks.landmark[6].y * image_height)
# 人差し指を曲げたとき、ダブルクリックをする
if index_finger_tip_y > index_finger_pip_y:
pyautogui.doubleClick(index_finger_pip_x,index_finger_pip_y)
time.sleep(1)
# 上記外は、カーソルを移動させる
else:
pyautogui.moveTo(index_finger_pip_x,index_finger_pip_y)
実行結果
しっかりと手を認識してくれてますね!
また、手の動きに対応してカーソル移動やダブルクリックもできていますね。
動かしているPCは、特段にスペックが高い訳ではありませんが、意外とサクサク動きます。
まとめ
MediaPipe と PyAutoGUIを使って簡単なマウス操作を非接触で行いました。
今回は、指先や関節の座標値でクリックの制御を行いましたが、
MediaPipeで取得した座標データを使って、
機械学習を行うことでグー・チョキ・パーなどの様々な手の形を判断することもできるので、今後試していきたいです。