Help us understand the problem. What is going on with this article?

Yolo v3+Windows 10でデスクトップのアイコンを識別してみる その1

はじめに

前回は、強化学習でデスクトップのアイコンをゴミ箱に移動するというものを作ってみました。
今回は、Yolo v3を使ってデスクトップのアイコンを識別して、それをゴミ箱に移動するというのを作ってみたいと思います。

環境

Windows10 Pro
Visual Studio 2017
CUDA 10.0
cuDNN 7.3.0.29
OpenCV 4.1.1

Yolo v3インストール

Yolo v3をWindowsにインストールするには、公式のものだといろいろ難しいようです。
そこで、Windows用にリポジトリしてくれたものがあるので、それを利用します。

github
git clone https://github.com/AlexeyAB/darknet.git
cd darknet

準備として、CUDAとcuDNNとOpenCVにパスを通します。

OpenCV
[配置先]\opencv\build\x64\vc15\bin

CUDA、CuDNN
[配置先]\CUDA\v10.0\bin

VSのソリューションを開きます。
ソリューションは、下記にあります。
[配置先]\darknet\build\darknet\darknet.sln

ソリューションプラットホームをReleasex64に変更します。Debugのままだとエラーになりました・・。

CUDAとOpenCVのインクルードディレクトリを追加します。
image.png

ライブラリにもディレクトリを追加します。
image.png

リビルドしましょう!
ワーニングはたくさん出ますが、最終的に成功しました。
image.png

ウェイトファイルを以下からダウンロードして、先ほどビルドして出来上がったdarknet.exeと同じ場所に保存します。
https://pjreddie.com/media/files/yolov3.weights

コマンドプロンプトで、darknet.exeの場所まで移動して、以下のコマンドを実行します。

コマンドプロンプト
darknet.exe detect cfg\yolov3.cfg yolov3.weights data\dog.jpg

サンプル画像での認識結果が表示されたら、インストール成功です。
image.png

テストデータを準備する

テストデータは、ネットの画像検索で取得してきます。
Goolgeで「デスクトップアイコン」というキーワードで画像検索すると、結構出てきます。

image.png

この画像たちをアノテーションしていくのですが、完全手作業だと手間がかかるので、labelImgというツールを使います。
Github:
https://github.com/tzutalin/labelImg

labelImgをインストールする

Windows+conda環境では、以下のようにインストールします。

conda_prompt
git clone https://github.com/tzutalin/labelImg.git
cd labelImg

conda install pyqt=5
pyrcc5 -o libs/resources.py resources.qrc
python labelImg.py
python labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]

python lavelImg.pyを実行すると以下のエラーが発生しました。

エラー発生
(labelImg) D:\Projects\python\labelImg>python labelImg.py
Traceback (most recent call last):
  File "labelImg.py", line 39, in <module>
    from libs.labelFile import LabelFile, LabelFileError
  File "D:\Projects\python\labelImg\libs\labelFile.py", line 10, in <module>
    from libs.pascal_voc_io import PascalVocWriter
  File "D:\Projects\python\labelImg\libs\pascal_voc_io.py", line 6, in <module>
    from lxml import etree
ModuleNotFoundError: No module named 'lxml'

そんな時は、lxmlをインストールすれば解決です。

conda_prompt
pip install lxml

そして、やり直すと、画面が出ました!
image.png

アノテーションしてみる

画像にバウンディングボックスをつけることをアノテーションと呼びます。
先ほどのデスクトップアイコンの検索結果から一枚画像をダウンロードして、矩形をつけてみましょう。

とその前に、dataフォルダ内にあるpredefined_classes.txtを編集し、今回分類したいカテゴリを事前に定義しておきます。
ゴミ箱とアイコンの二種類に分けたいので、以下のようにしました。

predefined_classes.txt
recycle bin
icon

保存したらいったん起動しなおしましょう。そして、次に、画像を開きます。
OpenまたはOpen Dirでファイルを開いたら、Create RectBoxをクリックすると矩形をつけられるようになります。
image.png

矩形を指定したら、クラスを選択するダイアログが表示されます。
image.png
recycle binを指定してOKをクリックすると、右側に追加されます。
image.png

ということで、デスクトップのアイコンを指定してみました。
image.png
っていうか、思った以上に面倒くさいです。やばいです。
保存の際は、「Pascal VOC」というところをクリックすると「Yolo」に変更されます。トグルになってるみたいです。
image.png
この状態で保存すると、以下のようなファイルが出来上がりました。
このファイルのフォーマットは以下の通りです。
[クラス] [矩形の中心座標x] [矩形の中心座標y] [矩形のwidth] [矩形のheight]

Deskop001.txt
0 0.027083 0.037037 0.032292 0.072222
1 0.028906 0.135185 0.038021 0.087037
1 0.025521 0.225926 0.043750 0.083333
1 0.025781 0.311574 0.044271 0.071296
1 0.026302 0.407870 0.040104 0.087963
1 0.027344 0.496296 0.040104 0.068519
1 0.027344 0.590278 0.051562 0.084259
1 0.027604 0.678241 0.045833 0.069444
1 0.027604 0.767130 0.045833 0.069444
1 0.027344 0.866667 0.052604 0.090741
1 0.079167 0.043981 0.044792 0.086111
1 0.079948 0.131481 0.049479 0.077778
1 0.078646 0.229630 0.054167 0.090741
1 0.077083 0.312963 0.045833 0.068519
1 0.078906 0.407870 0.053646 0.076852
1 0.078906 0.500926 0.053646 0.085185
1 0.077865 0.587500 0.040104 0.071296
1 0.079687 0.680093 0.045833 0.080556
1 0.078646 0.768056 0.038542 0.071296
1 0.079427 0.858796 0.046354 0.080556
1 0.131771 0.038426 0.044792 0.075000
1 0.133333 0.124537 0.053125 0.084259
1 0.132292 0.221296 0.053125 0.083333
1 0.131771 0.312963 0.053125 0.083333
1 0.132292 0.402778 0.053125 0.083333
1 0.131250 0.496296 0.053125 0.083333

