AI技術を用いてユーザーのジョジョ立ち画像を解析し、
ジョジョ立ちの合否を判定する検定サービスをリリースいたしました!
▼ サービスURL
https://jojo-pose-exam.jp
=> 現在サービス停止中🙇♂️
▼ リポジトリ
https://github.com/kohei-yamamoto1012/jojo-pose-exam
はじめに
はじめまして、ジョジョ好きエンジニアのやまもとと申します。
- 「ジョジョ好きが楽しめるサービスを開発したい」
- 「多く人がジョジョ立ちに挑戦する姿を見てみてたい!」
そのような思いから、ジョジョ立ちの検定サービスを開発いたしました!
受検手順
ジョジョ立ち検定は以下の3ステップで受検することができます。
-
検定選択
検定一覧から受検したいジョジョ立ちの検定を選択します。
リリース時点では、以下の検定がライナップされています。- ジョナサン立ち検定
- ジョルノ立ち検定
- 承太郎立ち検定
-
ジョジョ立ち撮影
検定を選択したら「お手本となるモデル」と「各検定ごとに設定されたチェックポイント」
を参考にジョジョ立ちを行い、スマホカメラ等で撮影します。 -
ジョジョ立ち画像のアップロード
撮影したジョジョ立ち画像をアップロードします。
アップロードした画像の解析後に、受検結果が表示されます!
また、受験結果ページへの遷移時には評価コメントのカットイン演出が行われます。
検定選択ページ | 検定詳細ページ | 検定結果ページ |
---|---|---|
合否判定処理
ジョジョ立ち検定の要となる合否判定処理について、解説したいと思います。
合否判定処理は、以下の事前準備と処理フローによって構成されています。
事前準備
合否判定処理中では、機械学習モデルを用いた姿勢推定(pose detection) を行います。
ジョジョ立ち検定では、姿勢推定用の機械学習モデルとして
TensorFlow1のMoveNet2を採用しました。
MoveNetの採用にあたり、1つの課題が発生します。
それは「TensorFlowがRubyをサポートしていない」という事です。
ジョジョ立ち検定はバックエンドにRuby on Railsを採用しているため、
MoveNet(=TensorFlow形式の学習モデル)を実行することができませんでした。
この課題を解決するために、事前準備としてMoveNetをTensorFlow形式から、
Ruby上で実行可能なONNX形式3への変換を行いました。
ONNX形式への変換には、tensorflow-onnx4を用います。
以下のようにtensorflow-onnxを実行して、変換を行います。
python -m tf2onnx.convert --opset 15 \
--saved-model movenet_singlepose_lightning_4 \
--output movenet_singlepose_lightning_4.onnx
※ 各パラメータの詳細については、tensorflow-onnx公式をご参照ください。
処理フロー
1. アップロード画像の加工
アップロードされたジョジョ立ち画像をMoveNetの入力形式に変換します。
-
MoveNetの入力形式
画像サイズ チャンネル数 色順 画素値の範囲 192x192 3 RGB 0 ~ 255 -
加工処理
ruby-vips5を用いて、アップロード画像をMoveNetの入力形式に変換します。
INPUT_IMG_WIDTH = 192
INPUT_IMG_HEIGHT = 192
def preprocess(img)
img = img[0..2] if img.bands > 3
img_resize = img.thumbnail_image(INPUT_IMG_WIDTH, height: INPUT_IMG_HEIGHT) # アスペクト比を維持しつつリサイズ
img_resize = img_resize.embed(0, 0, INPUT_IMG_WIDTH, INPUT_IMG_HEIGHT, extend: :black) # 正方形に0埋め
img_resize.to_a # Arrayに変換
end
2. 姿勢推定の実行
画像の加工が完了したら、姿勢推定を実行します。
事前準備にて、ONNX形式に変換したMoveNetをonnxruntime-ruby6を用いて実行します。
ML_MODEL_PATH = 'app/ml_models/movenet_singlepose_lightning_4.onnx'.freeze
def estimate_pose(img)
input = preprocess(img) # アップロード画像の加工処理
model = OnnxRuntime::Model.new(Rails.root.join(ML_MODEL_PATH)) # 学習モデル(MoveNet)の読み込み
model.predict({ 'input' => [input] })['output_0'][0][0] # 姿勢推定処理の実行
end
-
姿勢推定の結果について
MoveNetでは出力として、17の検出部位(=キーポイント)の姿勢推定結果が得られます。-
17の検出部位
鼻、両目、両耳、両肩、両肘、両手首、両腰、両膝、両足首 -
姿勢推定結果の内容
値 単位 検出部位の画像内でのx座標 (元画像の幅を1とした)割合 検出部位の画像内でのy座標 (元画像の高さを1とした)割合 検出結果の確からしさ 割合
-
3.合否判定
姿勢推定結果を用いて、以下の手順で合否判定を行います。
-
各チェックポイントのクリア判定
各検定ごとに複数のチェックポイントが設定されており、それらのクリア判定を行います。
チェックポイントの一例として、以下のようなものがあげられます。検定名 チェックポイント クリア条件 配点 ジョナサン立ち検定 右肩を上げる 右肩y座標 > 左肩y座標 > 右肘y座標 20点 承太郎立ち検定 左肘を直角に曲げ、左手を腰の横に 75度 < 左肘の角度 < 105度 20点 -
得点の計算
上記の例のように、各チェックポイントには配点が設定されており、
条件クリアしたチェックポイントの合計点を得点とします。 -
合否判定
得点が80点以上となった場合に 「合格」。
得点が79点以下となった場合に 「不合格」 と判定します。
ちなみに関節の角度の計算は、ベクトルを用いて行っています。
引用元: https://w3e.kanazawa-it.ac.jp/math/category/vector/henkan-tex.cgi?target=/math/category/vector/naiseki-wo-fukumu-kihonsiki.html
使用技術
-
Ruby 3.0.2
-
Rails 6.1.4
-
Vue.js 2.6.14
-
主要gemパッケージ
-
主要npmパッケージ
-
インフラ
- Heroku
- PostgreSQL
- Amazon S3
-
姿勢推定
- TensorFlowのMoveNet
ER図
おわりに
最後までご覧いただきありがとうございました!
もし興味を持っていただけましたら、ぜひジョジョ立ち検定に挑戦していただけると嬉しいです。
それでは、アリーヴェデルチ!(さよならだ)
▼ Twiiterアカウント
https://twitter.com/koheiyamamoto26
-
TensorFlowとは、Googleが開発しオープンソースで公開している、機械学習に用いるためのソフトウェアライブラリです。
https://www.tensorflow.org/?hl=ja ↩ -
MoveNetとは、TensorFlow公式によって公開されている、高速・高精度な姿勢推定用の学習済みモデルです。
https://www.tensorflow.org/hub/tutorials/movenet?hl=ja ↩ -
ONNXとは、Open Neural Network Exchangeの略称で、機械学習モデルを様々なフレームワーク間で共有するためのフォーマットです。
https://onnx.ai ↩ -
tensorflow-onnxとは、TensorFlow形式の学習モデルをONNX形式に変換するためのPythonパッケージです。
https://github.com/onnx/tensorflow-onnx ↩ -
ruby-vipsとは、画像処理ライブリラリlibvipsのrubyバインディングです。
https://github.com/libvips/ruby-vips ↩ -
onnxruntime-rubyとは、ONNX形式の学習モデルをRuby上で実行するためのgemパッケージです。
https://github.com/ankane/onnxruntime-ruby ↩