環境
- 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
- 画面左上から2番目の
Open Dir
を押し,all_images
フォルダを選択。画像が表示される - 画面左上から3番目の
Change Save Dir
を押し,all_labels
フォルダを選択 - 画面左上から8番目の表示が
YOLO
になるまでクリック - 画面左上にある
View
を押し,Auto Save mode
をクリック - 表示された画像を右クリックし,
Create RectBox
を選択 - クリック&ホールドで,検出対象を囲むように長方形を描く
- ホールド解除すると,ラベル名を入力するポップアップが出るので,入力する
- 画面左上から4番目の
Next Image
を押す -
6.
から8.
を繰り返してアノテーションを行う -
Next Image
を押しても次の画像が表示されなくなったら終了,画面右上の×
で閉じる
3. YOLO11で物体検出
データセットの作成
detection
フォルダに移動して,CreateDataset.py
を作成する
cd detection
ni CreateDataset.py
CreateDataset.py
をテキストエディタで開き,以下のコードを貼り付けて保存する
1画像につき1ラベルの場合
image_format
とtest_ratio
は自由に調整してください
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
をテキストエディタで開き,以下のコードを貼り付けて保存する
from ultralytics import YOLO
if __name__ == "__main__":
model = YOLO('yolo11n.pt')
model.train(data="dataset.yaml", epochs=100, batch=8)
yolo11n.pt
のn
はモデルサイズを表します。他のサイズは公式サイトに載っています
以下を実行し,モデルを学習させる
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
をテキストエディタで開き,以下のコードを貼り付ける
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_path
やsave_path
はすきなように設定してください
以下を実行し,推論を行う
python Predict.py
以上
未記入部分あり