【YOLOv5】ドローン画像からのA4用紙を検出してみよう！

![rectangle_large_type_2_b0a7b3ce25bbc84991c8a0ad31cfe4d4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/239309c2-db66-f273-b504-d238f7dee62f.png)

# はじめに
本記事は，大学の講義の一貫として行った内容をメモ程度に残したものです。

👇下記に学内学生向け用のドローンデータを添付しておきます👇
[ドローンデータ配布（学内学生向け）](https://risshouniv-my.sharepoint.com/:f:/g/personal/253h10001_rissho-univ_jp/Enmt8PFYJUhKtThjp5HG9jgBff_pf2AR8sVnND36T2g0DA?e=O8xalP)

[ LabelImg ](https://github.com/HumanSignal/labelImg)による教師データの作成やYOLOモデルの解説・学習については，
他の方の記事を参考にしてください。

ドローン画像は，[DJI Phantom3 Professional](https://www.dji.com/jp/support/product/phantom-3-pro) で撮影した画像をオルソ画像にし，
png形式で保存しています。

![Phantom3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/87436f62-69ea-75c6-eca9-58fb30ce3c97.jpeg)
出典：[DJI Phantom3 Professional](https://www.dji.com/jp/downloads/products/phantom-3-pro)


# 1. YOLOでの物体検出
## 1.1 YOLOとは？
そもそもYOLOとは何なのか？
<b>YOLO（You Only Look Once）</b>は，一般物体検出アルゴリズムの1つです。検出と識別を同時に行うため，検出速度が非常に速いことが特徴です。YOLOは2024年7月2日現在でversion10まで出ています。
![YOLOの論文.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/16f635b3-e0e7-a75f-20cd-080b95a49b15.png)
出典：[You Only Look Once: Unified, Real-Time Object Detection](https://arxiv.org/abs/1506.02640)

## 1.2 A4用紙検出モデルの構築手順
YOLOを用いたA4用紙の物体検出の手順を下記に示します。
先週の授業までで，濃い青色部分の「**ドローンによる撮影とオルソ画像化**」が完了していると思います。水色から黄緑色部分の「**教師データ作成～学習**」にかけては，事前にこちらで行っておきました。
本記事は主に緑色部分の「**推論**」について記載していきます。

![物体検出モデルの構築手順.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/e61cca8a-3d27-45cf-62ca-53e1d5e93511.png)


## 1.3 zipファイルの配布（2025/09/28まで取得可能）
授業で配布したzipファイルを解凍し，自身のGoogle Driveのマイドライブ上にドラッグ＆ドロップでアップロードしてください。
念のため，[ギガファイル便での共有リンク](https://34.gigafile.nu/0928-k9578d2ddcff1fbb5a5a0d304ead4a07c)も下記に置いておきます。

https://34.gigafile.nu/0928-k9578d2ddcff1fbb5a5a0d304ead4a07c

# 2. Google Colab での実装

## 2.1 フォルダのアップロード
今回は既にドローンで撮影した画像をもとに，GoogleColableを用いて検出を行っていきます。用いるデータは1.3節のもので，授業の際にも配布いたします。解凍後，ご自身のGoolgeDriveの任意の場所にアップロードし，開いてください。

```ruby:配布ファイルのフォルダ構成（yolov5フォルダの中身は省略）
A4paperDetection
├─A4paperDetection.ipynb
├─best.pt
├─image
│  ├─test2.png
├─output
│  ├─test2.png   
└─yolov5
```


アップロードしたフォルダ構成は上のようになっています。このうち，「**A4paperDetection.ipynb**」であるノートブックファイルをダブルクリックして，Google Colab アプリで開いてください。textで開いてしまう場合は，「ファイルを右クリック ▶ アプリで開く ▶ Google Colaboratory」で開いてください。

開けたら，中身のセルを1つずつ確認していきましょう。


## 2.2 ハードウェアアクセラレータをGPUに変更
まずはGoogleが提供しているGPU（通常より早く複雑な計算ができるPCの頭脳部分）を
使えるようにします。
Colab上部のランタイムタブから「ランタイムのタイプを変更」を選択し，
「ハードウェア アクセラレータ」を「**T4 GPU**」に変更して保存してください。
![1688559850809-Uj5KR3zGdM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/ea527d52-bb61-7bc9-8ae9-c4439dd6fdf4.png)


## 2.3 GPUの確認とDriveのマウント

```ruby:1つ目のセル
!nvidia-smi    # GPUの確認
!nvidia-smi -L
```
上記の1つ目のセルは今回使用できるGPUを確認しています。これを実行（Shiftキー + Enter）してみて下さい。すると以下のような結果が出てくると思いますが特に気にせず眺めるだけにしてください。詳しい内容については，quiverさんの[nvidia-smiでNVIDIA GPU使用状況をモニタリングする](https://dev.classmethod.jp/articles/monitor-nvidia-gpu-usage-with-nvidia-smi-nvsmi/)を確認してみて下さい．
![NVIDIA_smi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/e2784c4c-a7bb-646c-70b2-be6d667b14aa.png)


```ruby:2つ目のセル
from google.colab import drive  # Google Drive のマウント
drive.mount('/content/drive')   # Google Drive内のフォルダにアクセスできるようにしている             
```
次に2つ目のセルを実行してください。このコードは，Google Driveのマウントを行っています。許可の画面が出ると思うので，指示に従ってご自身のアカウントで許可を行ってください。

## 2.4 フォルダの作成とPythonパッケージのインストール

```ruby:3つ目のセル
%mkdir -p /content/drive/MyDrive/A4paperDetection         # %mkdir     ： ディレクトリ（フォルダ）の作成
%cd /content/drive/MyDrive/                               # %cd        ： ディレクトリ（フォルダ）へ移動
!git clone https://github.com/Tana-ris/A4paperDetection   # !git clone ： Github上にアップロードした授業用フォルダのダウンロード 
%cd A4paperDetection/yolov5                               
%pip install -qr requirements.txt                         # %pip       ： 必要なPythonパッケージ（今回はrequirements.txt内に記載）のインストール

import torch
import utils
from IPython.display import Image, clear_output, display  # to display images
display = utils.notebook_init()      
```

次に3つ目のセルを実行してみて下さい。そうすると，この授業専用に作成したGithub上のフォルダからYOLOv5のモデルのダウンロードがされ，GoogleDriveのMydrive直下に，「**A4paperDetection**」というフォルダが作られると思います。
また，「**A4paperDetection**」フォルダの中に「**yolov5**」「**image**」「**output**」というフォルダも作られていると思います。

作成した「**A4paperDetection**」フォルダの中に，解凍したファイルの中にある
学習済みモデル「**best.pt**」をアップロードしてください。

![1719816617675-c7EXJpBmB4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/c55ca7bd-81d4-ecc1-514a-44844a651b76.png)
![1719816724959-99KRsPByfV.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/0465a4aa-3620-206a-b866-2ddb72095316.png)

```ruby:4つ目のセル
# 必要なディレクトリを作成（Githubからクローン出来なかった人向け）
%mkdir -p /content/drive/MyDrive/A4paperDetection/image
%mkdir -p /content/drive/MyDrive/A4paperDetection/output
%cd /content/drive/MyDrive/A4paperDetection/yolov5

```
4つ目のセルでは，「A4paperDetection」直下に「image」と「output」の2つのフォルダを作成しています．

:::note warn
授業で配布したファイルではすでに作成しています。
:::

## 2.5 フォルダ作成と推論実行

```ruby:5つ目のセル
# YOLOv5の物体検出スクリプト（実際に推論を行うpythonファイルの）detect.pyを実行
# --source    ： 検出したい画像があるフォルダパス or 画像パス を指定
# --weights   ： 学習済みモデルの重みファイル（授業前に""A4用紙だけ""を見つけるために学習し最適化されたパラメータ）のパス
# --img       ： 入力画像サイズ
# --conf      ： 信頼度の閾値
# --name      ： 検出した画像の出力先フォルダ名
# --exist-ok  ： 出力先フォルダが存在してもエラーを出さない

print("YOLOを用いてA4用紙を検出中....")

!python detect.py --source /content/drive/MyDrive/A4paperDetection/image/ \
                  --weights /content/drive/MyDrive/A4paperDetection/best.pt \
                  --img 1280 \
                  --conf 0.3 \
                  --name /content/drive/MyDrive/A4paperDetection/output/ \
                  --exist-ok

print(f"検出されたすべての画像を，「/content/drive/MyDrive/A4paperDetection/output/」に出力しました！")
```
次に5つ目のセルを実行してみて下さい。
そうすると推論（実際に画像の中からA4用紙を見つける作業）が始まります。
1枚当たり51.1ms（**0.051秒/枚**）前後で実行できると思います。

detect.pyの引数（オプション）には，下記の5つを設定しています。「**--conf**」は検出の閾値を示しており，0～1の範囲をとります。閾値を下げると確度の低いものまで検出するようになり，逆に閾値を上げると確実にA4用紙だとAIが判断したもののみ検出するようになります。各自で適宜調整してみてください。

| 引数（オプション） | 説明 | 入力値 |
|:-----------|:-----------|:-----------|
| --source | 検出したい画像があるフォルダパス or 画像パス を指定 | /content/drive/MyDrive/A4paperDetection/image/ |
| --weights | 学習済みモデルの重みファイル（授業前に""A4用紙だけ""を見つけるために学習し最適化されたパラメータ）のパス　| /content/drive/MyDrive/A4paperDetection/best.pt |
| --img | 入力画像サイズ　| 1280 |
| --conf | 信頼度の閾値（最低限の検出信頼度を決める） | 0.3（0～1の間で設定） |
| --name | 検出した画像の出力先フォルダ名　| /content/drive/MyDrive/A4paperDetection/output/ |
| --exist-ok | 出力先フォルダが存在してもエラーを出さない　| (なし) |

# 3. 検出結果
## 3.1 ドローン画像からの検出
検出結果は，先ほど作成した「**/content/drive/MyDrive/A4paperDetection/output**」に
出力されています。A4用紙をうまく検出できているのがわかりますね！（感動ポイント）

![test2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/0994a98e-43d0-aa94-b57c-b64151419079.png)

![1719817493406-BIr9eTq1FD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049445/21cc72ac-83d6-8a19-47cf-ec362e9fc6dd.png)

授業で配布したファイルの中にある「detect.py」には，A4用紙の枚数をカウントし，出力画像上に枚数を記載するコードを追加しています。今回の「**best.pt**」だと29枚のA4用紙を発見することができています。

## 3.2 ドローン動画からの検出 (2024/07/06追記)
ちなみにGIS等で用いられるようなラスタデータ(.tif形式）や動画形式でも推論を行うことが出来ます。下記の動画は今年度の授業で撮影した動画を用いた検出例です。
<iframe width="560" height="500" src="https://www.youtube.com/embed/LI94HxIT6-A?si=0z35hlCmAis7QkYz" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

日陰内に点在する日向部分などで誤検出が発生していました。
教師データの質や量，撮影動画のフィルタリング等を行うことで精度が向上するかもしれません。

# まとめ
以上でドローン画像からYOLOv5を用いてA4用紙を検出するプログラムの解説を終わりにします。


# 参考文献
[1] DJI，DJI Phantom3 Professional．https://www.dji.com/jp/downloads/products/phantom-3-pro ．（2024年7月2日確認）

[2] Joseph Redmon, Santosh Divvala, Ross Girshick, Ali Farhadi，2016．You Only Look Once: Unified, Real-Time Object Detection，https://arxiv.org/abs/1506.02640 ．

[3] quiver，2020．nvidia-smiでNVIDIA GPU使用状況をモニタリングする，https://dev.classmethod.jp/articles/monitor-nvidia-gpu-usage-with-nvidia-smi-nvsmi/ ．（2024年7月2日確認）