勉強しないとな~blog

ちゃんと勉強せねば…な電気設計エンジニアです。

OpenPoseやってみる - 3

前回に続き、OpenPoseのデモをもう少し動かしてみる。

nokixa.hatenablog.com

やってみること

解析対象の動画は、前と同じくMOT16で。

OpenPoseDemo.exeのフラグを色々と試してみる。

手と顔の認識

--face--handのオプションで認識が追加される。
1個ずつやってみる。

.\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img1\ --face
(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img1\ --face
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
(base) PS C:\work\openpose_test\openpose>

かなり時間がかかったので、116フレームのところでCtrl+Cで強制終了。
記録やログには残ってないが、10分以上はかかってた。

この次はフレーム数減らしてやってみる。

タスクマネージャー見てみたら、GPUとCPU自体はそんなに動いていないが、専用GPUメモリがいっぱいいっぱいになっていた。
温度も80°になってる!

次は--handで。
元の画像フォルダとは別のところ(img1 -> img2)に、画像を100枚コピーして置いておいた。

.\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand
(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
(base) PS C:\work\openpose_test\openpose>

結果、まともに処理ができなかったので断念。
1枚もスクショ取れず。

解像度落とす

--net_resolutionオプションで処理する画像の解像度を下げることができて、精度は下がるが処理速度を上げられるよう。
やってみる。

openpose/doc/01_demo.md at master · CMU-Perceptual-Computing-Lab/openpose · GitHub

元の画像は解像度1920x1080なので、水平960(元の半分)にしてみる。

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand --net_resolution 960x-1
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
F0831 23:40:28.063871 25452 syncedmem.cpp:71] Check failed: error == cudaSuccess (2 vs. 0)  out of memory
*** Check failure stack trace: ***
(base) PS C:\work\openpose_test\openpose>

メモリ不足になってしまった。
強制終了した。

説明をよく見てみると、--net_resolutionのデフォルトは-1x368とのこと。
実は垂直368にリサイズしたうえで処理されていたものと考えられる。

このオプションの使用例で出されていたのは、垂直320、256、196、128の4パターン。 一番解像度小さい垂直128ぐらいにして再度試してみる。

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand --net_resolution -1x128
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
OpenPose demo successfully finished. Total time: 62.996555 seconds.
(base) PS C:\work\openpose_test\openpose>

今度は、画像100枚で1分ぐらいで済んだ。

わかりにくいが、画像右側の女性の手が認識されている。
しかし、ほかの人の手はほとんど認識されていない。
この解像度だと認識が厳しいか。

処理結果保存

--write_videoで、動画ファイルとして保存する。

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand --net_resolution -1x128 --write_video img2-1.mp4
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.

Error:
The frame rate of the frames producer is unknown. Set `--write_video_fps` to your desired FPS if you wanna record video (`--write_video`). E.g., if it is a folder of images, you will have to know or guess the frame rate; if it is a webcam, you should use the OpenPose displayed FPS as desired value. If you do not care, simply add `--write_video_fps 30`.

Coming from:
- C:\openpose\include\openpose/wrapper/wrapperAuxiliary.hpp:op::configureThreadManager():820
- C:\openpose\include\openpose/wrapper/wrapperAuxiliary.hpp:op::configureThreadManager():1222
- C:\openpose\include\openpose/wrapper/wrapper.hpp:op::WrapperT<struct op::Datum,class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > >,class std::shared_ptr<class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > > >,class std::shared_ptr<class op::Worker<class std::shared_ptr<class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > > > > > >::exec():424
(base) PS C:\work\openpose_test\openpose>

--write_video_fpsを指定しろと言われた。
指定を入れて再トライ。

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand --net_resolution -1x128 --write_video img2-1.mp4 --write_video_fps 30
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.

Error:
MP4 recording requires an Ubuntu or Mac machine.

Coming from:
- C:\openpose\src\openpose\filestream\videoSaver.cpp:op::VideoSaver::VideoSaver():87
- C:\openpose\src\openpose\filestream\videoSaver.cpp:op::VideoSaver::VideoSaver():101
- C:\openpose\include\openpose/wrapper/wrapperAuxiliary.hpp:op::configureThreadManager():1222
- C:\openpose\include\openpose/wrapper/wrapper.hpp:op::WrapperT<struct op::Datum,class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > >,class std::shared_ptr<class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > > >,class std::shared_ptr<class op::Worker<class std::shared_ptr<class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > > > > > >::exec():424
(base) PS C:\work\openpose_test\openpose> 

UbuntuMacじゃないとmp4保存はできないと。
aviで保存する。

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand --net_resolution -1x128 --write_video img2-1.mp4 --write_video_fps 30
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.

Error:
MP4 recording requires an Ubuntu or Mac machine.

Coming from:
- C:\openpose\src\openpose\filestream\videoSaver.cpp:op::VideoSaver::VideoSaver():87
- C:\openpose\src\openpose\filestream\videoSaver.cpp:op::VideoSaver::VideoSaver():101
- C:\openpose\include\openpose/wrapper/wrapperAuxiliary.hpp:op::configureThreadManager():1222
- C:\openpose\include\openpose/wrapper/wrapper.hpp:op::WrapperT<struct op::Datum,class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > >,class std::shared_ptr<class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > > >,class std::shared_ptr<class op::Worker<class std::shared_ptr<class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > > > > > >::exec():424
(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand --net_resolution -1x128 --write_video img2-1.avi --write_video_fps 30
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
OpenPose demo successfully finished. Total time: 55.650579 seconds.
(base) PS C:\work\openpose_test\openpose>

今度はできた。

姿勢情報のファイル出力

--write_jsonjson形式で保存。

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand --net_resolution -1x128 --write_json output/img2-1.json
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.

Error:
Could not create directory: output\img2-1.json\. Status error = -1. Does the parent folder exist and/or do you have writting access to that path?

Coming from:
- C:\openpose\src\openpose\utilities\fileSystem.cpp:op::makeDirectory():85
- C:\openpose\src\openpose\utilities\fileSystem.cpp:op::makeDirectory():91
- C:\openpose\src\openpose\filestream\fileSaver.cpp:op::FileSaver::FileSaver():15
- C:\openpose\include\openpose/wrapper/wrapperAuxiliary.hpp:op::configureThreadManager():1222
- C:\openpose\include\openpose/wrapper/wrapper.hpp:op::WrapperT<struct op::Datum,class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > >,class std::shared_ptr<class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > > >,class std::shared_ptr<class op::Worker<class std::shared_ptr<class std::vector<class std::shared_ptr<struct op::Datum>,class std::allocator<class std::shared_ptr<struct op::Datum> > > > > > >::exec():424
(base) PS C:\work\openpose_test\openpose> 

保存先フォルダは先に自分で作っとかないといけないよう。
作ってやり直し。

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --image_dir ..\..\MOT16\train\Mot16-09\img2\ --hand --net_resolution -1x128 --write_json output/img2-1_json
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
OpenPose demo successfully finished. Total time: 54.624008 seconds.
(base) PS C:\work\openpose_test\openpose>

jsonファイルができていた。
1フレーム1ファイルになっているよう。

テキストエディタで見たが、よくわからん。
ちゃんと何かでjson読み込みしてみないとダメか。

別の動画を使用

ピアノを弾く手の動きをキャプチャしたいと考えてる。

こちらを使用させていただく。

PexelsでのRDNE Stock projectによる動画: https://www.pexels.com/ja-jp/video/8197909/

こちらのサイトに上がってる動画は、無料で利用可能、出典表示不要、変更可能とのこと。
ありがたい。

無料の写真素材と動画のライセンス - Pexels

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --video "C:\Users\a\Downloads\pexels-rodnae-productions-8197909 (1080p).mp4" --hand --net_resolution -1x128 --write_video piano-1.avi
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
OpenPose demo successfully finished. Total time: 14.915336 seconds.
(base) PS C:\work\openpose_test\openpose> 

かなり速く処理が終わったが、手は全然認識されなかった。。。

解像度を上げて試してみる。
--net_resolutionのオプションを外す。

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --video "C:\Users\a\Downloads\pexels-rodnae-productions-8197909 (1080p).mp4" --hand --write_video output/piano-2.avi
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
OpenPose demo successfully finished. Total time: 203.339542 seconds.
(base) PS C:\work\openpose_test\openpose>

処理時間は長くなったが、結果はやっぱりいまいち。
手を人の全体として認識してたり、何も認識してなかったり。

このフレームだけはかろうじて手を認識してるように見える。

自分で撮影した動画で

自分でピアノを弾いた様子をEZVIZ CP1で撮影して、これを処理対象にしてみた。

15fpsで30秒ほどの動画。
フレーム数は450ぐらいになる。 解像度はおそらく前にいじって2304x1296になってた。

(base) PS C:\work\openpose_test\openpose> .\bin\OpenPoseDemo.exe --video "C:\Users\a\Downloads\2023-08-31 07.48.56.mov" --hand --write_video output/piano-3.avi
Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
Empty image on path: ./doc/GUI_help/GUI_help.png. In C:\openpose\src\openpose\filestream\fileStream.cpp:op::loadImage():367
(base) PS C:\work\openpose_test\openpose>

かなり時間かかったので、これも途中で強制終了した。

処理結果は結構いい感じでは??

23/11/07 追記

自分の動画をきちんと全部通して処理したので、認識結果の動画(gif変換後)を貼っておく。

今のところ評価

  • 人の全身が映っていれば、いい感じに姿勢、骨格推定できる。
  • 処理はめちゃくそ重い。
    リアルタイム処理どころの話じゃない。
  • 手の認識は、うまくいく条件がよくわからない。
    このままではどんなところでも使える、という風にはならないと思われる。

ここまで

とりあえずこんなところで。

どう続けていこうか思案中。。。