YOLOv5で物体検出して座標・幅・高さをCSV出力する_ Python

スポンサーリンク
Python/DeepLearning

みなさん、こんにちは!

みやしんです。^^

今回はYOLOv5を使って物体検出をやってみたいと思います!

みやしん
みやしん

物体検出はPythonを勉強している人なら一度はやってみたいスキルですにゃ!

簡単に出来ますので早速やっていきましょう!!

このブログの管理人も卒業生です。
スポンサーリンク

この記事で出来ること_YOLOv5

  1. 画像内の物体検出
  2. 物体検出は全部で80種類
  3. バウンディングBOXの座標、幅、高さをCSV出力
  4. 検出した物体の画像を切り抜く

1、画像内の物体検出

YOLOv5ではこんな感じで物体検出ができます!

元画像

物体検出

人間:person、カップ:cup、ケーキ:cake をしっかり検出できていますね!


2、物体検出は全部で80種類

下記の80種類の物体を検出可能です!

[‘person’, ‘bicycle’, ‘car’, ‘motorcycle’, ‘airplane’, ‘bus’, ‘train’, ‘truck’, ‘boat’, ‘traffic light’, ‘fire hydrant’, ‘stop sign’, ‘parking meter’, ‘bench’, ‘bird’, ‘cat’, ‘dog’, ‘horse’, ‘sheep’, ‘cow’, ‘elephant’, ‘bear’, ‘zebra’, ‘giraffe’, ‘backpack’, ‘umbrella’, ‘handbag’, ‘tie’, ‘suitcase’, ‘frisbee’, ‘skis’, ‘snowboard’, ‘sports ball’, ‘kite’, ‘baseball bat’, ‘baseball glove’, ‘skateboard’, ‘surfboard’, ‘tennis racket’, ‘bottle’, ‘wine glass’, ‘cup’, ‘fork’, ‘knife’, ‘spoon’, ‘bowl’, ‘banana’, ‘apple’, ‘sandwich’, ‘orange’, ‘broccoli’, ‘carrot’, ‘hot dog’, ‘pizza’, ‘donut’, ‘cake’, ‘chair’, ‘couch’, ‘potted plant’, ‘bed’, ‘dining table’, ‘toilet’, ‘tv’, ‘laptop’, ‘mouse’, ‘remote’, ‘keyboard’, ‘cell phone’, ‘microwave’, ‘oven’, ‘toaster’, ‘sink’, ‘refrigerator’, ‘book’, ‘clock’, ‘vase’, ‘scissors’, ‘teddy bear’, ‘hair drier’, ‘toothbrush’]

おまけ

ちなみにこれは、「person」「horse」もしくは「両方」のどのパターンで物体検出されるでしょうか?笑

答えは記事の最後で!

3、 バウンディングBOXの座標、幅、高さをCSV出力

CSVファイルにバウンディングBOXの「座標」「幅」「高さ」の情報をcsv出力します。

座標情報の出力は後々の解析にも使えますので、便利だと思い機能追加しました。

detction_Result.csv のファイル名で検出結果を出力します。

detection_Result.csv

検出した物体の画像を切り抜く

検出した物体をバウンディングBOXで切り抜いて保存します。

下記のように、それぞれフォルダーを分けて保存します。

それでは、実際にやり方を解説していきます!

動作環境の準備

pipとsetuptoolsの更新

出来れば個別で仮想環境を作ってからが良いと思います。自分はAnacondaで実施しています。

まずは、pipとsetuptoolsを更新します。

python -m pip install --upgrade pip setuptools

必要なライブラリをインストール

pipコマンドを実施して動作環境を設定します。

pip install -qr https://raw.githubusercontent.com/ultralytics/yolov5/master/requirements.txt

下記の内容をセッティングしています。

requirements.txt

# pip install -r requirements.txt

# Base ----------------------------------------
matplotlib>=3.2.2
numpy>=1.18.5
opencv-python>=4.1.2
Pillow>=7.1.2
PyYAML>=5.3.1
requests>=2.23.0
scipy>=1.4.1
torch>=1.7.0
torchvision>=0.8.1
tqdm>=4.41.0

