2020年4月23日木曜日

姿勢推定を行うPoseNetをWindowsなどのPCで実行する

1. はじめに

YOLOバージョン3をWindowsなどのPCで実行する」 では、Windows などの PC に Anaconda というディープラーニング実行用の環境をインストールし、物体検出を行う YOLO の動作を確認して頂きました。

Anaconda のインストールにはそれなりに手間がかかりましたので、YOLOだけの実行では物足りないと感じる方もいるかもしれません。そこで、本ページでは追加の演習として、姿勢推定を行う PoseNet を Anaconda 上で実行する方法を紹介します。余力のある方は試してみてください。

姿勢推定とは、下図のように映像から人間の目、鼻、関節などの位置を推定する技術のことを言います。なお、通常では、姿勢推定は人間が映った映像を対象とします。下図ではプライバシーに配慮して絵に対する認識結果の表示としましたのでご了承ください。


2. TensorFlow Lite 用の環境 tflite の作成

姿勢推定を行う PoseNet は、公式ページブラウザ上でのデモが紹介されているほか、TensorFlow Lite というツール上で実行可能です。

TensorFlow Liteとは、モバイルデバイス向けにディープラーニングによる推論の機能を提供するものです。主に Android、iOS、Raspberry Pi など用に(正確には ARM プロセッサ用に)最適化されています。それをここでは Windows などの PCで実行しようというわけです。ただし、TensorFlow Lite は現在 PC 向けには最適化されておりませんので、動作は高速ではありません。その点はご了承ください(参考)。この問題は TensorFlow Lite の将来のバージョンで改善される可能性はあるかもしれません。

YOLOバージョン3をWindowsなどのPCで実行する」では、TensorFlow バージョン2用に Anaconda 上で tf2 という環境を作成して演習を実行しました。ここでは新たに TensorFlow Lite 用に tflite という環境を作成し、そこで TensorFlow Lite をインストールしてから演習を実行するという流れになります。

YOLOバージョン3をWindowsなどのPCで実行する」の演習を済ませ、Anaconda のインストールが済んだ状態で以下の解説に進んでください。

それでは、TensorFlow Lite のインストールを行いましょう。まず、お使いの PC に合わせて、下記のファイルをダウンロードします。
以下では、Windows 10 を用いて解説しますのでご了承ください。

macOS に対するヒント
macOS 10.14 をお使いの方は、古いバージョンである tflite_runtime-2.1.0.post1-cp37-cp37m-macosx_10_14_x86_64.whl を試すという手もあります(ただし、動作検証していません)

上でダウンロードしたファイルは、通常は「ダウンロード」フォルダなどに保存されます。 このファイルを、Windows のエクスプローラを用いて「C:\Users\(ユーザー名)」というフォルダに移動しましょう。

「C:\Users\(ユーザー名)」とは、Anaconda Prompt において下図の赤線部に示されている内容です。図ではユーザー名は「neura」ですが、もちろん皆さんの環境では異なります。皆さんも Anaconda Prompt を起動して「C:\Users\(ユーザー名)」が自分の環境ではどうなっているか把握しましょう。


では、Windowsでは「C:\Users\(ユーザー名)」にどうやってたどり着けるでしょうか。それを示したのが下図です。まず、エクスプローラーで左の階層構造から「PC」を選択して展開し、その中にある「C:」という文字を含む項目をクリックします。図では「Windows (C:)」と書かれていますが、「Windows」という文字の部分は人により異なるので「C:」を手掛かりにするのです。これを「Cドライブ」と言います。


上図(左)のように「ユーザー」というフォルダが見つかるはずですので、ダブルクリックして開きます。

すると、上図(右)のように先ほど確認したユーザー名のフォルダが見つかります(図では「neura」)。それをさらにダブルクリックして開きましょう。

その結果、下図のように「ダウンロード」、「デスクトップ」、「ドキュメント」…などがあるフォルダにたどり着きます。 ここが、「C:\Users\(ユーザー名)」という場所になります。

ここに、先ほどダウンロードした tflite_runtime-2.....whl という長い名前のファイルを移動してください。下図のようになります。


さて、以上でダウンロードして場所を移動したファイルをインストールする作業に入りましょう。 まず、スタートメニューの「Anaconda3 (64-bit)」から「Anaconda Prompt (anaconda3)」をクリックして起動し、以下の4つの命令を一つずつ順に実行していきます。

