YOLO11によるインスタンスセグメンテーション
【概要】YOLO11-segを使用してリアルタイムインスタンスセグメンテーションを実行。Enhanced Feature Extractionにより物体検出と同時にピクセルレベルのセグメンテーションを学習し、5種類のモデルサイズによる精度と速度の比較実験が可能。Windows環境での実行手順、プログラムコード、実験アイデアを含む。

目次
概要
技術名: YOLO11-seg(You Only Look Once version 11 - Instance Segmentation)
発表: 2024年、Ultralytics YOLO Vision 2024 (YV24) にて発表
新規性・特徴: YOLO11-segは、Enhanced Feature Extraction(強化された特徴抽出)を採用した最新のインスタンスセグメンテーション技術である。C3k2(Cross Stage Partial with kernel size 2:カーネルサイズ2のクロスステージ部分接続)ブロックによる効率的な特徴抽出、C2PSA(Convolutional block with Parallel Spatial Attention:並列空間アテンション付き畳み込みブロック)による空間アテンション機構、SPPF(Spatial Pyramid Pooling - Fast:高速空間ピラミッドプーリング)による多スケール特徴統合により、物体検出とピクセルレベルセグメンテーションを同時実行する。
技術革新:
- C3k2ブロック:2つの小さな畳み込みによる効率的なCSP Bottleneck(クロスステージ部分ボトルネック:異なる段階の特徴を部分的に接続する構造)実装、処理速度向上
- C2PSA:空間アテンション機構(画像内の重要な領域に注意を向ける仕組み)により重要な領域に焦点、小物体検出精度向上
- SPPF:異なるスケールでの特徴プーリング(複数の解像度で特徴を統合する手法)による多スケール物体検出能力向上
- 統合アーキテクチャ:物体検出とインスタンスセグメンテーションの効率的同時処理
アプリケーション例: 自動運転、医療画像解析、工業検査、ロボットビジョン、映像制作、リアルタイム映像解析、品質管理、セキュリティ監視
使用する学習済みモデル
YOLO11-seg事前学習済みモデル:
- 学習データセット: MS COCO 2017(80クラス物体検出+セグメンテーション)
- 検出可能物体: 人、車両、動物、家具、電子機器など80種類
- 出力形式: バウンディングボックス + ピクセルレベルセグメンテーションマスク
- 入力解像度: 640×640ピクセル(デフォルト)
- モデルサイズ: Nano版(軽量)からExtra Large版(高精度)まで5種類
- 技術特徴: C3k2ブロック、C2PSA空間アテンション、SPPF多スケール処理
事前準備
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 numpy pillow
YOLO11物体検出・インスタンスセグメンテーションプログラム
概要
このプログラムは動画やカメラからの情報を処理し、物体の検出・識別・セグメンテーションを行う。
主要技術
- YOLO11物体検出アルゴリズム [1]: C3k2ブロック、C2PSA空間アテンション、SPPF(空間ピラミッドプーリング高速化)を組み合わせた物体検出・インスタンスセグメンテーション技術である。
参考文献
- [1] Khanam, R., & Hussain, M. (2024). YOLOv11: An overview of the key architectural enhancements. arXiv preprint arXiv:2410.17725.
# YOLO11物体検出・インスタンスセグメンテーションプログラム
# 特徴技術名: YOLO11 (You Only Look Once version 11)
# 出典: G. Jocher and J. Qiu, "Ultralytics YOLO11," GitHub repository, 2024. [Online]. Available: https://github.com/ultralytics/ultralytics
# 特徴機能: C3k2ブロックによる効率的な特徴抽出(カーネルサイズ2の軽量CSPボトルネック構造により、計算効率と検出精度を両立)
# 学習済みモデル: yolo11n-seg.pt (COCOデータセット80クラス対応インスタンスセグメンテーションモデル、自動ダウンロード、Nano版で高速軽量、https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11n-seg.pt から自動取得)
# 方式設計
# - 関連利用技術:
# * OpenCV (コンピュータビジョンライブラリ、画像・動画処理、カメラ制御)
# * NumPy (数値計算ライブラリ、配列処理、データ操作)
# * Tkinter (GUIライブラリ、ファイル選択ダイアログ)
# * PIL/Pillow (画像処理ライブラリ、日本語テキスト描画)
# - 入力と出力:
# 入力: 動画(ユーザは「0:動画ファイル,1:カメラ,2:サンプル動画」のメニューで選択.0:動画ファイルの場合はtkinterでファイル選択.1の場合はOpenCVでカメラが開く.2の場合はhttps://github.com/opencv/opencv/blob/master/samples/data/vtest.aviを使用)
# 出力: 処理結果が画像化できる場合にはOpenCV画面でリアルタイムに表示.OpenCV画面内に処理結果をテキストで表示.さらに,1秒間隔で,print()で処理結果を表示.プログラム終了時にprint()で表示した処理結果をresult.txtファイルに保存し,「result.txtに保存」したことをprint()で表示.プログラム開始時に,プログラムの概要,ユーザが行う必要がある操作(もしあれば)をprint()で表示.
# - 処理手順:
# 1. 動画フレーム取得 2. YOLO11モデルによる推論実行 3. 検出結果とセグメンテーションマスクの描画 4. リアルタイム表示
# - 前処理、後処理:
# 前処理: フレームバッファクリア(最新フレーム取得)、画像正規化(YOLO11内部処理)
# 後処理: 検出結果可視化、信頼度フィルタリング、セグメンテーションマスク合成
# - 追加処理:
# * DirectShowバックエンド使用によるカメラ安定化
# * バッファサイズ=1設定による遅延最小化
# * 乱数シード設定による結果再現性確保
# - 調整を必要とする設定値: CONF_THRESHOLD (信頼度閾値、0.25、YOLO11公式推奨のデフォルト値、検出感度と精度のバランス調整)
# 将来方策: CONF_THRESHOLDの自動最適化機能実装(フレーム毎の検出数と信頼度分布を統計的に分析し、適合率と再現率のF値が最大となる閾値を動的に算出。実装方法:過去30フレームの検出結果を保持し、信頼度ヒストグラムから最適閾値を計算)
# その他の重要事項: Windows環境対応、AGPL-3.0ライセンス、リアルタイム処理特化
# 前準備:
# - pip install -U torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
# - pip install ultralytics opencv-python numpy pillow
import cv2
import tkinter as tk
from tkinter import filedialog
import os
import urllib.request
from ultralytics import YOLO
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import time
from collections import defaultdict
import torch
# 定数定義
MODEL_NAME = 'yolo11n-seg.pt' # 使用するYOLO11モデル
CONF_THRESHOLD = 0.25 # 物体検出の信頼度閾値(0.0-1.0)
RANDOM_SEED = 42 # 再現性確保用の乱数シード
FONT_PATH = 'C:/Windows/Fonts/msgothic.ttc' # 日本語フォントパス
FONT_SIZE = 24 # 日本語フォントサイズ
COLOR_GREEN = (0, 255, 0) # フレーム情報表示色(BGR)
COLOR_YELLOW = (0, 255, 255) # 検出情報表示色(BGR)
# 日本語クラス名マッピング(COCO 80クラス)
CLASS_NAMES_JP = {
'person': '人', 'bicycle': '自転車', 'car': '車', 'motorcycle': 'バイク',
'airplane': '飛行機', 'bus': 'バス', 'train': '電車', 'truck': 'トラック',
'boat': 'ボート', 'traffic light': '信号機', 'fire hydrant': '消火栓',
'stop sign': '停止標識', 'parking meter': 'パーキングメーター', 'bench': 'ベンチ',
'bird': '鳥', 'cat': '猫', 'dog': '犬', 'horse': '馬', 'sheep': '羊',
'cow': '牛', 'elephant': '象', 'bear': '熊', 'zebra': 'シマウマ', 'giraffe': 'キリン',
'backpack': 'リュック', 'umbrella': '傘', 'handbag': 'ハンドバッグ', 'tie': 'ネクタイ',
'suitcase': 'スーツケース', 'frisbee': 'フリスビー', 'skis': 'スキー板',
'snowboard': 'スノーボード', 'sports ball': 'ボール', 'kite': '凧',
'baseball bat': 'バット', 'baseball glove': 'グローブ', 'skateboard': 'スケートボード',
'surfboard': 'サーフボード', 'tennis racket': 'テニスラケット', 'bottle': 'ボトル',
'wine glass': 'ワイングラス', 'cup': 'カップ', 'fork': 'フォーク', 'knife': 'ナイフ',
'spoon': 'スプーン', 'bowl': 'ボウル', 'banana': 'バナナ', 'apple': 'リンゴ',
'sandwich': 'サンドイッチ', 'orange': 'オレンジ', 'broccoli': 'ブロッコリー',
'carrot': 'ニンジン', 'hot dog': 'ホットドッグ', 'pizza': 'ピザ', 'donut': 'ドーナツ',
'cake': 'ケーキ', 'chair': '椅子', 'couch': 'ソファ', 'potted plant': '鉢植え',
'bed': 'ベッド', 'dining table': 'テーブル', 'toilet': 'トイレ', 'tv': 'テレビ',
'laptop': 'ノートPC', 'mouse': 'マウス', 'remote': 'リモコン', 'keyboard': 'キーボード',
'cell phone': '携帯電話', 'microwave': '電子レンジ', 'oven': 'オーブン',
'toaster': 'トースター', 'sink': 'シンク', 'refrigerator': '冷蔵庫',
'book': '本', 'clock': '時計', 'vase': '花瓶', 'scissors': 'ハサミ',
'teddy bear': 'ぬいぐるみ', 'hair drier': 'ドライヤー', 'toothbrush': '歯ブラシ'
}
def video_processing(frame, model, font, log_data):
"""動画フレームの処理"""
current_time = time.time()
log_data['frame_count'] += 1
# YOLO推論実行
results = model(frame, conf=CONF_THRESHOLD)
annotated_frame = results[0].plot()
# 検出情報収集
detection_info = {'objects': defaultdict(int), 'total': 0}
result = results[0]
if hasattr(result, 'boxes') and result.boxes is not None:
detection_info['total'] = len(result.boxes)
for box in result.boxes:
if hasattr(box, 'cls'):
cls_id = int(box.cls)
if cls_id < len(model.names):
class_name = model.names[cls_id]
detection_info['objects'][class_name] += 1
# 日本語で検出情報表示
if font and detection_info['total'] > 0:
img_pil = Image.fromarray(cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img_pil)
# 検出物体数表示
draw.text((10, 60), f'検出物体数: {detection_info["total"]}', font=font, fill=COLOR_YELLOW)
# クラス別検出数表示
y_offset = 90
for class_name, count in detection_info['objects'].items():
jp_name = CLASS_NAMES_JP.get(class_name, class_name)
draw.text((10, y_offset), f'{jp_name}: {count}個', font=font, fill=COLOR_YELLOW)
y_offset += 30
annotated_frame = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
# フレーム情報表示(英数字)
cv2.putText(annotated_frame, f'Frame: {log_data["frame_count"]} | GPU: {model.device}',
(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, COLOR_GREEN, 2)
# 1秒間隔での処理結果表示
if current_time - log_data['last_print'] >= 1.0:
elapsed = current_time - log_data['start_time']
fps = log_data['frame_count'] / elapsed if elapsed > 0 else 0
log_entry = f'[{elapsed:.1f}秒] フレーム: {log_data["frame_count"]}, FPS: {fps:.1f}, 検出物体数: {detection_info["total"]}'
if detection_info['objects']:
jp_names = [f'{CLASS_NAMES_JP.get(k, k)}:{v}' for k, v in detection_info['objects'].items()]
log_entry += ', 内訳: ' + ', '.join(jp_names)
print(log_entry)
log_data['log_entries'].append(log_entry)
log_data['last_print'] = current_time
return annotated_frame
# プログラム開始
print('=' * 60)
print('YOLO11物体検出・インスタンスセグメンテーションプログラム')
print('=' * 60)
print('概要:')
print(' - YOLO11モデルを使用したリアルタイム物体検出')
print(' - C3k2ブロックによる高効率な特徴抽出')
print(' - インスタンスセグメンテーション対応')
print(' - 80クラスの物体検出(COCOデータセット)')
print('')
print('操作方法:')
print(' - 動画再生中: Qキーで終了')
print(' - 検出結果は1秒間隔でコンソールに表示')
print(' - 終了時に検出履歴をresult.txtに保存')
print('=' * 60)
print('')
# 乱数シード設定
np.random.seed(RANDOM_SEED)
torch.manual_seed(RANDOM_SEED)
# GPU/CPU自動選択とモデル読み込み
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(f'使用デバイス: {device}')
print(f'YOLO11モデル {MODEL_NAME} をロード中...')
model = YOLO(MODEL_NAME)
model.to(device)
print(f'モデルのロードが完了しました')
print('')
# 日本語フォント読み込み
try:
font = ImageFont.truetype(FONT_PATH, FONT_SIZE)
except:
font = None
print('日本語フォントの読み込みに失敗しました。英語表示になります。')
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:
urllib.request.urlretrieve(url, filename)
temp_file = filename
cap = cv2.VideoCapture(filename)
except Exception as e:
print(f'動画のダウンロードに失敗しました: {url}')
print(f'エラー: {e}')
exit()
else:
print('無効な選択です')
exit()
# ログデータ初期化
log_data = {
'start_time': time.time(),
'last_print': time.time(),
'frame_count': 0,
'log_entries': []
}
# メイン処理
try:
while True:
cap.grab()
ret, frame = cap.retrieve()
if not ret:
break
processed_frame = video_processing(frame, model, font, log_data)
cv2.imshow('Video', processed_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
finally:
cap.release()
cv2.destroyAllWindows()
if temp_file:
os.remove(temp_file)
# 結果保存
if log_data['log_entries']:
with open('result.txt', 'w', encoding='utf-8') as f:
f.write('YOLO11物体検出・インスタンスセグメンテーション実行結果\n')
f.write('=' * 60 + '\n')
f.write(f'使用デバイス: {device}\n')
f.write(f'総フレーム数: {log_data["frame_count"]}\n')
elapsed = time.time() - log_data['start_time']
f.write(f'実行時間: {elapsed:.1f}秒\n')
f.write(f'平均FPS: {log_data["frame_count"] / elapsed:.1f}\n')
f.write('=' * 60 + '\n')
f.write('検出履歴:\n')
for entry in log_data['log_entries']:
f.write(entry + '\n')
print('')
print('result.txtに保存しました')
使用方法
- プログラムを実行すると、カメラが起動し、リアルタイムでインスタンスセグメンテーションが開始される
- カメラに向かって様々な物体を映すと、物体検出と同時にピクセルレベルのセグメンテーションが表示される
- 検出された各物体にはクラス名、信頼度、セグメンテーションマスクが表示される
- YOLO11のC2PSA並列空間アテンション機構により、複雑な背景や重複物体においてもセグメンテーション精度が向上する
- フレーム情報でEnhanced Feature Extractionとセグメンテーションの動作状況を確認できる
- 'q'キーを押すとプログラムが終了する
実験・探求のアイデア
YOLO11-segモデル選択実験
プログラム冒頭のMODEL_NAMEを変更することで、異なるYOLO11-segモデルを比較できる:
yolo11n-seg.pt
:Nano版(最高効率、エッジデバイス最適)yolo11s-seg.pt
:Small版(バランス型、実用性重視)yolo11m-seg.pt
:Medium版(汎用用途、精度向上)yolo11l-seg.pt
:Large版(高精度重視、計算コスト増)yolo11x-seg.pt
:Extra Large版(最高性能、最大計算要求)
空間アテンション機構の検証実験
C2PSAの並列空間アテンション効果を定量的に評価:
- 小物体検出:C2PSAによる小さな物体の検出精度向上の測定
- 重複物体分離:密集環境でのインスタンス分離能力の評価
- 部分遮蔽対応:遮蔽された物体のセグメンテーション復元性能
- 複雑背景処理:背景が複雑な環境での物体境界検出精度
体験・実験・探求のアイデア
アーキテクチャ改良効果の測定: C3k2とC2PSAの技術革新により、従来困難であった複雑シーンでの性能向上を定量的に測定
リアルタイム応用実験:
- 自動運転シミュレーション:車両、歩行者、道路標識の精密セグメンテーション
- 医療画像解析:X線、MRI画像での病変部位セグメンテーション
- 工業検査:製品の欠陥部位自動検出とセグメンテーション
- 映像制作:リアルタイム背景除去と合成
多スケール検出能力の実験: SPPFによる異なるサイズの物体同時検出性能を評価