YOLOv5 (https://github.com/ultralytics/yolov5) はオープンソースの物体検出のためのアーキテクチャで,COCO dataset (https://cocodataset.org/) に基づいた学習済みモデルも含まれています.ここでは Python で YOLOv5 を使った物体検出を行ってみよう.
YOLOv5 を利用するには,torch をはじめ様々なライブラリをインストールしなければなりません.Anaconda の base 環境にライブラリをインストールしても良いですが,バージョンの不一致などトラブルに見舞われる可能性もあります.したがってここでは YOLOv5 用の Python 仮想環境を構築して,その仮想環境にライブラリをインストールして YOLOv5 を利用することにします.
ここでは,Anaconda Prompt を用いて,仮想環境を構築してみます.Anaconda Navigator を GUI で操作して仮想環境を構築する方法はこちらを参照してください.まず,インストールされている Python の仮想環境を一覧で表示します.
(base) C:\Users\lecture>conda env list ⏎
# conda environments:
#
base * C:\Users\lecture\anaconda3
py39ocr C:\Users\lecture\anaconda3\envs\py39ocr
(base) C:\Users\lecture>
Python 3.9 をベースにした仮想環境を作成し,その名前を py39yolo
にします.
(base) C:\Users\lecture>conda create -n py39yolo python=3.9 ⏎
(base) C:\Users\lecture>
インストールされている Python の仮想環境を一覧で表示し,py39yolo が構築できていることを確認します.
(base) C:\Users\lecture>conda env list ⏎
# conda environments:
#
base * C:\Users\lecture\anaconda3
py39ocr C:\Users\lecture\anaconda3\envs\py39ocr
py39yolo C:\Users\lecture\anaconda3\envs\py39yolo
(base) C:\Users\lecture>
仮想環境 py39yolo を有効化し,その結果を確認します.
(base) C:\Users\lecture>conda activate py39yolo ⏎ (py39yolo) C:\Users\lecture>conda env list ⏎ # conda environments: # base C:\Users\lecture\anaconda3 py39ocr C:\Users\lecture\anaconda3\envs\py39ocr py39yolo * C:\Users\lecture\anaconda3\envs\py39yolo (py39yolo) C:\Users\lecture>
インストールされているライブラリを確認します.
(py39yolo) C:\Users\lecture>pip list Package Version ------------ --------- certifi 2022.6.15 pip 22.1.2 setuptools 63.4.1 wheel 0.37.1 wincertstore 0.2 (py39yolo) C:\Users\lecture>
YOLOv5 を利用するには,torch をはじめ様々なライブラリをインストールしなければなりません.Anaconda の base 環境にライブラリをインストールしても良いですが,バージョンの不一致などトラブルに見舞われる可能性もあります.したがってここでは YOLOv5 用の Python 仮想環境を構築して,その仮想環境にライブラリをインストールして YOLOv5 を利用することにします.
M1 Mac に構築した Minforge 環境において,Python 3.9 をベースにした仮想環境を作成し,その名前を py39yolo
にします.その後,作成した仮想環境を有効化します.
(base) rinsaka@MacStudio2022 ~ % conda create -n py39yolo python=3.9 ⏎ (base) rinsaka@MacStudio2022 ~ % conda activate py39yolo ⏎ (py39yolo) rinsaka@MacStudio2022 ~ %
以降は macOS での操作によって説明しますが,Windows であっても(次の1行目 cd
コマンドのフォルダ区切り文字以外は)ほぼ同様です.
YOLOv5 ソースコードのクローンを GitHub (https://github.com/ultralytics/yolov5) から作成します.Git のインストールについてはここを参照してください.あるいは,GitHub のサイトから ZIP 形式でダウンロードして展開しても構いません.
(py39yolo) rinsaka@MacStudio2022 ~ % cd Documents/python ⏎ (py39yolo) rinsaka@MacStudio2022 python % git clone https://github.com/ultralytics/yolov5 ⏎ Cloning into 'yolov5'... remote: Enumerating objects: 12123, done. remote: Counting objects: 100% (76/76), done. remote: Compressing objects: 100% (58/58), done. remote: Total 12123 (delta 37), reused 35 (delta 18), pack-reused 12047 Receiving objects: 100% (12123/12123), 12.51 MiB | 24.35 MiB/s, done. Resolving deltas: 100% (8328/8328), done. (py39yolo) rinsaka@MacStudio2022 python %
クローンの作成ができればそのフォルダに移動します.
(py39yolo) rinsaka@MacStudio2022 python % cd yolov5 ⏎
YOLOv5 の実行に必要なライブラリは requirements.txt というファイルに記載されています.これらのライブラリをインストールするには次のようなコマンドを実行します.
(py39yolo) rinsaka@MacStudio2022 yolov5 % pip install -r requirements.txt ⏎
さらに,Jupyter Notebook もインストールしておきます.
(py39yolo) rinsaka@MacStudio2022 yolov5 % pip install jupyter ⏎
YOLOv5 が実行可能な環境が構築できているか動作確認を行います.まず,Jupyter Notebook を起動します.
(py39yolo) rinsaka@MacStudio2022 yolov5 % jupyter notebook⏎
次の3行のコードを入力して実行できれば OK です.
import torch
import utils
display = utils.notebook_init()
Checking setup... YOLOv5 🚀 v6.2-47-geab35f6 Python-3.9.13 torch-1.12.1 CPU Setup complete ✅ (10 CPUs, 32.0 GB RAM, 518.5/926.4 GB disk)
YOLOv5 の data フォルダの中にサブフォルダを作成し,その中に物体検出を行いたい画像ファイルを設置します.ここでは,GitHub のサンプルデータ (https://github.com/rinsaka/sample-data-sets)にある yolo_images.zip をダウンロードして data フォルダ内に展開します.中には20枚の写真 (img_01.jpg 〜 img_20.jpg) があります.そのうち3枚を確認します.
img_01.jpg (米国 Texas 州 Dallas の Elm 通り:ケネディ大統領暗殺地点のすぐ近く)
img_03.jpg (米国 Texas 州 Houston のジョンソン宇宙センター)
img_06.jpg (米国 Texas 州 Dallas の Reunion Tower からの眺め)
YOLOv5 では物体検出のための Python プログラム (detect.py) が提供されており,さらにいくつかの学習済みモデルも提供されています.これらの学習済みモデルは検出の精度と演算に必要な負荷が異なります.いくつか試して適切なモデルを選ぶと良いでしょう.まず,YOLOv5s (small) のモデルを使って物体検出を行います.このとき Jupyter Notebook から Python のプログラム (detect.py) を実行するには,シェルコマンド ( ! ) を利用すると良いでしょう.あるいは,Windows の Anaconda Prompt や Mac のターミナルを使って実行しても構いません.このときは ! を入力せずに python detect.py ...
から入力してください.
!python detect.py --weights yolov5s.pt --img 640 --conf 0.25 --source data/yolo_images
detect: weights=['yolov5s.pt'], source=data/yolo_images, data=data/coco128.yaml, imgsz=[640, 640], conf_thres=0.25, iou_thres=0.45, max_det=1000, device=, view_img=False, save_txt=False, save_conf=False, save_crop=False, nosave=False, classes=None, agnostic_nms=False, augment=False, visualize=False, update=False, project=runs/detect, name=exp, exist_ok=False, line_thickness=3, hide_labels=False, hide_conf=False, half=False, dnn=False YOLOv5 🚀 v6.2-73-g91a81d4 Python-3.9.13 torch-1.12.1 CPU Downloading https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5s.pt to yolov5s.pt... 100%|██████████████████████████████████████| 14.1M/14.1M [00:00<00:00, 21.5MB/s] Fusing layers... YOLOv5s summary: 213 layers, 7225885 parameters, 0 gradients image 1/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img01.jpg: 480x640 9 cars, 1 truck, 6 traffic lights, 67.7ms image 2/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img02.jpg: 480x640 2 cars, 1 train, 56.9ms image 3/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img03.jpg: 480x640 1 person, 1 airplane, 50.3ms image 4/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img04.jpg: 480x640 1 car, 5 trucks, 48.5ms image 5/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img05.jpg: 480x640 3 bottles, 1 cup, 3 bowls, 1 sandwich, 1 dining table, 49.7ms image 6/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img06.jpg: 480x640 1 car, 3 trains, 1 truck, 49.5ms image 7/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img07.jpg: 384x640 12 persons, 2 cars, 1 horse, 4 cows, 44.3ms image 8/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img08.jpg: 480x640 5 persons, 2 cars, 1 bus, 1 stop sign, 51.1ms image 9/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img09.jpg: 480x640 7 persons, 1 airplane, 48.5ms image 10/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img10.jpg: 480x640 8 persons, 1 car, 1 truck, 51.1ms image 11/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img11.jpg: 640x480 (no detections), 51.0ms image 12/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img12.jpg: 480x640 1 airplane, 51.2ms image 13/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img13.jpg: 384x640 1 sheep, 42.6ms image 14/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img14.jpg: 480x640 1 car, 1 train, 1 truck, 51.2ms image 15/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img15.jpg: 480x640 1 car, 52.0ms image 16/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img16.jpg: 480x640 1 car, 50.0ms image 17/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img17.jpg: 480x640 9 cars, 50.8ms image 18/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img18.jpg: 480x640 3 persons, 4 cars, 51.6ms image 19/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img19.jpg: 480x640 1 person, 2 cars, 4 traffic lights, 50.9ms image 20/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img20.jpg: 480x640 1 person, 11 cars, 2 trucks, 50.3ms Speed: 0.3ms pre-process, 51.0ms inference, 0.5ms NMS per image at shape (1, 3, 640, 640) Results saved to runs/detect/exp
最初に実行したときに学習済みモデルファイルが自動的にダウンロードされることに注意してください.さらに,上の実行結果を見ると,img01.jp からは9台の自動車,1台のトラック,6台の交通信号機が検出されたことがわかります.結果の最後の行には出力されたフォルダ名 runs/detect/exp
が表示されているので,そのフォルダのファイルを確認します.
自動車や交通信号機などが検出できています.
img_01.jpg
2機の航空機(ジェット機とスペースシャトル)が1つの航空機であると判断しているようです.
img_03.jpg
自動車やトレーラの車列を列車と判断しているようです.
img_06.jpg
次はモデル YOLOv5m (medium) を使ってみます.実行結果は連番で新たなフォルダが自動的に作成されて出力されることに注意してください.2回めの実行であるので exp2 というフォルダが runs/detect/ フォルダに作成されています.
!python detect.py --weights yolov5m.pt --img 640 --conf 0.25 --source data/yolo_images
YOLOv5m summary: 290 layers, 21172173 parameters, 0 gradients
image 1/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img01.jpg: 480x640 9 cars, 1 truck, 9 traffic lights, 105.0ms
image 3/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img03.jpg: 480x640 1 person, 1 airplane, 96.5ms
image 6/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img06.jpg: 480x640 8 cars, 94.6ms
...
Results saved to runs/detect/exp2
検出された交通信号機の数が6台から9台に増えました.
img_01.jpg
検出した物体は変わりませんが confidence (信頼度・確信度) が増加しました.
img_03.jpg
列車であると誤判断していたものが自動車と認識できてます.
img_06.jpg
次はモデル YOLOv5l (large) を使ってみます.
!python detect.py --weights yolov5l.pt --img 640 --conf 0.25 --source data/yolo_images
YOLOv5l summary: 367 layers, 46533693 parameters, 0 gradients image 1/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img01.jpg: 480x640 9 cars, 2 trucks, 11 traffic lights, 180.8ms image 3/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img03.jpg: 480x640 1 person, 2 airplanes, 155.4ms image 6/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img06.jpg: 480x640 20 cars, 1 truck, 154.9ms ... Results saved to runs/detect/exp3
モデル YOLOv5m と比較してトラックが1台から2台へ,信号機が9台から11台に増えました.
img_01.jpg
ジェット機とスペースシャトルがそれぞれ別の航空機であると認識できました.
img_03.jpg
認識できた自動車の数が8台から20台に増えました.
img_06.jpg
次はモデル YOLOv5x (x-large) を使ってみます.
!python detect.py --weights yolov5x.pt --img 640 --conf 0.25 --source data/yolo_images
YOLOv5x summary: 444 layers, 86705005 parameters, 0 gradients image 1/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img01.jpg: 480x640 10 cars, 2 trucks, 13 traffic lights, 252.3ms image 3/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img03.jpg: 480x640 1 person, 2 airplanes, 239.3ms image 6/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img06.jpg: 480x640 29 cars, 1 train, 1 truck, 239.9ms ... Results saved to runs/detect/exp4
モデル YOLOv5l と比較して認識できた自動車が1台,信号機が2台増えました.
img_01.jpg
モデル YOLOv5l で認識できていた2機の航空機が正しく認識できなくなりました.
img_03.jpg
認識できた自動車の数が20台から29台に増え,列車の一部も認識できるようになりました.ただし,実際の列車は写真の右下端から左端までつながっています.
img_06.jpg
次はモデル YOLOv5l6 (YOLOv5-P6 の large) を使ってみます.P6 のモデルでは --img
引数に 1280
が利用できるようになります.
!python detect.py --weights yolov5l6.pt --img 1280 --conf 0.25 --source data/yolo_images
YOLOv5l6 summary: 476 layers, 76726332 parameters, 0 gradients image 1/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img01.jpg: 960x1280 12 cars, 2 trucks, 15 traffic lights, 620.8ms image 3/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img03.jpg: 960x1280 2 persons, 2 airplanes, 550.1ms image 6/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img06.jpg: 960x1280 43 cars, 2 trains, 3 trucks, 570.7ms ... Results saved to runs/detect/exp5
認識できた自動車や信号機の数が増えました.
img_01.jpg
モデル YOLOv5l と同じ物体が検出されていますが,信頼度が異なります(物体ごとに増減が認められます).
img_03.jpg
モデル YOLOv5x と比べても自動車の認識台数が増加しました.
img_06.jpg
YOLOv5 の detect.py の実行時引数に --save-crop
を追加すると CROP(切り抜き画像)を取得できるようになります.また,--conf
を変更することで,信頼度を変更することができます.これまでの実行では信頼度が 0.25 以上のものを認識結果として出力していましたが,これを 0.1 に変更してみます.
!python detect.py --weights yolov5l6.pt --img 1280 --conf 0.1 --source data/yolo_images --save-crop
YOLOv5l6 summary: 476 layers, 76726332 parameters, 0 gradients image 1/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img01.jpg: 960x1280 12 cars, 2 trucks, 21 traffic lights, 584.5ms image 3/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img03.jpg: 960x1280 3 persons, 1 car, 3 airplanes, 648.9ms image 6/20 /Users/rinsaka/Documents/python/yolov5/data/yolo_images/img06.jpg: 960x1280 1 person, 117 cars, 11 trains, 6 trucks, 549.1ms ... Results saved to runs/detect/exp6
信頼度の低い物体も出力することから,結果的に認識された信号機の数がさらに増えました.
img_01.jpg
クレーン作業員の信頼度が 0.11 でしたがこれが出力されました.
img_03.jpg
自動車の認識台数が大幅に増加しました.
img_06.jpg
さらに,出力されたフォルダ内には crop というサブフォルダが作成され,認識された物体ごとに切り抜き画像が保存されていることを確認してください.
物体検出した結果を何らかの別の処理に引き渡したいような場合はテキスト形式でも出力すると良いでしょう.このためには --save-txt
オプションを追加します.
!python detect.py --weights yolov5l6.pt --img 1280 --conf 0.1 --source data/yolo_images --save-txt
この結果,画像ごとにテキストファイルが作成されます.例えば img01.txt は次のような結果になります.
9 0.682617 0.782878 0.00585938 0.00976562 9 0.654297 0.773438 0.0078125 0.0169271 9 0.75293 0.790365 0.00488281 0.0143229 ...(中略)... 9 0.399414 0.426432 0.0351562 0.105469 # 中央の信号機(左) 9 0.599854 0.435872 0.0375977 0.10612 # 中央の信号機(右) 2 0.929199 0.873698 0.140625 0.251302 # 右下の自動車(白) 2 0.205322 0.826497 0.134277 0.10612 # 左下の自動車(黒) 2 0.0595703 0.848633 0.118164 0.13737 # 左下の自動車(白)
上の結果の各行は認識された物体の「ラベル」,「中心X座標」,「中心Y座標」,「幅」,「高さ」を意味します.詳細はここの記事 (https://github.com/ultralytics/yolov5/discussions/2032)を読むと理解できることでしょう.
さらに,--save-txt
と同時に --save-conf
も指定すると,信頼度もテキストファイルに出力することができるようになります.
!python detect.py --weights yolov5l6.pt --img 1280 --conf 0.1 --source data/yolo_images --save-txt --save-conf
このとき出力されるテキストファイルは次のようになります.最終列に信頼度が表示され,信頼度の順にソートされていることもわかりました.例えば最後の2行は左下の2台の自動車(どちらも0.94)で,下から3行目のデータは画面右下の自動車(0.92)の認識結果を意味しています.さらに下から4行目と5行目は写真中央にある信号機(0.86と0.85)の認識結果です.
9 0.682617 0.782878 0.00585938 0.00976562 0.13844 9 0.654297 0.773438 0.0078125 0.0169271 0.150449 9 0.75293 0.790365 0.00488281 0.0143229 0.172376 ...(中略)... 9 0.399414 0.426432 0.0351562 0.105469 0.852787 # 中央の信号機(左) 9 0.599854 0.435872 0.0375977 0.10612 0.864282 # 中央の信号機(右) 2 0.929199 0.873698 0.140625 0.251302 0.922037 # 右下の自動車(白) 2 0.205322 0.826497 0.134277 0.10612 0.93531 # 左下の自動車(黒) 2 0.0595703 0.848633 0.118164 0.13737 0.935599 # 左下の自動車(白)
img_01.jpg