はじめに
YOLOv5は物体検出に強力なモデルですが、GPUがない環境でもDockerを使って動かすことが可能です。この記事では、NVIDIAのGPUがないUbuntu環境で、Dockerを使ってYOLOv5をCPUで動かす手順を詳しく説明し、各ステップで発生しうるエラーと解決策についても詳しく解説します。
環境と要件
- OS: UbuntuServer 22.04
- Docker: インストール済み
- CPU: IntelCorei37500
- メモリ: 4GB(後に8GB増強して12GBにした)
- SSD: 500GB
- GPU: なし (CPUでYOLOv5を実行)
必要なリソース:
- Dockerイメージ:
ultralytics/yolov5:v6.2-cpu
(CPU環境向け)
ステップ1: Dockerイメージの準備
まず、YOLOv5のDockerイメージをDockerHubから取得します。
docker pull ultralytics/yolov5:v6.2-cpu
イメージのダウンロードが完了したら、コンテナを起動します。
docker run --rm -it \
--device /dev/video0:/dev/video0 \
--device /dev/video1:/dev/video1 \
-v $(pwd):/usr/src/app \
ultralytics/yolov5:v6.2-cpu
-
--device /dev/video0:/dev/video0
はホストマシンのカメラをコンテナにマウントしています。 -
-v $(pwd):/usr/src/app
でホストのカレントディレクトリをコンテナにマウントし、結果ファイルを直接ホスト側で確認できるようにしています。
ステップ2: 推論の実行
カメラ映像を使ったリアルタイム推論
まずカメラデバイスが認識されているか確認します。
ls /dev/video*
カメラが認識されていれば、YOLOv5でリアルタイム推論を実行できます。
python3 detect.py --source 0 --weights yolov5s.pt --conf 0.5 --device cpu
しかし、Docker環境では通常、GUIがサポートされないため、cv2.imshow()
や PIL Image.show()
は使用できません。代わりに、推論結果をファイルとして保存して確認する方法を利用します。
ステップ3: 結果の保存と確認
推論結果をファイルとして保存するには、以下のオプションを使用します。
python3 detect.py --source 0 --weights yolov5s.pt --conf 0.5 --device cpu --save-txt --save-conf
-
--save-txt
: 検出されたオブジェクトの座標をテキストファイルに保存 -
--save-conf
: 検出結果に信頼度を追加
推論結果はデフォルトで runs/detect/exp
ディレクトリに保存されます。コンテナ内の結果をホスト側にコピーするには、以下のコマンドを使用します。
docker cp <container_id>:/usr/src/app/runs/detect ./detect_results
ステップ4: Flaskを使ったリアルタイム表示
Docker環境内でリアルタイム表示が難しい場合は、Flaskを利用して、推論結果をWebブラウザにストリーミングする方法があります。
Flaskアプリケーションのセットアップ
Flaskとその他必要なライブラリをインストールします。
pip install flask opencv-python
Flaskアプリケーションを作成します。以下のコードを app.py
として保存します。
from flask import Flask, render_template, Response
import cv2
import torch
import numpy as np
app = Flask(__name__)
# YOLOv5モデルのロード
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
# カメラの初期化
camera = cv2.VideoCapture(0)
def generate_frames():
while True:
success, frame = camera.read()
if not success:
break
else:
# YOLOv5による推論
results = model(frame)
annotated_frame = np.squeeze(results.render())
# フレームをJPEG形式にエンコード
ret, buffer = cv2.imencode('.jpg', annotated_frame)
frame = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
@app.route('/')
def index():
return render_template('index.html')
@app.route('/video_feed')
def video_feed():
return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
templates
フォルダを作成し、その中に index.html
を配置します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>YOLOv5 Real-Time Object Detection</title>
</head>
<body>
<h1>Real-Time Object Detection</h1>
<img src="{{ url_for('video_feed') }}" width="800">
</body>
</html>
Flaskアプリケーションを実行します。
python app.py
ブラウザで http://localhost:5000
にアクセスすると、YOLOv5のリアルタイム推論結果が表示されます。
トラブルシューティング
TemplateNotFoundエラー
Flaskアプリケーションで jinja2.exceptions.TemplateNotFound: index.html
エラーが出た場合、index.html
が templates
フォルダ内に正しく保存されているか確認してください。
cv2.imshow()が動作しない
Docker環境でGUI表示が必要な場合、X11転送を使用するか、ホスト環境で直接実行する方法を検討してください。
CPU環境での速度低下
GPUがない場合、推論速度が遅くなる可能性があります。リアルタイム処理が求められる場合は、GPU搭載マシンでの実行が望ましいでしょう。
まとめ
この記事では、Ubuntu上のDocker環境でYOLOv5をCPUで実行し、Flaskを使ってリアルタイムに表示する方法を詳しく解説しました。Docker環境での制約を理解し、発生しやすいエラーとその対策も含めて説明しました。この手順を参考に、トラブルを解決しながらYOLOv5をDockerで実行してみてください。