RGBカメラ画像処理による関節角度推定

大学の画像処理の実習で、実験の課題が出されました。

実験の内容としては、「今まで学習したことを使って、実験する価値のある画像処理プログラムを作成する」ことです。「実験する価値がある」というのは、すでに実現できるとわかっているものではなく、実験してみないとわからないものということでした。

 

そこで私はRGBカメラによる人間の関節角度推定システムを作ることにしました。

普段、開発をしていてRGBカメラしかない状況で、「深度センサーを組み込んだRGB-Dカメラのような距離情報を取得できるカメラがあれば…」ということが多々あります。例えば、iPhoneアプリ開発で、iPhoneのカメラを使ってセンシングする場合など.....

Kinectのような深度センサーが組み込まれたRGB-Dカメラなら関節推定はできる(と思う)のですが、RGBカメラでは普通にはできません。

 

 

システム構成

今回は腕の関節角度推定をしました。

肌色領域抽出とテンプレートマッチングがベースのシステムになっています。

 

簡単な流れとしては、

1. 上腕と前腕部分をテンプレート画像として抽出

2. 腕を任意の角度に曲げて角度推定開始

3. 上腕と前腕部のテンプレート画像から腕の状態の候補となる合成画像を生成

4. 角度推定を開始したときのフレーム画像と3の合成画像を肌色抽出し、2値化

5. 4で生成した二枚の画像でテンプレートマッチングし類似度計算

6. 3で肘関節、肩関節の角度を変えながら3~5を繰り返す

7. 最も類似度が高かった時の合成画像の状態を推定結果として出力

となっています。実際の画像で見ていきましょう↓

 

1. 上腕と前腕部分をテンプレート画像として抽出

マウスドラッグで赤色の枠を出し、画像切り出し部分を選択します。

f:id:IKEP:20180805142001p:plain

切り出した画像が↓

page6image1768224  page7image1772480
 

 2. 腕を任意の角度に曲げて角度推定開始

適当に腕を曲げて角度推定開始です。今回、角度推定開始はキーボードのpキーを押したら始まるようにしました。

 

3. 上腕と前腕部のテンプレート画像から腕の状態の候補となる合成画像を生成

一度、上腕に対して前腕部を回転させた画像を生成し、その画像全体を回転させています。その結果の合成画像が↓

f:id:IKEP:20180805143821p:plain

前腕部回転により肘の回転、そのあとの画像全体の回転によって肩の回転の候補を作成しています。

 

4. 角度推定を開始したときのフレーム画像と3の合成画像を肌色抽出し、2値化

合成画像に対して肌色領域抽出して2値化したものです↓

f:id:IKEP:20180805150155j:plain

 

5. 4で生成した二枚の画像でテンプレートマッチングし類似度計算

6. 3で肘関節、肩関節の角度を変えながら3~5を繰り返す

7. 最も類似度が高かった時の合成画像の状態を推定結果として出力

 

 

プログラム

以上のことをプログラミングしたのが↓

Visual StudioC++OpenCVで実現しています

今回は腕の肩側が左側に、手のひら側が右側でカメラに映るのを前提にしています。

 

 

 

動かしてみる

コンソールに出力されてる文字が見にくいですが…

肘関節角度は肘の開き具合です。肘を曲げずに腕がまっすぐなら180度、完全に曲げたら10度(?)です。

肩関節は腕を水平にしている状態が0度、そこから下に降ろした状態が-90度、上にあげた状態が90度です。

 

まとめ

色々試行錯誤して作った結果、そこそこいい感じに推定できているのではないかなと....

ただ、計算速度が遅すぎるのは問題ですが....笑

やっぱ、RGB-Dカメラを使うのが手取り早いです..... (^^;