2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

おもちゃで遊ぶAdvent Calendar 2022

Day 1

姿勢推定を用いて腕立てを応援してくれるおもちゃを作ってみた!

Last updated at Posted at 2022-11-30

腕立て伏せを応援してくれるアプリです。
筋トレをしてかっこいい体になりたいのでAIの力を借りようと思います。

はじめに

腕立て伏せを3回するごとに黄色い声援で応援してくれるアプリを作りました。
sample_pushup.gif

ソースコードはこちら↓
https://github.com/Kentea-Watanabe/push_up_count

使うもの

  • MediaPipeのPoseを使用します。
  • playsoundで音声を扱えます。
  • 効果音ラボでフリー音源を使わせてもらいました。

MediaPipe

Poseを使うと全身の33か所を検出してくれます。
公式ページから以下のようにIndexの番号が決まっています。

pose_tracking_full_body_landmarks.png

33か所の座標情報はこんな風に格納される。

landmark {
  x: 0.6190348863601685
  y: 0.7434951066970825
  z: -0.7935404181480408
  visibility: 0.9996245503425598
}
landmark {
  x: 0.6465774178504944
  y: 0.6267579197883606
  z: -0.7744203805923462
  visibility: 0.9992997646331787
}
landmark {
  x: 0.6661152243614197
  y: 0.6248564124107361
  z: -0.7743856906890869
  visibility: 0.9992523193359375
}

各ランドマークは、以下で構成されるみたい。

  • x : ランドマークのX座標([0.0、1.0])
  • y : ランドマークのY座標([0.0、1.0])
  • z : ランドマークの深度。腰の中点を原点として、値が小さいほどカメラに近くなる。全身モードでのみ予測される。([0.0、1.0])
  • visibility : 画像表示(存在し遮られていない)の可能性([0.0、1.0])。

腕立てをどのように定義するのか

手のひらの位置と肩の位置が近くなったら腕立ての回数を増やすことにします。
Indexで言うと、19と11の距離が短くなったら腕立ての成功としました。

if results.pose_landmarks:
      for idx, landmark in enumerate(results.pose_landmarks.landmark):
        if idx == 11:  # 左肩
            left_shoulder = landmark
        if idx == 19:  # 左手
            left_index = landmark
            # 2点間の距離を求める
            distance = math.sqrt((left_shoulder.x - left_index.x)**2 + (left_shoulder.y - left_index.y)**2)

全frameに推論かけるとエグいことになるので...。

fps = cap.get(cv2.CAP_PROP_FPS)
max_inference = fps * 2
push_up_cnt = 0
frame = 0

while cap.isOpened():
    frame +=1
# 省略 ##############################################
    # max_inferenceに到達したら推論をかける
    if frame > max_inference:
        if distance < 0.15:
            push_up_cnt += 1
            # frame数の初期化
            frame = 0
            print('push up success', f'cnt : {push_up_cnt}')

ダイエットのための工夫

playsoundを用いて、腕立てを3回成功するたびに、黄色い声援を送ります。
効果音ラボから応援されたいサウンドを取得してきます。

pushup_app.py
from playsound import playsound

if frame > max_inference:
    if distance < 0.15:
        push_up_cnt += 1
        # 黄色い声援の追加
        if push_up_cnt % 3 ==0:
            playsound("sound\sample_sound.mp3")

最後に

他にも、音声の種類を増やしたり、スクワットでも同じAIを作ろうと思います。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?