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 pillow
プログラムコード
概要
本プログラムは、YOLOv11を用いて動画から人体の姿勢をリアルタイムで推定するシステムである。Ultralyticsが提供するYOLOv11の姿勢推定モデル[1]を使用し、動画の各フレームから人体の17箇所のキーポイントを検出する。入力源として動画ファイル、ウェブカメラ、サンプル動画の3種類に対応し、検出結果をリアルタイムで可視化する。
主要技術
YOLOv11 (You Only Look Once version 11)
YOLOv11は、Ultralyticsが2024年に発表した物体検出・姿勢推定モデルである[1]。YOLOシリーズの最新版として、改良された特徴抽出機構と最適化された計算効率を実現している。本プログラムでは、yolo11n-pose.ptモデル(2.9Mパラメータ)を使用し、COCOデータセット[2]で定義された17個のキーポイント形式で人体姿勢を検出する。
COCO Keypoint形式
Microsoft COCOデータセット[2]で標準化された人体姿勢表現形式である。鼻、左右の目、耳、肩、肘、手首、腰、膝、足首の計17箇所を定義している。この形式は姿勢推定分野で広く採用されており、モデル間の互換性と評価の標準化を実現している。
技術的特徴
本実装では、以下の技術的工夫により実用的な姿勢推定システムを構築している:
- 信頼度閾値(CONF_THRESHOLD=0.5)によるキーポイントのフィルタリング機能。誤検出を抑制しながら、確実なキーポイントのみを表示
- PyTorchのdevice自動選択機能により、CUDA対応GPUが利用可能な場合は自動的にGPU処理を実行
- OpenCVのバッファサイズを1に設定することで、カメラ入力時の遅延を最小化
- 複数人物の同時検出に対応し、各人物のキーポイントを個別に処理
実装の特色
ユーザビリティと実用性を考慮した以下の機能を実装している:
- Pillowライブラリを使用した日本語表示機能。Windows環境ではメイリオフォントを使用してキーポイント名を日本語で表示
- tkinterによるGUIファイル選択ダイアログの実装。ユーザーが動画ファイルを直感的に選択可能
- 処理結果のテキストファイル保存機能。フレーム数、使用デバイス情報、検出結果をresult.txtに記録
- サンプル動画の自動ダウンロード機能。OpenCVの公式サンプル動画を使用した動作確認が可能
性能と制約
yolo11n-poseモデルは軽量版(nano)であり、2.9Mパラメータという小規模なモデルサイズでリアルタイム処理を実現している[1]。信頼度閾値は0.5に設定されており、この値を調整することで検出感度と精度のバランスを制御できる。低い閾値設定では検出数が増加するが、誤検出のリスクも上昇する。
参考文献
[1] Ultralytics. (2024). YOLOv11: Enhanced Feature Extraction and Optimized Efficiency. GitHub Repository. https://github.com/ultralytics/ultralytics
[2] Lin, T. Y., et al. (2014). Microsoft COCO: Common Objects in Context. European Conference on Computer Vision (ECCV), pp. 740-755. https://arxiv.org/abs/1405.0312
ソースコード
# プログラム名: YOLOv11姿勢推定プログラム
# 特徴技術名: YOLOv11 (You Only Look Once version 11)
# 出典: Ultralytics. (2024). YOLOv11: Enhanced Feature Extraction and Optimized Efficiency. https://github.com/ultralytics/ultralytics
# 特徴機能: Ultralyticsライブラリによる姿勢推定機能を利用
# 学習済みモデル: yolo11n-pose.pt(COCOデータセット17キーポイント学習済み、2.9Mパラメータ)URL: Ultralyticsライブラリが自動ダウンロード
# 方式設計:
# - 関連利用技術: OpenCV(画像処理・表示)、NumPy(数値計算)、Pillow(日本語フォント描画)、PyTorch(GPU/CPU自動選択)
# - 入力と出力: 入力: 動画(ユーザは「0:動画ファイル,1:カメラ,2:サンプル動画」のメニューで選択.0:動画ファイルの場合はtkinterでファイル選択.1の場合はOpenCVでカメラが開く.2の場合はhttps://raw.githubusercontent.com/opencv/opencv/master/samples/data/vtest.aviを使用)、出力: OpenCV画面でリアルタイム表示(検出された姿勢とキーポイント座標)、各フレームごとにprint()による処理結果表示、終了時にresult.txtファイルへ保存
# - 処理手順: 1.YOLOv11モデルロード、2.動画フレーム取得、3.Ultralyticsライブラリによる姿勢推定、4.17キーポイント検出、5.信頼度閾値によるフィルタリング、6.結果の可視化
# - 前処理、後処理: 前処理:適切なバックエンドによる低遅延フレーム取得、バッファサイズ1設定。後処理:信頼度0.5以上のキーポイントのみ表示、キーポイント名と座標の日本語フォント描画
# - 調整を必要とする設定値: CONF_THRESHOLD(キーポイント検出の信頼度閾値、デフォルト0.5、低くすると検出数増加but誤検出も増加)
# 将来方策: 検出されたキーポイント数の時系列変化を監視し、安定して検出されるキーポイントの割合からCONF_THRESHOLDを動的に調整する機能の実装
# その他の重要事項: クロスプラットフォーム対応、COCO形式17キーポイント(鼻、目、耳、肩、肘、手首、腰、膝、足首)
# 前準備: pip install ultralytics opencv-python pillow torch
import cv2
import numpy as np
from ultralytics import YOLO
import tkinter as tk
from tkinter import filedialog
import time
import urllib.request
from PIL import Image, ImageDraw, ImageFont
from datetime import datetime
import torch
# GPU/CPU自動選択
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f'デバイス: {str(device)}')
# 定数定義
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'
]
# 日本語キーポイント名称
KEYPOINT_NAMES_JP = [
'鼻', '左目', '右目', '左耳', '右耳',
'左肩', '右肩', '左肘', '右肘',
'左手首', '右手首', '左腰', '右腰',
'左膝', '右膝', '左足首', '右足首'
]
# キーポイント数定義と整合性チェック
NUM_KEYPOINTS = len(KEYPOINT_NAMES)
assert NUM_KEYPOINTS == len(KEYPOINT_NAMES_JP), "KEYPOINT_NAMESとKEYPOINT_NAMES_JPの長さが不一致である"
# プログラム開始時の説明
print('=== YOLOv11姿勢推定プログラム ===')
print('概要: YOLOv11を使用してリアルタイムで人体の17箇所のキーポイントを検出します')
print('検出部位: 鼻、目(左右)、耳(左右)、肩(左右)、肘(左右)、手首(左右)、腰(左右)、膝(左右)、足首(左右)')
print('')
# YOLOv11モデルのロード
print('YOLOv11モデルをロード中...')
model = YOLO(MODEL_NAME)
model.to(device)
print(f"モデル '{MODEL_NAME}' のロードが完了しました")
print('')
# フォント設定
FONT_PATH = 'C:/Windows/Fonts/meiryo.ttc'
FONT_SIZE = 16
try:
font = ImageFont.truetype(FONT_PATH, FONT_SIZE)
except:
font = ImageFont.load_default()
# 結果記録用
frame_count = 0
results_log = []
def draw_japanese_text(frame, text, position, font, color=(0, 255, 0)):
"""OpenCVの画像に日本語テキストを描画する関数"""
img_pil = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img_pil)
draw.text(position, text, font=font, fill=color)
return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
def video_frame_processing(frame):
global frame_count
current_time = time.time()
frame_count += 1
# YOLOv11による姿勢推定実行
result = model(frame)[0]
processed_frame = result.plot()
# キーポイント処理(複数人物対応)
keypoint_count = 0
person_count = 0
keypoints = result.keypoints
if keypoints is not None:
keypoints_data = keypoints.data.detach().cpu().numpy()
if keypoints_data.ndim == 3 and keypoints_data.shape[1] == NUM_KEYPOINTS:
# 人数を一括取得
person_count = int(keypoints_data.shape[0])
# 1フレームにつき1回だけBGR↔RGB変換してPILで描画
img_pil = Image.fromarray(cv2.cvtColor(processed_frame, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img_pil)
for person_idx in range(person_count):
for i in range(NUM_KEYPOINTS):
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_JP[i]}({x:.0f},{y:.0f})'
draw.text((int(x), int(y)), text, font=font, fill=(255, 255, 255))
keypoint_count += 1
processed_frame = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
# 結果の整形
if person_count > 0:
result_str = f'検出人数:{person_count}, キーポイント数:{keypoint_count}'
else:
result_str = '人物未検出'
return processed_frame, result_str, current_time
print("0: 動画ファイル")
print("1: カメラ")
print("2: サンプル動画")
choice = input("選択: ")
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)
if not cap.isOpened():
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
else:
# サンプル動画ダウンロード・処理
SAMPLE_URL = 'https://raw.githubusercontent.com/opencv/opencv/master/samples/data/vtest.avi'
SAMPLE_FILE = 'vtest.avi'
urllib.request.urlretrieve(SAMPLE_URL, SAMPLE_FILE)
cap = cv2.VideoCapture(SAMPLE_FILE)
if not cap.isOpened():
print('動画ファイル・カメラを開けませんでした')
exit()
# メイン処理
print('\n=== 動画処理開始 ===')
print('操作方法:')
print(' q キー: プログラム終了')
MAIN_FUNC_DESC = "YOLOv11姿勢推定"
try:
while True:
ret, frame = cap.read()
if not ret:
break
processed_frame, result_str, current_time = video_frame_processing(frame)
cv2.imshow(MAIN_FUNC_DESC, processed_frame)
if choice == '1': # カメラの場合
print(datetime.fromtimestamp(current_time).strftime("%Y-%m-%d %H:%M:%S.%f")[:-3], result_str)
else: # 動画ファイルの場合
print(frame_count, result_str)
results_log.append(result_str)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
finally:
print('\n=== プログラム終了 ===')
cap.release()
cv2.destroyAllWindows()
if results_log:
with open('result.txt', 'w', encoding='utf-8') as f:
f.write('=== 結果 ===\n')
f.write(f'処理フレーム数: {frame_count}\n')
f.write(f'使用デバイス: {str(device).upper()}\n')
if device.type == 'cuda':
f.write(f'GPU: {torch.cuda.get_device_name(0)}\n')
f.write('\n')
f.write('\n'.join(results_log))
print(f'\n処理結果をresult.txtに保存しました')
使用方法
- プログラムを実行すると、カメラが起動し、リアルタイムで姿勢推定が開始される
- カメラに向かって様々なポーズを取ると、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の高速性を活用した応用アイデアの検証
複数人同時検出: 改良されたアーキテクチャによる複数人検出性能の向上を確認
建設現場安全監視シミュレーション: 危険姿勢(しゃがみ、前屈等)の自動検出実験