【VisionPose Nano】姿勢推定AI技術で検出した関節の位置から角度を計算するには?計算式から詳しく解説【すぐに使えるエクセルシート付き】

シェアする?

VisionPoseで関節の角度を求める方法

皆さん初めまして、ネクストシステムのエンジニア尾畑と申します。

弊社ではカメラ映像や動画、画像から人間の骨格情報を検出できる姿勢推定AIエンジン「VisionPose」の開発をしています。

WEBカメラだけで3D解析を行うAI骨格検出システム「VisionPose(ビジョンポーズ)」は人間の動きを測定したい方のための唯一の国産SDKです。リアルタイム検出だけでなく動画や静止画からも骨格検出が可能。各種スポーツでのフォーム解析や監視システムへの組み込み、Vtuber配信など、さまざまなシーンでお使いいただけ...

本日は「VisionPose」シリーズの中でも、ハード付属で面倒なセットアップやインストールの手間がない安価な研究開発用のスターターキット「VisionPose Nano」をご購入いただいた方、または検討段階の方に向けてフォーカスし、

「Nanoで骨格の位置はわかったけど、関節の角度ってどうやって計算すればいいの?」

悩めるビジネスマン

という疑問にお応えするとともに、Nanoで取得した推論結果をコピペするだけで角度が算出できる、超便利エクセルシートをご共有したいと思います!

ちなみに、後述する計算式の考え方部分は一般的なものなので、Nano以外のVisionPoseシリーズにも応用頂けます。

3つの関節座標から角度を求めるエクセルシートをDL

何はともあれ、こちらのNanoで取得した推論結果をコピペするだけで、すぐにお使い頂けるエクセルシートをダウンロードしてください。

ご利用いただいているNanoの推論結果をA〜AG列にまるっとコピペして頂ければ、右肘の関節角度が自動的にAW列に計算されます!

他に必要な角度があれば同様に数式をコピペして増やしてください。

エクセルイメージ

AからAG列にNanoの推論結果をコピペすると・・・?

角度算出イメージ

あら、簡単!角度が自動で算出されます!

はい、これで終わりです!お疲れさまでした!

・・・というのも味気ないので、角度計算に使っているAI〜AW列のExcel処理内容について、どんなことをしているか、それぞれ解説してみたいと思います。

そもそも角度の算出ってどうするの?という方は後半により詳しい解説をご用意しています。

推論結果文字列から数値データだけを抽出する

まずは、計算の大元となる骨格位置情報$ (x, y) $を準備します。

AI列:右肩の推論結果文字列から両端の大括弧を取り除く処理

=MID(M3,2,LEN(M3)-2)

右肩の推論結果文字列 [x y](M列)から両端の大かっこを除去(2文字目〜最後から2文字目までを抽出)してます。

参考:MID関数LEN関数

AJ列:右肩の$x$値のみを抽出する処理

=MID(AI3,1,FIND(" ",AI3,1)-1)

AI列から右肩の$x$値のみ(文字列の左から空白までの値)を抽出してます。

参考:FIND関数

AK列:右肩の$y$値のみを抽出する処理

=RIGHT(AI3,LEN(AI3)-FIND(" ",AI3,1))

AI列から右肩の$y$値のみ(文字列の右から空白までの値)を抽出してます。

参考:RIGHT関数

これで、右肩の骨格位置情報$ (x, y) $を抽出することができました!

同様に、右肘(AL~AN列)と右手首(AO~AQ列)も$ (x, y) $をそれぞれ抽出しておきます。

骨格のベクトルを求める

ベクトルのイメージ

AR列:右上腕(右肘→右肩)ベクトルのXを計算する処理

=AJ3-AM3

右肘から右肩へのベクトルなので、右肩の$x$値から右肘の$x$値を引いています。

AS列:右上腕(右肘→右肩)ベクトルのYを計算する処理

=AK3-AN3

AR列と同様に、右肩の$y$値から右肘の$y$値を引いています。

同様に、右前腕(右肘→右手首)ベクトルも求めます。(AT〜AU列)

角度を求める

いよいよ、右肘の角度を求めます!