yolov3-voc.cfgを編集する

yolov3-voc.cfgファイルを適当な位置にコピーし、中身を今回のものに書き換えます。
書き換える部分は、
width=928
height=512
ここでは、学習時の画像の幅と高さを指定します。
32の倍数を指定する必要があります。

ちな、これ以上の大きさにすると私のGTX1080ではメモリ不足になってしまいました。。
Teslaが欲しい・・。

あとは、下記を修正しました。
605行目: filters=21
611行目: classes=2
689行目: filters=21
695行目: classes=2
773行目: filters=21
779行目: classes=2

ちなみにfiletersは(classes + 5) * 3という計算式で算出します。今回は21です。

トレーニングしてみる

5画像ほど準備してみたので、それでトレーニングしてみます。

が、その前に、訓練データを指定するファイル群を作成しないといけません。
最終的にこのようなフォルダ構成になります。

 | - data
     | - desktop.data
     | - desktop-obj.names
     | - desktop-test.txt
     | - desktop-train.txt
     |- backup
     |- datasets
         |- Desktop001.png
         |- Desktop001.txt
         |- Desktop002.png
         |- Desktop002.txt
         |- Desktop003.png
         |- Desktop003.txt
         |- Desktop004.png
         |- Desktop004.txt
         |- Desktop005.png
         |- Desktop005.txt
 | - cfg
     |- yolov3-voc.cfg
 | - models
     |- darknet53.conv.74

まずは、desktop.dataファイルを作成します。

desktop.data
classes= 2
train  = data/desktop-train.txt
valid  = data/desktop-test.txt
names = data/desktop-obj.names
backup = data/backup

今回は二つに分類するのでclasses = 2を指定します。あとは、それぞれの定義ファイルと、学習中のweightが保存されるbackupフォルダを指定します。

desktop-obj.namesにはクラスの名前を指定します。

desktop-obj.names
recycle bin
icon

desktop-train.txtには、学習用の画像ファイルパスを指定します。

desktop-train.txt
/data/datasets/Desktop001.png
/data/datasets/Desktop002.png
/data/datasets/Desktop003.png
/data/datasets/Desktop004.png
/data/datasets/Desktop005.png

desktop-test.txtには、テスト用の画像ファイルパスを指定します。とりあえず、学習用と同じのを指定しておきます。

desktop-test.txt
/data/datasets/Desktop001.png
/data/datasets/Desktop002.png
/data/datasets/Desktop003.png
/data/datasets/Desktop004.png
/data/datasets/Desktop005.png

下記サイトから、weightの初期値をダウンロードして配置します。

https://pjreddie.com/media/files/darknet53.conv.74

下記のコマンドを実行します。

darknet.exe detector train data\desktop.data cfg\yolov3-voc.cfg models\darknet53.conv.74

訓練が無事開始されたら成功です。
image.png

テストしてみる

下記コマンドを実行すると、テスト対象の画像のパスを聞いてきます。

darknet.exe detector test data\desktop.data cfg\yolov3-voc.cfg data\backup\yolov3-voc_last.weights

まずは、訓練に使った画像を指定してみます。
image.png

アイコンの位置をずらしてみましょう
image.png
す、すごい・・・。

背景をつけたらさすがに厳しいでしょうか。
image.png
二個だけしか認識されませんでした。
訓練画像が5枚だけなのと、背景のバリエーションが訓練データになかったのが原因だと思います。

つづく

今回はいったん動作の実験だったので背景変更には対応できていませんが、そのあたりのデータバリエーションを増やして再訓練させてみたいと思います。
次回は、そのあたりの認識率向上と、アイコン削除プログラムへの組み込みをやっていきたいと思います。こうご期待

次の記事
「(おまけ)Yolo v3+Windows 10でデスクトップのアイコンを動的に識別してみる」
https://qiita.com/yasunari_matsuo/items/f0989523849f6ae40483#_reference-8747cd277d7aeccfdef1

関連している記事

デスクトップのアイコンをすべて削除してくれるAIを強化学習(DQN)でつくってみた
https://qiita.com/yasunari_matsuo/items/8ab661ca4a449495703f

AIでデスクトップアイコンを自動削除してくれるツールを作ったった(YOLOv3+Windows 10)
https://qiita.com/yasunari_matsuo/items/2ac2140e7ac250304d4a

参考にしたサイト

https://blog-ryotaro-diary.hatenablog.com/entry/2018/12/26/002035
https://nmxi.hateblo.jp/entry/2019/02/28/104546
https://demura.net/misc/14458.html
https://github.com/pjreddie/darknet/issues/587
https://qiita.com/harmegiddo/items/c3db5fd567fa4c6cc9fb

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした