0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

YOLO11で物体検出

Last updated at Posted at 2025-01-30

環境

  • Windows11
  • CPU

1. uvで環境構築

powershellでuvをインストール

powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

powershell再起動後,インストールできているか確認

uv --version

新規フォルダを作成(my-projectは任意の名前)

mkdir my-project

my-projectに移動

cd my-project

仮想環境作成(my-project-venvは任意の名前)

uv venv my-project-venv -p 3.12

仮想環境のアクティベート

my-project-venv/Scripts/activate

アクティベートできていれば,以下のようになっている

(my-project-venv) C:\Users\[USER]\my-project>

公式サイトの通りPyTorch, Torchvision, Torchaudioをインストール(先頭にuvをつける)
cpuを使うなら,以下をそのまま実行

uv pip install torch torchvision torchaudio

ultralyticsをインストール

uv pip install ultralytics

labelImgをインストール

uv pip install labelimg

2. labelImgでアノテーション

エラー原因の修正

このままlabelImgを実行するとエラーが発生するので,事前に修正する

C:\Users\[USER]\my-project\my-project-env\Lib\site-packages\labelImg\labelImg.py
のプログラムファイルをテキストエディタで開く

965行目を以下のように修正

- bar.setValue(bar.value() + bar.singleStep() * units)
+ bar.setValue(int(bar.value() + bar.singleStep() * units))

971行目を以下のように修正

- self.zoom_widget.setValue(value) 
+ self.zoom_widget.setValue(int(value)) 

1025, 1026行目を以下のように修正

- h_bar.setValue(new_h_bar_value) 
- v_bar.setValue(new_v_bar_value) 
+ h_bar.setValue(int(new_h_bar_value)) 
+ v_bar.setValue(int(new_v_bar_value)) 

C:\Users\[USER]\my-project\my-project-env\Lib\site-packages\libs\canvas.py
のプログラムファイルをテキストエディタで開く

526行目を以下のように修正

- p.drawRect(left_top.x(), left_top.y(), rect_width, rect_height)
+ p.drawRect(int(left_top.x()), int(left_top.y()), int(rect_width), int(rect_height))

530行目, 531行目を以下のように修正

- p.drawLine(self.prev_point.x(), 0, self.prev_point.x(), self.pixmap.height())
- p.drawLine(0, self.prev_point.y(), self.pixmap.width(), self.prev_point.y())
+ p.drawLine(int(self.prev_point.x()), 0, int(self.prev_point.x()), self.pixmap.height())
+ p.drawLine(0, int(self.prev_point.y()), self.pixmap.width(), int(self.prev_point.y()))

参考元:

アノテーション準備

detectionフォルダを作成(省略可)

mkdir detection

all_imagesフォルダとall_labelsフォルダを作成

mkdir detection/all_images
mkdir detection/all_labels

all_imagesフォルダにアノテーションしたい画像を入れてください

アノテーション

labelImgを起動

labelimg
  1. 画面左上から2番目のOpen Dirを押し,all_imagesフォルダを選択。画像が表示される
  2. 画面左上から3番目のChange Save Dirを押し,all_labelsフォルダを選択
  3. 画面左上から8番目の表示がYOLOになるまでクリック
  4. 画面左上にあるViewを押し,Auto Save modeをクリック
  5. 表示された画像を右クリックし,Create RectBoxを選択
  6. クリック&ホールドで,検出対象を囲むように長方形を描く
  7. ホールド解除すると,ラベル名を入力するポップアップが出るので,入力する
  8. 画面左上から4番目のNext Imageを押す
  9. 6.から8.を繰り返してアノテーションを行う
  10. Next Imageを押しても次の画像が表示されなくなったら終了,画面右上の×で閉じる

image.png

3. YOLO11で物体検出

データセットの作成

detectionフォルダに移動して,CreateDataset.pyを作成する

cd detection
ni CreateDataset.py

CreateDataset.pyをテキストエディタで開き,以下のコードを貼り付けて保存する

1画像につき1ラベルの場合

image_formattest_ratioは自由に調整してください

CreateDataset.py
import os
import shutil
from sklearn.model_selection import train_test_split
from glob import glob

DATASET_PATH = 'datasets'
IMAGE_PATH = os.path.join(DATASET_PATH, 'images')
LABEL_PATH = os.path.join(DATASET_PATH, 'labels')
IMAGE_TRAIN_PATH = os.path.join(IMAGE_PATH, 'train')
LABEL_TRAIN_PATH = os.path.join(LABEL_PATH, 'train')
IMAGE_VAL_PATH = os.path.join(IMAGE_PATH, 'val')
LABEL_VAL_PATH = os.path.join(LABEL_PATH, 'val')

ALL_IMAGES_PATH = 'all_images'
ALL_LABELS_PATH = 'all_labels'

# データセットフォルダの作成
os.makedirs(IMAGE_TRAIN_PATH, exist_ok=True)
os.makedirs(LABEL_TRAIN_PATH, exist_ok=True)
os.makedirs(IMAGE_VAL_PATH, exist_ok=True)
os.makedirs(LABEL_VAL_PATH, exist_ok=True)

# ラベルのクラス名を取得
with open(os.path.join(ALL_LABELS_PATH, 'classes.txt'), 'r') as f:
    classes = f.read().splitlines()

# 画像とラベルを訓練データと検証データに分割
import os
import shutil
from sklearn.model_selection import train_test_split
from glob import glob