AV列:右肘の$ \cos\theta $を計算する処理

=(AR3*AT3+AS3*AU3)/(SQRT(AR3*AR3+AS3*AS3)*SQRT(AT3*AT3+AU3*AU3))

角度を求めるために、2つのベクトルからコサインを計算しています。
$$ \cos\theta = \frac{ \vec{a}\cdot\vec{b} }{ |\vec{a}||\vec{b}| } = \frac{ a_{x}b_{x} + a_{y}b_{y} }{ \sqrt{a_{x}^2+a_{y}^2}\sqrt{b_{x}^2+b_{y}^2} } $$

(計算式の内容については後述)

AW列:$ \cos\theta $を度数へ変換する処理

=DEGREES(ACOS(AV3))

コサインの値から角度(逆余弦)を求めて、ラジアンを度数に変換しています。

参考:ACOS関数DEGREES関数

以上の処理をエクセル上で行うことで、右肘の関節を計算しています。

角度は2つのベクトルが成す角なので、鋭角となる方の角度(0〜180度)で表現されていることにご注意ください。

また、関節がカメラから見えない場合など、推論結果が一部「0(ゼロ)」になっている場合があります。この場合は関節角度は求められませんのでご注意ください。

後はご自身の希望に合わせて、求めたい関節角度を計算しちゃってください!

(より理解したい人へ)角度の求め方自体の解説

どうして上の計算式で角度を求めることができるの!?と興味津々なあなたのために、もう少し詳しい解説も載せておきます!

ベクトルの成す角

ベクトル角度

ベクトルのことをご存知の方は、ベクトルの内積の定義から $ \cos\theta $を算出できます。

ベクトルの内積定義

ベクトルの内積は以下の様に定義されています。

$ \vec{a}\cdot\vec{b} = |\vec{a}||\vec{b}|\cos\theta $

ここに$ \cos\theta $が含まれているので、内積の値が分かれば$ \cos\theta $を計算することができます。

つまり以下の計算式が解ければ良いというわけです。

$ \cos\theta = \frac{ \vec{a}\cdot\vec{b} }{ |\vec{a}||\vec{b}| } \ldots①  $

ベクトル成分から$ \cos\theta $を計算

ではどうやって内積の値を求めるかというと、ベクトルの成分から計算できます。

ベクトルをそれぞれ $ \vec{a} = (a_{x},a_{y}) ,  \vec{b} = (b_{x},b_{y}) $ とすると、

ベクトルの内積は

$ \vec{a}\cdot\vec{b} = a_{x}b_{x} + a_{y}b_{y}\ldots② $

となります。

また$ |\vec{a}| $と$ |\vec{b}| $はそれぞれのベクトルの長さなので、

$ |\vec{a}| = \sqrt{a_{x}^2+a_{y}^2}\ldots③ $

$ |\vec{b}| = \sqrt{b_{x}^2+b_{y}^2}\ldots④ $

となります。

①〜④を合わせることで、ベクトル成分から$ \cos\theta $を計算する式を算出できるというわけです。(ExcelファイルのAV列で使われていた式です)

$$ \cos\theta = \frac{ \vec{a}\cdot\vec{b} }{ |\vec{a}||\vec{b}| } = \frac{ a_{x}b_{x} + a_{y}b_{y} }{ \sqrt{a_{x}^2+a_{y}^2}\sqrt{b_{x}^2+b_{y}^2} } $$

$ \cos\theta $を角度に変換する

上記の式から、3点の座標が分かれば成す角$ \cos\theta $が計算できることがわかりました。

しかし、「知りたいのは角度が何度なのかであって、$ \cos\theta $がわかってもしょうがないよ!?」内心思っている方もいらっしゃることでしょう。

続いては、$ \cos\theta $を度数に変換する方法について解説したいと思います。

$ \theta $を計算

$ \cos\theta $のうち$ \theta $が角度部分に当たるので、$ \theta $を求めます。

cosθの説明

図の様に、底辺の長さがcosθ、斜辺の長さは1の直角三角形の角度を考えれば良いんですが…

毎回考えてもいられないので、コサインの逆関数(arccos)を使ってコンピュータに計算してもらいましょう!

