前回の記事では、YOLOv8を用いて物体検出を行いました。今回は YOLOv8-segモデル を用いて、検出した物体を画像から切り抜く方法を紹介します。
YOLOv8-segを利用することで、物体検出だけでなく、物体の輪郭情報を利用した画像処理が可能になります。
使用した環境
OS: Ubuntu 22.04
言語: Python 3
YOLOモデルの種類: YOLOv8-seg
必要なパッケージのインストール
YOLOv8を使用するために必要なパッケージをインストールします。
インストール方法については、以下の記事を参考にしてください。
<https://rtc-fukushima.jp/technical/7489/>
YOLOモデルの種類
YOLOは物体検出に用いられるアルゴリズムの一つで、画像内の物体を高速に検出することができます。YOLOには用途の異なる複数のモデルが存在し、目的に応じて適切なモデルを選択して使用します。YOLOv8-segは物体検出に加えてセグメンテーションマスク(物体の輪郭)を取得でき、検出した物体のみを切り抜くことができます。
| モデル |
主なタスク |
用途 |
| YOLOv8 |
物体検出 |
画像内の物体を矩形(Bounding Box)で囲んで検出するタスク。自動運転での歩行者・車両検知などに使用される。 |
| YOLOv8-seg |
インスタンスセグメンテーション |
物体を四角い枠だけでなく、輪郭を正確に切り抜くタスク。背景と物体を綺麗に分離したい場合(画像編集や医療画像解析など)に使用される。 |
| YOLOv8-pose |
姿勢推定 |
人間の関節位置や特定の特徴点(キーポイント)を推定するタスク。ジェスチャー認識などに使用される。 |
| YOLOv8-obb |
物体の向きを考慮した検出 |
斜めに傾いた物体に対して、傾きに合わせた矩形で検出するタスク。真上から撮影した航空写真(人工衛星画像)や文書画像の検出に使用される。 |
| YOLOv8-cls |
画像分類 |
画像全体を1つのカテゴリに分類するタスク(位置は特定しない)。製品検査や動物分類などに使用される。 |
サンプルプログラム
以下のサンプルプログラムは、YOLOv8-segを用いて画像内の物体を検出し、検出した物体を切り抜いて保存するプログラムです。指定した画像を読み込み、YOLOv8-segによって検出された物体ごとに画像を生成し保存します。
from ultralytics import YOLO
import cv2
import numpy as np
from ultralytics import YOLO
# モデルの読み込み(自動的にダウンロードされます)
model = YOLO("yolov8n-seg.pt")
# 画像の読み込み
img = cv2.imread("test.png")
# 物体検出の実行
results = model(img)
for result in results:
if result.masks is None:
continue
# マスクのデータ、クラスID、を取得
for i,(mask, cls) in enumerate(zip(result.masks.data, result.boxes.cls),start=1):
# クラスIDを整数に変換
class_id = int(cls.item())
# 条件分岐:車(2) 以外はスキップする
#if class_id != 2:
# continue
# 切り出し処理
mask = mask.cpu().numpy()
mask = cv2.resize(mask, (img.shape[1], img.shape[0]))
alpha = (mask * 255).astype(np.uint8)
b, g, r = cv2.split(img)
# 背景を透明にして物体を切り取る
img_result = cv2.merge([b, g, r, alpha])
# 結果をファイルに保存
cv2.imwrite(f"result_{i}.png",img_result)
図 1 テスト画像(OpenAI「ChatGPT」により作成)
サンプルプログラムの実行
サンプルプログラムを yolov8seg_test.py、テスト画像を test.png のファイル名でホームディレクトリに保存します。
その後、ホームディレクトリで以下のコマンドを実行します。
python3 yolov8seg_test.py
初回実行時は、モデルの読み込みに時間がかかります。指定したモデル(ここではyolov8n-seg.pt)がプログラムと同じディレクトリに存在しない場合は、自動的にダウンロードされます。
プログラムを実行すると、画像内の物体を検出し、検出した物体ごとに切り抜いた画像が保存されます。
今回のサンプルプログラムでは、検出したすべての物体を対象として画像を保存します。
python3 yolov8seg_test.py
0: 448x640 2 persons, 1 car, 566.1ms
Speed: 15.6ms preprocess, 566.1ms inference, 54.4ms postprocess per image at shape (1, 3, 448, 640)
図 2 検出した物体の切り抜きの結果(左および中央:人物, 右:車)
保存された画像(result_1.png、result_2.png、result_3.png)を確認すると、人物を切り抜いた画像が2枚、車を切り抜いた画像が1枚生成されています。今回のテスト画像では、人が車の近くに立っている影響で車と地面の境界が不明瞭となり、車の検出結果に地面の一部が含まれました。このように、物体同士が近接している場合や境界が不明瞭な場合には、物体を正確に切り抜けないことがあります。
一方、以下の画像のように人と車が十分に離れており、境界が明確な場合には、より高精度に物体を切り抜くことができます。
図 3 車の切り抜きの例(左:元画像(OpenAI「ChatGPT」により生成), 右:切り抜き画像)
切り抜く対象を選択したい場合
上記のサンプルプログラムは、認識したすべての物体を切り抜いて保存します。
特定の物体だけを切り抜きたい場合は、以下のコメントアウトを削除します。
# 条件分岐:車(2) 以外はスキップする
if class_id != 2:
continue
例えば、上記のように設定すると、クラスIDが 2(車) の物体のみが保存対象となります。
また、クラスIDを 0 に変更すると人物のみを切り抜くことができます。
if class_id != 0:
continue
このように条件分岐を追加することで、必要な物体のみを切り抜いて保存することができます。
本記事では、YOLOv8-segを用いて画像内の物体を検出し、検出した物体を保存する方法を紹介しました。
YOLOv8-segを利用することで、物体検出に加えて、輪郭情報を活用した画像処理が可能となります。人物や車など特定の物体だけを抽出したい場合や、画像解析の前処理として活用できます。
今後、YOLOを用いた画像処理を行いたい方の参考になれば幸いです。