これは、「YOLOバージョン3をWindowsなどのPCで実行する」で実行した内容と似ていますが、今回は TensorFlow Lite 用の環境 tflite を新たに作成している点が異なります。
YOLOバージョン3をWindowsなどのPCで実行する」で学んだ「命令のコピーと、Anaconda Prompt への貼り付け」を思い出し、命令を一つずつ確実に実行してください。
conda create -n tflite python=3.8

conda activate tflite

conda install py-opencv pip spyder console_shortcut toml

pip install tflite_runtime-2.5.0-cp38-cp38-win_amd64.whl
1つ目と3つ目の実行時には「Proceed ([y]/n)?」と確認を求められますが、「キーボードで y を入力して Enter」または「キーボードでEnter」により処理が進みます。
2つ目の命令を実行すると、プロンプトの先頭が「(tflite) C:\Users\neura>」のように「(tflite)」に変化しますので確認しましょう。tflite という環境に入ったことを意味します。
4つ目の命令が正しく成功すると「Successfully installed tflite_runtime-2.5.0」と表示されます。

macOS に対するヒント
1つ目の命令は、下記のように python 3.7 を指定しないと
後のインストールが恐らくうまくいかないでしょう。
conda create -n tflite python=3.7
また、4つ目の命令は
pip install (ダウンロ―ドしたファイルの名前)
のように適切に読み替える必要があります。


すべて終わったら Anaconda の環境 tflite への TensorFlow Lite のインストールが完了しました。Anaconda Prompt は閉じて構いません。 さらに、先ほど「C:\Users\(ユーザー名)」という場所にエクスプローラーで移動した tflite_runtime-2.....whl というファイルは削除して構いません。

3. 姿勢推定を行う PoseNet の準備と実行

姿勢推定のプログラムを圧縮したファイル「project-posenet-master.zip」を こちらのページ にあるボタンを「Code」→「Download ZIP」とたどることでダウンロードしてください。

ダウンロードする場所はどこでも構いません。プログラムを置きたい場所を自分で選んでください。

ダウンロードした「project-posenet-master.zip」を右クリックして「すべて展開」を選択し、「展開」ボタンをクリックすることで、 圧縮ファイルを展開します。以上で準備は完了です。

展開したファイルを実行するため、スタートメニューの「Anaconda3 (64-bit)」から「Spyder (tflite)」をクリックして起動します。必ず「(tflite)」と記されたものを選択するようにしましょう。TensorFlow Lite をインストールした tflite 環境で動作する Spyder を起動するわけです。

起動した Spyder (tflite) のメニューの「ファイル」→「開く」より、先ほど展開したフォルダをたどって 「project-posenet-master」→「pose_camera_cpu_cv.py」を開きます。似たような名前のファイルがたくさんあるので、間違わずに選択しましょう。

そして、メニューの「実行」→「ファイルごとの設定」で 「コンソール」を「外部システムターミナルで実行」に変更します。さらに「一般設定」で「コマンドラインオプション」にチェックし、
--res 480x360
を記入して「OK」ボタンを押します。

最後に、「実行」→「実行」で実行します。本ページ冒頭に示したように映像中の人物に骨格が上書き表示された画面が開くはずです。

冒頭で述べたように Windows用の TensorFlow Lite が遅いため、480x360 という低解像度の画像で認識を行い、 結果を 640x480 の画像に書き出しています。プログラムを終了するには、映像上でキーボードの q をタイプしてください。

なお、「コマンドラインオプション」に記す内容を、下記のように「--mirror」を追加したものに変更すると、現れる映像が鏡のように左右反転され、直感的に理解しやすい映像となりますのでお好みでご利用ください。
--res 480x360 --mirror 
なお、PoseNet は Raspberry Pi というコンピュータに Coral USB Accelerator というデバイスを追加して実行すると高速であることが確認されています (参考:「Raspberry Pi + Coral USB Accelerator + TensorFlow Lite で物体検出と姿勢推定を試してみよう」)。興味のある方は参考にしてみてください。

4. PoseNet の出力の解説

最後に、PoseNet が人間の姿勢を推定する方法の概略を解説します。

PoseNet では、人間の姿勢(Pose)が下図の17個のキーポイント(keypoint)で構成されていると考えます。それぞれのキーポイントが、画像中のどの場所に存在するかを考えるわけです。


そのために、各キーポイントに対して下図のようなヒートマップ(heatmap)を考えます。本書6章で解説した YOLO のように、ヒートマップは画像をグリッドに区切ったものです。グリッドは横方向にNx個、縦方向にNy個あるものとします。例えば、640x480の画像に対しては Nx=41、Ny=31 という値が用いられます。

