前回、MeidaPipeライブラリを使って手を検出するプログラムを紹介しました。今日はCVZoneというライブラリを使って、Webカメラに映った手を検出して、指の数をかぞえるプログラムを作成してみました。CVZoneはOpenCVとMediaPipeを利用したコンピュータビジョンのライブラリです。MediaPipeを使いやすくしたラッパーのようなものでしょうか。詳しくは以下のサイトを見てください。

https://github.com/cvzone/cvzone

また今日紹介するプログラムはこちらのビデオを参考にしています。

それでは早速、内容に入りましょう。

【準備】ライブラリのインストールと使用する画像

まず準備として、以下のコマンドでcvzoneとmediapipeをインストールします(OpenCVも必要です)。

今回使うイメージファイルとプログラムのソースコードはこちらからダウンロードできます。

Pythonのスクリプトと「images」という名前のフォルダに「0.png」「1.png」「2.png」「3.png」「4.png」「5.png」という6つの画像が入っています。それぞれの画像には以下のように指の絵が描かれています。

今回のプログラムでは、検出された指の数に対応する上のイラストが画面に表示されるようになっています。

プログラムの内容(全体)

ソースコードの全体はこちら。

実行した様子はこちら。

プログラムの説明

内容について簡単に説明していきます。

3行目で CVZone の手を検出するモジュールをインポートしています。

Webカメラのオブジェクトを作成します(5行目)。環境に合わせて引数の数字を変更してください。
またカメラの画像サイズは幅640 px、高さ480 pxにしています(6,7行目)。

「images」フォルダにある手のイラスト画像を読みだす処理です。os.listdir 関数を使ってフォルダ内の全てのファイルをリストにして、それぞれを読み込んでいます。読み込んだイラスト画像は配列 finger_imgs に格納しています。

手を検出するモデルを作成します(19行目)。detectionCon パラメータは0~1.0の値を取り、高い値にすると検出の精度が高くなります(デフォルト値は0.5)。

Webカメラから画像を読み込み、モデルで手の検出をしています(22,23行目)。

もし手が見つかった場合、fingersUp 関数でどの指が伸びているかを調べます(26行目)。fingersUp 関数の戻り値(変数 fingers)は5つの要素をもつリストで、1もしくは0の値が入っています。1だと指が上がっていて、0だと下がっています。たとえば以下のようにすると、どの指が上がっているかを判定できます。

今回はどの指が上がっているかの判定はせず、fingers.count(1) で上がっている指の数をかぞえて(27行目)、その数に対応するイラスト画像を表示するようにしています(28~31行目)。また指の数を数値としても表示しています(32行目)。

キーボードの Q ボタンを押すとプログラムを終了するようにしています(35~37行目)。

さいごに

実行した様子のビデオでも分かる通り、かなり高い精度で指を検出できているのではないでしょうか。このプログラムをちょっと変えてやれば、じゃんけんゲームなんかが作れそうですね。

今日の内容が誰かのお役に立てば幸いです。