DATASET_PATH = 'datasets'
IMAGE_PATH = os.path.join(DATASET_PATH, 'images')
LABEL_PATH = os.path.join(DATASET_PATH, 'labels')
IMAGE_TRAIN_PATH = os.path.join(IMAGE_PATH, 'train')
LABEL_TRAIN_PATH = os.path.join(LABEL_PATH, 'train')
IMAGE_VAL_PATH = os.path.join(IMAGE_PATH, 'val')
LABEL_VAL_PATH = os.path.join(LABEL_PATH, 'val')

ALL_IMAGES_PATH = 'all_images'
ALL_LABELS_PATH = 'all_labels'

# データセットフォルダの作成
os.makedirs(IMAGE_TRAIN_PATH, exist_ok=True)
os.makedirs(LABEL_TRAIN_PATH, exist_ok=True)
os.makedirs(IMAGE_VAL_PATH, exist_ok=True)
os.makedirs(LABEL_VAL_PATH, exist_ok=True)

# ラベルのクラス名を取得
with open(os.path.join(ALL_LABELS_PATH, 'classes.txt'), 'r') as f:
    classes = f.read().splitlines()

# 画像とラベルを訓練データと検証データに分割
def split_dataset(image_format='.jpg', test_ratio=0.2):
    images = []
    labels = []
    label_indices = []

    for image in os.listdir(ALL_IMAGES_PATH):
        if not image.endswith(image_format):
            continue         
        image_name = image.replace(image_format, '')
        label = f'{image_name}.txt'
        with open(os.path.join(ALL_LABELS_PATH, label), 'r') as f:
            content = f.read()
            label_index = content[0]
        
        images.append(image)
        labels.append(label)
        label_indices.append(label_index)
    
    print(f'images:\n{images}')
    print(f'labels:\n{labels}')
    print(f'label_indices:\n{label_indices}')

    train_images, val_images, train_labels, val_labels = train_test_split(images, labels, test_size=test_ratio, stratify=label_indices)

    for image, label in zip(train_images, train_labels):
        image_path = os.path.join(ALL_IMAGES_PATH, image)
        label_path = os.path.join(ALL_LABELS_PATH, label)

        shutil.copy2(image_path, os.path.join(IMAGE_TRAIN_PATH, image))
        shutil.copy2(label_path, os.path.join(LABEL_TRAIN_PATH, label))
    
    for image, label in zip(val_images, val_labels):
        image_path = os.path.join(ALL_IMAGES_PATH, image)
        label_path = os.path.join(ALL_LABELS_PATH, label)

        shutil.copy2(image_path, os.path.join(IMAGE_VAL_PATH, image))
        shutil.copy2(label_path, os.path.join(LABEL_VAL_PATH, label))
    
    print(f'Train images: {len(train_images)}, Val images: {len(val_images)}')

def create_yaml(classes):
    path = DATASET_PATH
    train = IMAGE_TRAIN_PATH.replace(DATASET_PATH + '\\', '').replace('\\', '/')
    val = IMAGE_VAL_PATH.replace(DATASET_PATH + '\\', '').replace('\\', '/')

    with open('dataset.yaml', 'w') as f:
        f.write('# Path\n')
        f.write(f'path: ./{path}\n')
        f.write(f'train: {train}\n')
        f.write(f'val: {val}\n')
        f.write('\n')
        f.write('# Classes\n')
        f.write(f'nc: {len(classes)}\n')
        f.write(f'names: {classes}')

if __name__ == '__main__':
    split_dataset(image_format='.jpg', test_ratio=0.2)
    create_yaml(classes)

1画像につき複数ラベルの場合

工事中

実行前に,必要なパッケージをインストールする

uv pip install scikit-learn

以下を実行し,データセットを作成する

python CreateDataset.py
エラーが発生した場合

画像の数が少ない場合,以下のエラーが発生します。画像を増やしてください

ValueError: The least populated class in y has only 1 member, which is too few. The minimum number of groups for any class cannot be less than 2.

モデルの学習

TrainModel.pyを作成する

ni TrainModel.py

TrainModel.pyをテキストエディタで開き,以下のコードを貼り付けて保存する

TrainModel.py
from ultralytics import YOLO

if __name__ == "__main__":
    model = YOLO('yolo11n.pt')
    model.train(data="dataset.yaml", epochs=100, batch=8)

yolo11n.ptnはモデルサイズを表します。他のサイズは公式サイトに載っています

以下を実行し,モデルを学習させる

python TrainModel.py

学習完了後,runs/detect/trainを確認する。weights/best.ptが学習済みのモデルです

エラーが発生した場合

以前にUltralyticsをインストールしていた場合,以下のエラーが出るかもしれません

raise RuntimeError(emojis(f"Dataset '{clean_url(self.args.data)}' error ❌ {e}")) from e
RuntimeError: Dataset 'dataset.yaml' error
Dataset 'dataset.yaml' images not found , missing path 'C:\images\val'
Note dataset download directory is '何か'. You can update this in 'C:\Users\[USER]\AppData\Roaming\Ultralytics\settings.json'

以下を実行すれば解決します

yolo settings datasets_dir='.'

モデルの推論

学習させたモデルを使って推論を行う

Predict.pyを作成する

ni Predict.py

Predict.pyをテキストエディタで開き,以下のコードを貼り付ける

Predict.py
from ultralytics import YOLO

if __name__ == "__main__":
    image_path = 'test.jpg'
    save_path = 'result.jpg'

    model = YOLO('./runs/detect/train/weights/best.pt')
    results = model(image_path, save=False)
    results[0].save(save_path)

image_pathsave_pathはすきなように設定してください

以下を実行し,推論を行う

python Predict.py

以上

未記入部分あり

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?