腕立て伏せを応援してくれるアプリです。
筋トレをしてかっこいい体になりたいのでAIの力を借りようと思います。
はじめに
腕立て伏せを3回するごとに黄色い声援で応援してくれるアプリを作りました。
ソースコードはこちら↓
https://github.com/Kentea-Watanabe/push_up_count
使うもの
- MediaPipeのPoseを使用します。
- playsoundで音声を扱えます。
- 効果音ラボでフリー音源を使わせてもらいました。
MediaPipe
Poseを使うと全身の33か所を検出してくれます。
公式ページから以下のようにIndexの番号が決まっています。
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を作ろうと思います。