このヒートマップの各グリッドに対し、対応するキーポイントが存在するときに高い値をとる「スコア」という数値を割当てます。それにより、例えば「鼻(nose)のヒートマップのスコアが最大値をとるグリッドの位置に鼻がある」とみなせるようになります。


しかし、ヒートマップのグリッドは例えば 640x480 の画像に対して 41×31 個しかないのですから、 そのままでは推定されたキーポイントの位置は精度の低い粗いものとなってしまいます。

そこで、キーポイントの位置を補正して精度を上げるため、下図のようなオフセットベクトル(offset vector)が定義されます。下図のように、各グリッドの位置は飛びとびの粗いものですが、各グリッドから本当のキーポイント(図では鼻)の位置へのベクトル (x, y) を割当てるのです。


そのようなベクトルを各キーポイントの各グリッドに割り当てると下記のようになります。ベクトルには x 成分と y 成分の 2 つがありますから、オフセットベクトルの数値は Nx×Ny×17×2 個になります。


ここまでをまとめると、以下の個数の数値が必要となります。
  • ヒートマップ : Nx×Ny×17 個
  • オフセットベクトル : Nx×Ny×17×2 個
この個数の数値を、出力層のニューロンに出力させます。YOLO と同様に、この出力層を畳み込みニューラルネットワーク(CNN)の出力部に接続するのです。

もし画像中に人間が一人しかいなかったら、「キーポイントごとにヒートマップが最大値をとるグリッドをみつけ、オフセットベクトルで補正する」という操作により、すべてのキーポイントが得られ、姿勢(Pose)が確定します。これを Single-Pose Estimation Algorithm (一つの姿勢を推定するアルゴリズム)といいます。

一方、画像中に複数の人間がいる場合は少し複雑で、Multi-Pose Estimation Algorithm(複数の姿勢を推定するアルゴリズム)が必要になります。その最初の方針は Single-Pose Estimation Algorithumと変わらず、各キーポイントごとのヒートマップを調べ、値が大きなグリッドの位置をキーポイントの候補と見なします。問題は、各キーポイントのヒートマップごとに候補位置が複数見つかり、それを一人一人の人間ごと(Pose ごと)にまとめるのが難しいことです。例えば「A さんの鼻と B さんの目をつなぐ」ということが起こり得ます。

この問題を解決するため、変位ベクトル(displacement vector)という考え方が利用されます。

まず、下図のように各キーポイントを結ぶ 16 本の線分を考えます。これらをエッジと言います。エッジは、認識画像に表示される黄色の線分とは異なり、変位ベクトル用に特別なつなぎ方を考えます。

そして、各エッジに2つの方向の矢印(ベクトル)を考えます。2つのベクトルを区別するために、鼻(nose)から遠ざかる方向を前向き(forward)、鼻に近づく方向を後ろ向き(backward)と呼ぶことにします。これらが変位ベクトル(displacement vector)です。


そして、一つのベクトルを見たときに、その始点をソースキーポイント、終点をターゲットキーポイントと呼びます。


以上の準備のもと、複数人のキーポイントの候補から、一人の人間のキーポイントの候補をまとめる方法は以下のようになります。

まず、ヒートマップが大きな値をとるグリッドをもとに、一つキーポイントの位置を決めます。そのキーポイントを上図のソースキーポイントと考えたときに、 変位ベクトルをたどってターゲットキーポイントの位置を得ます。これを、16本のエッジを前向きと後向きの両方向にたどることで、 一つのキーポイントの位置から17個のキーポイントの位置を数珠つなぎ状に得ることができます。これを Fast Greedy Decoding (高速で欲張りなデコード)といいます。

ヒートマップが大きい一つのキーポイントから出発して残り16個のキーポイントの位置を一気に得てしまうことから Greedy (欲張り)と言われます。 また、ニューロンの出力から人間の姿勢(Pose)を得ることをデコードと言います。

以上を実現する変位ベクトルは、下図のように Nx×Ny×16×2×2 個の数値から構成されます。これらの数値も、出力層のニューロンから出力されます。


以上、PoseNet がどのような出力をもち、そこから人間の姿勢をどのように再構成するかの概略を解説しました。より詳しく知りたい方は、英語ですが 以下を参照してください。


0 件のコメント:

コメントを投稿