コサインの関数が $ y = \cos\theta $だとすると、

コサインの逆関数は$ \theta = \arccos y$という関係にあります。

ExcelのACOS関数を使うことで、θを計算することが出来るという訳です!

$ \theta $を角度へ変換

$ \theta $を求めることが出来ましたが、1つ注意点があります。

一般的に$ \theta $は、ラジアン(rad)という単位で表される点です!(ナ、ナンダッテー

そのため、ExcelのACOS関数も例に漏れずラジアンの単位で結果が出力されてしまいます。

しかし、ご安心を。

ラジアン表記は360°のことを $ 2\pi $($\pi$は円周率)で表しただけなので、簡単に度数に変換することができます!

つまり、

$$ \theta° = \theta\times\frac{360}{2\pi}[rad] =  \theta\times\frac{180}{\pi}[rad] $$

という変換式が作れるわけです!

これで$ \theta $を度数に変換することができました!

しかしこんなことをしなくても、ExcelにはDEGREES関数という便利な関数が用意されているので、Excelをお使いの方は素直にこの関数を使ってしまいましょう!

まとめ

無事、関節角度を求めることができたでしょうか?

この記事が皆様のやりたかったことの一助となれば幸いです。

弊社では、さまざまな最新技術を駆使した開発を行っています。

実現させたい内容に合わせて最適な方法をご提案いたしますので、姿勢推定技術を使って実現できるのかお悩みの方はぜひ弊社にご相談下さい!

VisionPoseのご購入、またはご質問ご相談のお問い合わせはこちらから。アカデミックライセンスご希望の際もこちらからお問い合わせください。よくある質問もあわせてご確認ください。

オマケ:ベクトルを使わない $ \cos\theta $の計算方法

ベクトルって何!?美味しいの??!??というそんなあなたに、2次元平面(XY平面)の3点から角度を算出する方法も載せておきます。(やっている内容はほとんど同じです)

余弦定理を使って $ \cos\theta $を求める

世の中には余弦定理というものがあります。

$$ a^2 = b^2 + c^2 – 2bc\cos\theta $$

余弦定理

図の様に3点A,B,Cがあり、その点の対角にある辺(点自身と接しない辺)をそれぞれa, b, cとします。

余弦定理から $\cos\theta$ を求める形に変形すると以下の様になります

$ \cos\theta = \frac{ b^2 + c^2 – a^2 }{ 2bc } $

線分a,b,cの長さは、各点のx, yを用いて以下の様に表せます(三平方の定理)

$ a = \sqrt{(C_{x} – B_{x})^2 + (C_{y} -B_{y})^2} $

$ b = \sqrt{(C_{x} – A_{x})^2 + (C_{y} -A_{y})^2} $

$ c = \sqrt{(B_{x} – A_{x})^2 + (B_{y} -A_{y})^2} $

これを先ほどの式に組み込むと

$ \cos\theta = \frac{ b^2 + c^2 – a^2 }{ 2bc } $

$ \cos\theta = \frac{ (C_{x} – A_{x})^2 + (C_{y} -A_{y})^2 + (B_{x} – A_{x})^2 + (B_{y} -A_{y})^2 – (C_{x} – B_{x})^2 – (C_{y} -B_{y})^2 }{ 2\sqrt{(C_{x} – A_{x})^2 + (C_{y} -A_{y})^2}\sqrt{(B_{x} – A_{x})^2 + (B_{y} -A_{y})^2} } $

の様に、3点の座標から $\cos\theta$を求めることができます。

ちょっと大変ですが、先ほどのExcelに組み込むならば

=((AP3-AM3)^2+(AQ3-AN3)^2+(AJ3-AM3)^2+(AK3-AN3)^2-(AP3-AJ3)^2-(AQ3-AK3)^2)/(2*SQRT((AP3-AM3)^2+(AQ3-AN3)^2)*SQRT((AJ3-AM3)^2+(AK3-AN3)^2))

とすることで、$ \cos\theta $を求めることができます!

後は、$ \cos\theta $を上記と同じ流れで角度に変換してください!

トップへ戻る