# Logging -------------------------------------
tensorboard>=2.4.1
# wandb

# Plotting ------------------------------------
pandas>=1.1.4
seaborn>=0.11.0

# Export --------------------------------------
# coremltools>=4.1  # CoreML export
# onnx>=1.9.0  # ONNX export
# onnx-simplifier>=0.3.6  # ONNX simplifier
# scikit-learn==0.19.2  # CoreML quantization
# tensorflow>=2.4.1  # TFLite export
# tensorflowjs>=3.9.0  # TF.js export
# openvino-dev  # OpenVINO export

# Extras --------------------------------------
# albumentations>=1.0.3
# Cython  # for pycocotools https://github.com/cocodataset/cocoapi/issues/172
# pycocotools>=2.0  # COCO mAP
# roboflow
thop  # FLOPs computation

物体検出の実行スクリプト

まずはフォルダー構成です。yolov5.pyのコードは以下に記載しています。物体検出したい画像のファイル名は変えて、コピペしてお使い頂けます。

yolov5.py を実行します。

yolov5.py

import torch
import csv

# PyTorch Hubから学習済みモデルをダウンロード 
model = torch.hub.load("ultralytics/yolov5", "yolov5s", pretrained=True)
# 検出できる物体を表示する(80種類)
print(model.names)  
 
results = model("birthday.jpg")  # 画像パスを設定し、物体検出を行う
objects = results.pandas().xyxy[0]  # 検出結果を取得してobjectに格納
# objectに格納したデータ
# => バウンディングBOX左上のx座標とy座標、信頼度、クラスラベル、物体名

# 物体検出結果を出力するためのcsvファイルを作成
with open('detection_Result.csv', 'w') as f:
    print("ID,種類,x座標,y座標,幅,高さ", file=f) # print()の第2引数で出力先を指定可能
 
    for i in range(len(objects)):
        name = objects.name[i]
        xmin = objects.xmin[i]
        ymin = objects.ymin[i]
        width = objects.xmax[i] - objects.xmin[i]
        height = objects.ymax[i] - objects.ymin[i]
        # print(f"{i}, 種類:{name}, 座標x:{xmin}, 座標y:{ymin}, 幅:{width}, 高さ:{height}")
        # csvファイルにバウンディングBOX情報を出力
        print(f"{i},{name},{xmin},{ymin},{width},{height}", file=f)

results.show()  # 検出した物体の表示
results.crop()  # 検出した物体の切り取り

処理が終了すると、下記のようなフォルダー構成でデータが出力されます。

もしエラーが発生したら

AttributeError: ‘Upsample’ object has no attribute ‘recompute_scale_factor’

■解決策

下記のコード修正をすることで解決しました。

修正するファイル:upsampling.py

C:\Users\[ユーザー名]\anaconda3\envs\[仮想環境名]\Lib\site-packages\torch\nn\modules\upsampling.py

修正前

def forward(self, input: Tensor) -> Tensor:

        return F.interpolate(input, self.size, self.scale_factor, self.mode, self.align_corners,recompute_scale_factor=self.recompute_scale_factor)

修正後

def forward(self, input: Tensor) -> Tensor:

        return F.interpolate(input, self.size, self.scale_factor, self.mode, self.align_corners)

これでOKです!

おまけの答え

答えは「person」でした! ウケル!意外www!

物体検出をもっと学習したい方にUdemyがお勧めです。

このブログの管理人も卒業生です。

合わせて読みたい


Python/DeepLearning
スポンサーリンク
記事が良かったらSNSでシェアを宜しくお願いします!
みやしんをフォローすると役立つ情報がいっぱいにゃ!
スポンサーリンク

コメント

  1. K.M より:

    はじめましてみやしんさん、私はyoloxで実装しているのですが、座標出力をやってみたくてできるのでしょうか? csv出力について情報をお聞かせ願えませんか?

タイトルとURLをコピーしました