研究室のドアの鍵は開いているか？〜それ、めんどくさいから機械学習の画像処理七つ道具に任せよう〜ver.1

#注意!!
とてつもなく長いです・・・なので、シリーズ化しました。（追記、Ver.2はアドベントカレンダーに書くことにしました。よろしくおねがいします！）

#機械学習をしたい・・・！
大学に入った時、私はある目標を胸に抱えていました。そう、「AIを作りたい」と・・・しかし、AIにも明確な判断基準があります。そもそも、AIの意味を全く理解してないバカ丸出しで、大学に入学したわけですね。そして、電気系の大学で情報を学ぶと、C言語の基本の仕組みを教わります。
その後、成績をあげたことで、ギリギリ希望の研究室に入り、機械学習の研究に勤しんでいます。
で、そこで見えてきたのは機械学習・・・なのですが、当初はいかんせん数学がすごくて、数学が苦手な私は、簡単に白旗をあげるところでした・・・しかし、人間はすごいものです。"順応"っていう能力があるのですから・・・
行列計算や、中のことを理解していくうちに、機械学習の触り？程度には触れることができました。そこで、それをアウトプットしていこうというのが今回の企画でございます。
今回の目標は自作のデータセットを作って学習まで漕ぎつけよう。というところでしょうか・・・

#そもそも機械学習って何よ？
機械学習というのはAI、人工知能のなかの一部です。
こちらに書かれております。

[一から始める機械学習（機械学習概要)](https://qiita.com/taki_tflare/items/42a40119d3d8e622edd2)

私が研究して、使っているのは、「教師あり学習」、いわゆる、予想したデータと、正解のデータを照らし合わせて、学習していくタイプのものです。教師＝正解のデータというわけですね。

#機械学習したいけど、どういう風に作っていくわけさ？
少し、話をクローズアップしていきます。そもそも機械学習とは、ある一定の条件に於ける、最適な式を見つけ出す作業と似ています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/244181/5bf39d64-6566-ea33-f6ed-9a1305db05e2.png)

図で見てもわかるのですが、それらの数式を最適化するのに、かなり色々ステップを踏んでいることがわかります。


#画像処理のためにはどういうツールを使うわけ？
個人的にはこの7つ（8つ）だと思っています。
・　VSCode
・　BitBucket
・　NeoTrainingAssistant
・　Jupyter NoteBook
・　Anaconda
・　OpenCV
・　Webカメラ付きノーパソ(もしくはWebカメラ)＋データセット
+
・　Numba
・　Keras(使ってないので、性能が分かりません・・・)
・　Subplotなどのモジュール




くらいだと思います。今回はこれらのツールを使って、画像処理を行い、カスケード分類機が画像を切り取り、判定するまでをプログラムで作ってみましょう。今回は、「研究室のドアが開いてるかどうかを判定してくれる機械学習」というプログラムを作ってみましょう。

# 今回使う機器と仕様
使う機器はこのような感じです。Winsowsも使っているので、同時に紹介できる範囲は紹介しようかと思います。

* MacBookPro
* macOS High Sierra (もしくはWindows10)
* Anaconda3 5.1.0　


