YOLOv11による2次元姿勢推定
【概要】YOLO11-poseを使用して、カメラから人体17箇所のキーポイント(鼻、目、耳、肩、肘、手首、腰、膝、足首)をリアルタイム検出。Nano・Small・Medium・Large・Extra-Largeの5種類のモデルサイズで精度と処理速度のトレードオフを比較実験可能。Windows環境での実行手順、プログラムコード、実験アイデアを含む。

目次
概要
技術名: YOLOv11-pose(You Only Look Once version 11 - Pose Estimation)
発表: Ultralytics YOLO Vision 2024 (YV24) にて発表、2024年リリース
新規性・特徴: YOLOv11-poseは、改良されたバックボーンとネック設計により、YOLOv8と比較して22%少ないパラメータで高い精度を実現する姿勢推定技術である。人体の17箇所のキーポイント(関節位置)をリアルタイムで検出し、トップダウン方式とボトムアップ方式の両方の利点を組み合わせた単一ステップ処理を採用している。エッジデバイスからクラウドプラットフォームまで幅広い環境で動作可能である。
技術革新:
- Enhanced Feature Extraction:改良されたバックボーンとネック設計による特徴抽出能力の向上
- Optimized Efficiency:精度を維持しながら高速処理を実現する最適化された学習パイプライン
- Adaptability:エッジデバイス、クラウド、NVIDIA GPU対応の環境適応性
- Unified Processing:人物検出とポーズ推定を単一ネットワークで同時実行
アプリケーション例: スポーツ動作解析、リハビリテーション支援、フィットネスアプリ、モーションキャプチャ、姿勢矯正システム、建設現場安全監視、動物行動分析
体験価値: カメラの前で様々なポーズを取ることで、最新のAIが人体の関節位置を瞬時に認識する過程を視覚的に体験できる。異なるモデルサイズによる精度と速度のトレードオフを実験的に比較し、最新AI技術の性能特性を理解することが可能である。
事前準備
Python, Windsurfをインストールしていない場合の手順(インストール済みの場合は実行不要)。
- 管理者権限でコマンドプロンプトを起動する(手順:Windowsキーまたはスタートメニュー > cmd と入力 > 右クリック > 「管理者として実行」)。
- 以下のコマンドをそれぞれ実行する(winget コマンドは1つずつ実行)。
REM Python をシステム領域にインストール
winget install --scope machine --id Python.Python.3.12 -e --silent
REM Windsurf をシステム領域にインストール
winget install --scope machine --id Codeium.Windsurf -e --silent
REM Python のパス設定
set "PYTHON_PATH=C:\Program Files\Python312"
set "PYTHON_SCRIPTS_PATH=C:\Program Files\Python312\Scripts"
echo "%PATH%" | find /i "%PYTHON_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_PATH%" /M >nul
echo "%PATH%" | find /i "%PYTHON_SCRIPTS_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_SCRIPTS_PATH%" /M >nul
REM Windsurf のパス設定
set "WINDSURF_PATH=C:\Program Files\Windsurf"
if exist "%WINDSURF_PATH%" (
echo "%PATH%" | find /i "%WINDSURF_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%WINDSURF_PATH%" /M >nul
)
必要なパッケージのインストール
管理者権限でコマンドプロンプトを起動し、以下のコマンドを実行する:
pip install -U torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
pip install ultralytics opencv-python
プログラムコード
# プログラム名: YOLOv11姿勢推定プログラム
# 特徴技術名: YOLOv11 (You Only Look Once version 11)
# 出典: Ultralytics. (2024). YOLOv11: Enhanced Feature Extraction and Optimized Efficiency. https://github.com/ultralytics/ultralytics
# 特徴機能: Enhanced Feature Extraction with C3k2 blocks - YOLOv8のC2fブロックを改良したC3k2ブロックにより、計算効率を維持しながら特徴抽出能力を向上。22%少ないパラメータで高精度を実現
# 学習済みモデル: yolo11n-pose.pt(COCOデータセット17キーポイント学習済み、2.9Mパラメータ、最速処理)URL: Ultralyticsライブラリが自動ダウンロード
# 方式設計:
# - 関連利用技術: OpenCV(画像処理・表示)、NumPy(数値計算)
# - 入力と出力: 入力: 動画(ユーザは「0:動画ファイル,1:カメラ,2:サンプル動画」のメニューで選択.0:動画ファイルの場合はtkinterでファイル選択.1の場合はOpenCVでカメラが開く.2の場合はhttps://github.com/opencv/opencv/blob/master/samples/data/vtest.aviを使用)、出力: OpenCV画面でリアルタイム表示(検出された姿勢とキーポイント座標)、1秒間隔でprint()による処理結果表示、終了時にresult.txtファイルへ保存
# - 処理手順: 1.YOLOv11モデルロード、2.動画フレーム取得、3.C3k2ブロックによる特徴抽出、4.姿勢推定ヘッドで17キーポイント検出、5.信頼度閾値によるフィルタリング、6.結果の可視化
# - 前処理、後処理: 前処理:DirectShowバックエンドによる低遅延フレーム取得、バッファサイズ1設定。後処理:信頼度0.5以上のキーポイントのみ表示、キーポイント名と座標のテキスト描画
# - 追加処理: grab()とretrieve()の分離呼び出しによる最新フレーム取得(遅延防止効果)
# - 調整を必要とする設定値: CONF_THRESHOLD(キーポイント検出の信頼度閾値、デフォルト0.5、低くすると検出数増加but誤検出も増加)
# 将来方策: 検出されたキーポイント数の時系列変化を監視し、安定して検出されるキーポイントの割合からCONF_THRESHOLDを動的に調整する機能の実装
# その他の重要事項: Windows環境専用(cv2.CAP_DSHOW使用)、COCO形式17キーポイント(鼻、目、耳、肩、肘、手首、腰、膝、足首)
# 前準備: pip install ultralytics opencv-python
import cv2
import numpy as np
from ultralytics import YOLO
import tkinter as tk
from tkinter import filedialog
import os
import time
import urllib.request
# 定数定義
MODEL_NAME = 'yolo11n-pose.pt'
CONF_THRESHOLD = 0.5 # キーポイント検出の信頼度閾値(0.0-1.0)
# 人体17箇所キーポイント名称(COCO形式)
KEYPOINT_NAMES = [
'nose', 'left_eye', 'right_eye', 'left_ear', 'right_ear',
'left_shoulder', 'right_shoulder', 'left_elbow', 'right_elbow',
'left_wrist', 'right_wrist', 'left_hip', 'right_hip',
'left_knee', 'right_knee', 'left_ankle', 'right_ankle'
]
# プログラム開始時の説明
print('=== YOLOv11姿勢推定プログラム ===')
print('概要: YOLOv11を使用してリアルタイムで人体の17箇所のキーポイントを検出します')
print('検出部位: 鼻、目(左右)、耳(左右)、肩(左右)、肘(左右)、手首(左右)、腰(左右)、膝(左右)、足首(左右)')
print("操作方法: 'q'キーで終了")
print('')
# 乱数シード設定(再現性確保)
np.random.seed(42)
# YOLOv11モデルのロード
print('YOLOv11モデルをロード中...')
model = YOLO(MODEL_NAME)
print(f"モデル '{MODEL_NAME}' のロードが完了しました")
print('')
# 結果記録用リスト
results_log = []
last_print_time = time.time()
frame_count = 0
fps_start_time = time.time()
def video_processing(frame):
global last_print_time, results_log, frame_count, fps_start_time
# FPS計算
frame_count += 1
current_time = time.time()
# YOLOv11による姿勢推定実行
results = model(frame)
annotated_frame = results[0].plot()
# FPS表示
fps = frame_count / (current_time - fps_start_time)
cv2.putText(annotated_frame, f'FPS: {fps:.1f}', (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
# キーポイント処理(複数人物対応)
detected_keypoints = []
person_count = 0
for result in results:
if hasattr(result, 'keypoints') and result.keypoints is not None:
keypoints = result.keypoints
if hasattr(keypoints.data, 'cpu'):
keypoints_data = keypoints.data.cpu().numpy()
else:
keypoints_data = keypoints.data
if len(keypoints_data.shape) == 3 and keypoints_data.shape[1] == 17:
# 全人物を処理
for person_idx in range(keypoints_data.shape[0]):
person_count += 1
person_keypoints = []
for i in range(17):
keypoint = keypoints_data[person_idx, i]
if len(keypoint) >= 3:
x, y, conf = keypoint[:3]
if conf > CONF_THRESHOLD:
# 人物番号を含めて表示
text = f'P{person_idx}:{KEYPOINT_NAMES[i]}({x:.0f},{y:.0f})'
cv2.putText(annotated_frame, text, (int(x), int(y)),
cv2.FONT_HERSHEY_SIMPLEX, 0.4,
(255, 255, 255), 1)
person_keypoints.append(f'Person{person_idx}-{KEYPOINT_NAMES[i]}:({x:.0f},{y:.0f},conf:{conf:.2f})')
if person_keypoints:
detected_keypoints.extend(person_keypoints)
# 1秒間隔での出力
if current_time - last_print_time >= 1.0:
if detected_keypoints:
timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
log_entry = f'[{timestamp}] 検出人数: {person_count}, 検出キーポイント数: {len(detected_keypoints)}, FPS: {fps:.1f}'
print(log_entry)
for kp in detected_keypoints[:5]: # 最初の5個のみ表示
print(f' {kp}')
if len(detected_keypoints) > 5:
print(f' ... 他 {len(detected_keypoints) - 5} 個のキーポイント')
results_log.append(log_entry)
results_log.extend([f' {kp}' for kp in detected_keypoints])
else:
timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
log_entry = f'[{timestamp}] キーポイントが検出されませんでした, FPS: {fps:.1f}'
print(log_entry)
results_log.append(log_entry)
last_print_time = current_time
return annotated_frame
print('0: 動画ファイル')
print('1: カメラ')
print('2: サンプル動画')
choice = input('選択: ')
temp_file = None
if choice == '0':
root = tk.Tk()
root.withdraw()
path = filedialog.askopenfilename()
if not path:
exit()
cap = cv2.VideoCapture(path)
elif choice == '1':
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
elif choice == '2':
# サンプル動画ダウンロード・処理
url = 'https://github.com/opencv/opencv/raw/master/samples/data/vtest.avi'
filename = 'vtest.avi'
try:
print(f'サンプル動画をダウンロード中: {url}')
urllib.request.urlretrieve(url, filename)
temp_file = filename
cap = cv2.VideoCapture(filename)
print('サンプル動画のダウンロードが完了しました')
except Exception as e:
print(f'動画のダウンロードに失敗しました: {url}')
print(f'エラー: {e}')
exit()
else:
print('無効な選択です')
exit()
# メイン処理
print('\n処理を開始します...')
try:
while True:
cap.grab()
ret, frame = cap.retrieve()
if not ret:
break
processed_frame = video_processing(frame)
cv2.imshow('YOLOv11 Pose Estimation', processed_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
finally:
cap.release()
cv2.destroyAllWindows()
if temp_file:
try:
os.remove(temp_file)
except:
pass
# 結果をファイルに保存
if results_log:
with open('result.txt', 'w', encoding='utf-8') as f:
f.write('\n'.join(results_log))
print('\n処理結果をresult.txtに保存しました')
print('プログラムを終了しました')
使用方法
- プログラムを実行すると、カメラが起動し、リアルタイムで姿勢推定が開始される
- カメラに向かって様々なポーズを取ると、17箇所のキーポイントが検出・表示される
- 各キーポイントには番号、名称、座標(ピクセル単位)が表示される
- YOLOv11の改良された特徴抽出により、より正確なキーポイント検出が実現される
- 'q'キーを押すとプログラムが終了する
実験・探求のアイデア
YOLOv11モデル選択実験
プログラム冒頭のMODEL_NAMEを変更することで、異なるYOLOv11モデルを比較できる:
yolo11n-pose.pt
:Nano版(最高速、軽量、エッジデバイス最適)yolo11s-pose.pt
:Small版(高速、バランス型)yolo11m-pose.pt
:Medium版(汎用用途、精度重視)yolo11l-pose.pt
:Large版(高精度、高計算要求)yolo11x-pose.pt
:Extra Large版(最高精度、最大性能)
Enhanced Feature Extraction検証実験
YOLOv11の改良された特徴抽出能力を検証:
- 部分的遮蔽状況での検出性能
- 複雑な背景での人物検出精度
- 低照度環境での検出安定性
- 高速動作時のキーポイント追跡性能
検出閾値調整実験
CONF_THRESHOLDの値(0.0-1.0)を変更することで、検出感度を調整できる:
- 0.3:低信頼度のキーポイントも表示(ノイズ増加)
- 0.5:標準設定(バランス型)
- 0.7:高信頼度のキーポイントのみ表示(検出数減少)
体験・実験・探求のアイデア
精度と効率性の体験実験: 異なるYOLOv11モデル(n, s, m, l, x)で同じ動作を行い、Enhanced Feature ExtractionとOptimized Efficiencyの効果を実感する
環境適応性実験:
- 異なる解像度での検出性能変化
- CPU vs GPU環境での処理速度比較
高度なポーズ検出実験:
- スポーツ動作(ジャンプ、投球、キック)での精密検出
- ダンス動作での連続キーポイント追跡
- 座位、臥位など非標準姿勢での検出性能
- 部分的遮蔽(手で顔を覆う等)での復元能力
リアルタイム応用実験: YOLOv11の高速性を活用した応用アイデアの検証
複数人同時検出: 改良されたアーキテクチャによる複数人検出性能の向上を確認
建設現場安全監視シミュレーション: 危険姿勢(しゃがみ、前屈等)の自動検出実験