【AI】YOLOv8をpython openCVでちゃちゃっと物体検出してみる

![__YOLO v8__をpython openCVでちゃちゃっと動かしてみる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832106/4bce6aff-53c8-9736-1b0f-b9706ecbbe1e.png)
## YOLOv8を自分のコードで使ってみたい
タイトルの通り数あるYOLOモデルの最新バージョンであるv8をちゃちゃっと使ってみたかったのですが、記事を書いてる皆さんのレベルが高すぎて自分が理解できなかったり、わかりやすそうな記事が有料だったり、そもそも新しすぎて情報が出きってなかったりしてました。頑張って解読してちゃちゃっと物体検出ができるチュートリアルを書いてみます。
YOLOv8についての説明はもういいですよね？```2023年6月時点のつよつよはやはやお手軽物体検出ライブラリ```です。ちゃちゃっと行きます。

## 前提
- pythonを実行できる環境
- pipが入っている
- YOLO v8は下記YOLOと書きます。
- これを目指します。↓
![image0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832106/ca6eb71e-2503-5a77-19a0-0a0b83eec15e.jpeg)

## まずは学習モデルをダウンロードする。
公式が出してる学習モデルのファイル名は```yolov8*.pt```です。*yolov8*の後に続く接尾辞で検出精度や得意不得意が変わります。
リンクが切れてなければ公式gitHub下のちゃちゃっと動かせるモデルの直リン↓
https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt
または公式ドキュメントからを開いてお好きなモデルをダウンロード
[ultralytics YOLOv8 Docs](https://docs.ultralytics.com/models/yolov8/#supported-tasks)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832106/095e0e3a-34ac-f29e-2fa9-335f5b5ba268.png)

## 実行準備
新しいフォルダにダウンロードしたモデルファイル(YOLOv8*.pt)と物体検出させたい画像ファイルをぶち込み、```yolo-test.py```を作成。インプットする画像の用意が無ければ下記の画像を```bus.jpg```で保存してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832106/5efb9fe7-6b46-d67f-a107-bb1dc995bae6.png)
<img width="200" alt="bus.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832106/f40eaa78-e97e-2788-2c72-6fd92227cc63.jpeg">

## インストール
**YOLO**と**openCV**をインストールします。openCVは無くても検出だけなら出来ますが入力する画像をごにょごにょしてYOLOで検出したり、検出された画像をopenCVでごにょごにょしたりすると思うのでopenCVを使うことを想定して書きます。(PILでも可能です。)
```
pip install ultralytics
pip install opencv-python
```

## 実行
このまま```yolo-test.py```に下記のコードを記述します。
```python:yolo-test.py
from ultralytics import YOLO
import cv2

# モデル読み込み
model = YOLO("yolov8n.pt")

# 入力画像
results = model('bus.jpg',save=True) 
```
modelの```yolov8n.pt```と```bus.jpg```はご自身の環境に合わせて変更してください。
実行すると```run\detect\predict```というフォルダが生成され、入力されたファイル名と同じファイル名でラベルが上書きされた画像が出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832106/3e17ef18-be17-9c70-0712-ae2ecfd28ee4.png)

```model('bus.jpg',save=True) ```の第2引数以降は下記の通りに指定することができます。
| 引数           | デフォルト | 内容                          |
|--------------|---------|-------------------------------|
| save         | False   | 推論画像を保存                 |
| show         | False   | 推論画像を表示                 |
| save_txt     | False   | 結果をテキストファイルに保存   |
| save_conf    | False   | スコアをテキストファイルに保存 |
| save_crop    | False   | 検出された画像をクロップ        |
| hide_labels  | False   | ラベルを非表示にする            |
| hide_conf    | False   | スコアを非表示にする            |
| vid_stride   | False   | 動画のフレームレートのストライド |
| line_thickness | 3       | バウンディングボックスの太さ     |
| visualize    | False   | モデルの特徴を視覚化            |
| augment      | False   | 拡張推論                      |
| agnostic_nms | False   | クラスに依存しないNMS           |
| retina_masks | False   | 高解像度マスク（セグメンテーション時） |


## 出力
次は試しに今作っているサービスの画像を使って且つ```save_text=true```と```save_conf=True```を追加してみます。クマ自体はstable diffutionに付け加えてもらいました。
```python:yolo-test.py
from ultralytics import YOLO
import cv2

# モデル読み込み
model = YOLO("yolov8n.pt")

# 入力画像
results = model('bear.png', save=True, save_txt=True, save_conf=True) 
```
![bear.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832106/dce429ff-d6b3-b882-2880-acb6f4ef89e6.png)
2回目以降の実行は```runs\detect\predict2```というように*predict*の後に数字がされる形で出力フォルダが増えていきます。
今回はこれに加えて*labels*というフォルダも生成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832106/25dfef80-e79d-7a42-94fb-e4d0319965fc.png)
中を見るとスペース区切りで数字が羅列されているテキストファイルが入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832106/6f7f286d-c884-d504-2cd9-78fbdefedccb.png)
読み方は以下の通りです。

:::note info
読み方
1番目がクラスID(検出された物体)
2番目が検出された物体を囲む矩形の左上のx座標
3番目が　　　　　　〃　　　　　　左上のy座標
4番目が　　　　　　〃　　　　　　右下のx座標
5番目が　　　　　　〃　　　　　　右下のy座標
最後が検出の精度です。
:::
クラスIDは使用するモデルにより異なると思いますが、yolov8nの場合下記の様に特定の物体に紐づいています。今回の画像ではクラスIDが```21```となっているので下記のリストと照らし合わせて```熊```が```93%```の精度で検出されたと分かりますね。
| クラスID | クラス名           | 日本語名           |
|----------|--------------------|--------------------|
| 0        | person             | 人                 |
| 1        | bicycle            | 自転車             |
| 2        | car                | 車                 |
| 3        | motorcycle         | バイク             |
| 4        | airplane           | 飛行機             |
| 5        | bus                | バス               |
| ⋮        | ⋮               | ⋮             |
| 21        | baer                | 熊               |
| ⋮        | ⋮               | ⋮             |
| 79       | toothbrush         | 歯ブラシ           |

他のIDも知りたい場合は下記の記事を参照してください。

https://qiita.com/napspans/items/e7390280b7f31675325c

## 動画
パスを.mp4などの動画を指定すれば簡単に検出してくれます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">YOLOv8すごーい<br>悩んだけど、実行簡単 <a href="https://t.co/dtXByakHmK">pic.twitter.com/dtXByakHmK</a></p>&mdash; Tsubasa (@napspans) <a href="https://twitter.com/napspans/status/1671464196670906368?ref_src=twsrc%5Etfw">June 21, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## まとめ
ここまで実行できればYOLOv8の入門は出来たのではないでしょうか。
他のモデルを使ったり、学習させてみるのもできれば面白そうですね。
お疲れ様でした。ではまた。

## 参考文献
https://docs.ultralytics.com/

https://zenn.dev/opamp/articles/51ee26445a1732

https://qiita.com/Nya-ku/items/ad07872260cfe8abd322

https://tt-tsukumochi.com/archives/6303