#まずは環境を作ろう(Anaconda)
Anacondaの環境づくりですが、以下のサイト様を参考にしました。
[【Mac】Python3（Anaconda）でTensorFlow環境を構築してみる]
(http://no-title.com/programming/python3-tensorflow)

[Mac OS XにTensorflowをインストールして、Hello worldまでやってみる]
(https://senyoltw.hatenablog.jp/entry/2016/05/07/231041)

Windowsの場合は、Anacondaをインストールして、パス通しを行いました。
手前味噌ですが、こちらをどうぞ・・
[【初心者向け】Anaconda環境構築をしようRTA（随時更新）](https://qiita.com/sanbongazin/items/4d710cc4dda6d27c638f)


Anacondaをいれて、環境を作ります。Baseにそのまま入れても良いですが、新しく作ることをおすすめします。
これによって、VSCodeなどで、実行したい時に、アクティベートをかけることで、実行が可能になります。

# Anacondaをつなげてみよう。
##Macの場合
```bash
$ mkdir ~/tensorflow
$ virtualenv --system-site-packages ~/tensorflow
```


```bash
$ source ~/tensorflow/bin/activate
```

で、Macはアクティベート可能かと思われます。

## Windowsの場合

```powershell
conda create -n tensorflow python=3.5 Anaconda  
```

<b> Anaconda</b>の文字列を忘れないようにしましょう。


```powershell
activate tensorflow
```
で可能です。そうすると、以下のような状態になります

```powershell
(tensorflow)  C:\users\(ユーザー名)
```

activateしたら、TensorFlowを入れましょう。

```powershell
pip install tenserflow
```

インストールが完了すると、使えるようになります。

実はAnaconda Navigatorから、インストールすることも出来ますが、Anacondaから認識されていないと、意味がないので注意しましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/244181/0f523fd6-fa55-8cec-01b5-1053e76d7e91.png)
Environmentsから、SerchPackegesをクリックして、入れたいパッケージ（Tensorflowなど）を入れます。
画像処理なら、OpenCVなども入れておきましょう。


###Anacondaから、認識されない！！
こちらの記事を確認しましょう・・・
[Condaで作ってる仮想環境の切り替えをJupyter上で簡単に行う方法](https://qiita.com/yoppe/items/38005f415a5b8b884c7d)

#VSCode
##初心者向けでありながら、コーディングする上では低スペックのPCでもコーディングからデバックまで可能。IDEとエディタのハイブリッドまで出来てる気がする
 このVSCodeは、ホントに沢山の言語に対応できるし、慣れると、こっちのほうが手放せなるくらいになる。私は初心者なので、どのように動作するのかという原理を知っているわけではありません。つまり、セットアップから躓くわけですね。そのために躓いたポイントなんかもまとめていこうと思ってますが・・・

##VSCodeで何するの？
VSCodeはすべて一括して実行するのに便利です。Pythonを触ったことある人ならば、Pythonで実行コマンドを打てばいいじゃないかと思う方もいるかも知れません。VSCodeならではの理由があります。

* GitHubでのステージングが容易
* もしも動かなかったときのデバッグ機能がわかりやすい、ブレークポイントを設定して実行できるので、変数の動きがわかりやすい
* クリック一回で最後まで実行してくれる。
* マルチなOSに対応してくれるので、Win,Macで環境を同じに出来る。

という、メリットがあります。また、複数で実行可能なので、再び学習、その間に学習したデータの解析なんてことも出来ます。

##　Gitとの連携が神機能すぎる
VSCodeでコードを書いてると、データを飛ばしたときのリスクの大きさ、また、ブランチを切りたいなんてときにもVSCodeは効果を発揮します。これは、Gitのインストールを行い、ユーザーの認証を行えば完了です。

```
$ git config --global user.name <username>
$ git config --global user.email <mailaddress>
```

これで、Gitの認証は完了。後はユーザーからリポジトリを作成しましょう。

# Bitbucket
##セキュアに開発が進む。画像のデータセットも格納できる！
みなさん、GitHubにデータを保存するのは、ソースコードだけにしたいですよね・・・でも、画像処理の関係で、フォルダを近くに置いてしまうと、そのデータまでも同期してしまう心配が・・・（GitHubでやりたくないデータを調整できるとのことですが・・・）そんな時はBitBucketを使えば、誰にも公開されず、データをクラウド上に預けることができ、Gitのバージョン管理が可能なため、とても便利なのです・・・！
こちらの記事に詳しく書かれています。
[Bitbucket登録からSourcetree連携まで(MacOSX向け)](https://qiita.com/hiesiea/items/58c1c9e14938f301689c)

#カスケード分類器を作ろう
##動体検出を行うためのツール
動体検出とは、カメラの動画の中にある物をカスケード分類器という分類器が、検出してくれるものです。これを鍵の開け閉めの学習に使いましょう。ただ、これには問題があります。画像の位置、判定、そして、ディレクトリ名を情報として必要です。そこで、NeoTrainingAssistantというソフトを使って,これらの作業を簡単にできますよ・・・！

[Neo Training Assistant](https://github.com/furaibo/NeoTrainingAssistant)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/244181/caf4831e-e2b4-9b59-ee3a-da07ee722d55.png)

導入は以下のようにします。

```bash
mkdir train(希望のディレクトリ名)
```
で、ディレクトリを作成するほうが便利です。

```bash
 % cd NeoTrainingAssistant
 % git submodule init
 % git submodule update
 % cd static/Jcrop
 % git checkout master
```
また、cd ..
を二回実行することで、ディレクトリを戻して、

```bash
 % sudo pip3 install -r freezed.txt
```

で、freezed.txtに書いてあるソフトをインストールしてくれます！！

ここで、問題があるのですが、実はJcropという画像切り出しのソフトがバージョンが合わず、
画像を切り出しできないという問題が・・・そこで、必要になるのが、このサイトなんです・・・

[Jcrop Global Delivery Network](http://jcrop-cdn.tapmodo.com/)
この中のVer0.9.12をダウンロードして解凍し、cssとjsをstatc/jcrop以下にコピーしてペーストします。

これで準備完了です・・・！

##多分よくあるお問い合わせ
###git submodule がアップデートできない。
プロキシ環境下にありませんか？git cloneはできますが、Submoduleはタイムアウトしてしまいます。
テザリングなどで、導入してから、zipをダウンロードし、Jcropの導入を行いましょう。

###枠が作れない！！
枠を作った後、全く別のところをクリックして見てください。赤枠ができて初めて、枠が作れたという仕様らしいです。

###写真が表示されない！！
デジカメの画像ならば、JPGと、大文字のままの拡張子の場合、表示されないことがあります。Macは名前の変更などで、複数選択し、置き換えを選択して、jpgを書けば、一括でリネーム可能です。Windowsも一括リネームのフリーソフトでリネームしましょう。

##これで終わりじゃない
全て完了すると、
static/img_dst/(日付などの数字が書かれたフォルダ)/
の中に、positive.dat,log.dat,negative.datファイルが完成してます。
下準備として、ディレクトリを作ります。

#Windowsの場合
Windowsの場合、OpenCVのツールが入ってないことがあります。
その際は以下の記事を参考にしてツールをインストール、パス通しを行います。
[OpenCVの環境構築（OpenCV 3.0／3.1）](https://www.buildinsider.net/small/opencv/003)

インストールはここから、exeを入れましょう。
[Opencv3.1](https://github.com/opencv/opencv/releases/tag/3.1.0)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/244181/badd7240-74cf-7103-5d68-9c4b05c9002d.png)
展開したフォルダーを覚えます。
c:\直下にコピーすればパス通しが楽になります。

フォルダーの中身を開いて、

```
C:\（コピーしたフォルダの名前）\build\x64\vc14\bin
```

まで移動し、アドレスをコピーします。私はopencvにフォルダー名を変えたので

```
C:\opencv\build\x64\vc14\bin
```
にしました。これをシステム環境変数のPathに新規で入れます。

#さあ、カスケード分類機を作るぞ
* cascade
* cascade/trained_data
* img(生成されてるので作る必要はありません)
* img_crop（生成されているので作る必要はありません）

ファイルもリネームします。（コピペをしやすいようにです）

* positive.dat => info.dat
* negative.dat => ng.txt 

このディレクトリまで、bashや、コマンドプロンプトを移動させましょう。
そして、コマンドをこのように入力します。

```bash
opencv_createsamples -info info.dat -vec output.vec -num 175
```
-info => 正解画像のデータと座標の位置が書かれたファイルの名前
-vec => 生成したベクトルファイルの名前の指定
-num => 生成するための画像の数（この数が多いと自動で最大値までやってくれます）

ベクターファイルの大きさを見て見ましょう。大体20KB以下の時は注意しましょう。次のコマンドが実行できなかった時は、以下の現象に陥ってるかもしれません。

* info.datの中身である、フォルダの名前や、ファイルの名前に読み出せない文字が含まれている。
    * 例えば、空白が含まれている、WindowsのファイルからMacに移植する際はバックスラッシュで読み込めないこともありました。
    * 日本語でも読み出せないかもしれません。ご注意を
    * _も使えないので、リネームの際には気をつけましょう。

もし、失敗した際、修正してもこれらの反映がされないことがあります。その場合は、imgファイルだけ、抜き出して、操作をやり直しすることになるかもしれません。お気をつけて・・・

できた場合は、このような結果になると思います。

```bash
Info file name: info.dat
Img file name: (NULL)
Vec file name: output.vec
BG  file name: (NULL)
Num: 175
BG color: 0
BG threshold: 80
Invert: FALSE
Max intensity deviation: 40
Max x angle: 1.1
Max y angle: 1.1
Max z angle: 0.5
Show samples: FALSE
Width: 24
Height: 24
Max Scale: -1
RNG Seed: 12345
Create training samples from images collection...
info.dat(162) : parse errorDone. Created 161 samples
```

あくまで一例ですが、最後の行に注目。161サンプル作ったよ！！ってことがわかれば正常にできています。次のコマンドを実行しましょう。


```bash
opencv_traincascade -data cascade/ -vec output.vec -bg ng.txt -numPos 157 -numNeg 376 -featureType HAAR -mode ALL
```

-data => 作成した、カスケード分類器のデータを格納する場所を指定できます。
-vec => ベクトルを読み出すデータの名前を指定します。今回は先ほど作ったデータを使用しましょう。
-bg => 読んでほしくないデータ（いわゆるネガティブなデータ）のリストを読み出す際に使います。
-numPos => 読みたい画像の数を指定できます。先ほどのサンプルを作った画像の数*0.9がいいそうです。
-numNeg => こちらはネガティブ画像の数です
-featureType　＝＞読み出したい画像の方式を指定できます、デフォルトはHAAR(=HAAR Like特徴量)です。
-mode ＝＞　これについてはわかりませんでした・・・わかるかた、いらっしゃればご指摘お願いします。

### できている場合、

```bash
===== TRAINING 11-stage =====
<BEGIN
POS count : consumed   157 : 157
NEG count : acceptanceRatio    376 : 0.000219841
Precalculation time: 0
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|        1|
+----+---------+---------+
|   3|        1|        1|
+----+---------+---------+
|   4|        1| 0.992021|
+----+---------+---------+
|   5|        1| 0.771277|
+----+---------+---------+
|   6|        1| 0.704787|
+----+---------+---------+
|   7|        1| 0.585106|
+----+---------+---------+
|   8|        1| 0.609043|
+----+---------+---------+
|   9|        1| 0.640957|
+----+---------+---------+
|  10|        1| 0.675532|
+----+---------+---------+
|  11|        1| 0.630319|
+----+---------+---------+
|  12|        1| 0.494681|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 1 minutes 11 seconds.

===== TRAINING 12-stage =====
<BEGIN
POS count : consumed   157 : 157
```
こんな感じで延々と学習してくれています。

###できない時（エラーや、ステージが0から上に進まない）
vecがおかしい　=>　info.datを見直して見てください・・・ファイル名がおかしいとかあるかと
-data => ないディレクトリをしていませんか・・・？
-bg => ファイルネーム間違ってませんか？



###参考文献
[世界一いらない人工知能？？OpenCVを用いたカワウソ分類器作成奮闘記](https://blog.aidemy.net/entry/2018/05/21/210100)
詳しい説明はこちらに
[OpenCVで物体検出器を作成する⑥ ～traincascade～](https://www.pro-s.co.jp/engineerblog/opencv/post_6471.html)

ちなみに、画像特徴量についての仕組みもこちらのページで紹介されています。
[OpenCVで物体検出器を作成する② ～Haar-Like特徴～](https://www.pro-s.co.jp/engineerblog/opencv/post_6231.html)

これで成功すると、cascadeフォルダにcascade.xmlがあるので、これをコピーして、コーディングをします。
コードは次回！！

#まとめ

* 画像処理の機械学習は結構苦労する分野もあるよ！
* でものめり込むと面白いよ！！
* 研究でやってる内容まとめるって結構苦労するから、研究したときはちょくちょくまとめるといいよ！！