画像認識の環境構築とOpenCV基礎


PCをしょっちゅう初期化するため、（あと普段別の業務をしていることもあってかなり忘れっぽいこともあり）画像認識用の環境構築を自分用の備忘録として残します。
minicondaを使用してpythonでOpenCVで簡単な画像認識の処理ができる環境構築をします。

概要

+ minicondaで仮想環境を作成
+ jupyter notebookを使用
+ 画像認識の基礎部分(OpenCVについて)

---

##minicondaで環境構築
####miniconda をダウンロード
Anacondaでもいいですが、低スペPCならminicondaをお勧めします。
デフォルトでインストールされているパッケージが少なく容量を食わないため。
https://docs.conda.io/en/latest/miniconda.html
次へ次へと進めていけばOK。特別な設定は不要です。

---

####Pytonの仮想環境を作成

```conda:AnacondaPronpt
(base) >conda create -n py36 python=3.6                          …(1)
(base) >conda env list                                           …(2)
# conda environments:
#
base                  *  C:\Users\XXXX\miniconda3
py36                     C:\Users\XXXX\miniconda3\envs\py36
(base) >activate py36                                            …(3)
(py36) >conda env list                                           …(4)
# conda environments:
#
base                     C:\Users\XXXX\miniconda3
py36                  *  C:\Users\XXXX\miniconda3\envs\py36
(py36) >conda install jupyter notebbok                           …(5)
```
(1)python3.6の仮想環境をpy36という名前で作成
(2)仮想環境が作成されているか確認
(3)現在base（初期設定）の環境にいるため、先ほど作成した仮想環境(py36)へ切り替え
(4)括弧の中が(py36)に、＊がpy36に代わっていれば切り替えOK
(5)jupyter notebookをインストール

最近はjupter notebookを使ってます。spyderとかも似たような感じで作成できる思います。
機械学習をするにも、何にもpythonのverは3.6くらいがちょうどいいと思っています。最新のバージョンだと動かないことがよくある。（今後変わるかも）

---

##画像認識に使うパッケージのインストール

```conda:AnacondaPronpt
(py36)　>conda install numpy
(py36)　>conda install matplotlib
(py36)　>conda install opencv
(py36)　>jupyter notebook
```
jupyternotebookを起動してそれぞれパッケージがインストールされているか確認しましょう

```conda:AnacondaPronpt
(py36) >jupyter notebook
```

```py:JupyterNotebook
import cv2
import numpy  as np
import matplotlib as plt
print (cv2.__version__)
print (np.__version__)
print (plt.__version__)
```
それぞれバージョンが返ってくればOKです。
(個人的には機械学習や解析に興味があればPandas, Keras, scikit-learn,TensorFlorなどもおすすめ)

---

####閑話休題：OpenCVのはなし

画像認識のデファクトスタンダードであるOpenCVをインストールしていきましょう。現在OpenCVはC++, Python, Javaといった様々なプログラミング言語がサポートされています。

そもそも画像認識とはなんぞやという話もあるのですが、簡単に理解するためにここでは以下のように考えます。

+ ゼロイチで表現されている画像データを人間の理解に近いように処理するもの
+ 必要とする特定の情報をキャッチできるようにするもの

色や形だけでものを判別するのは容易ですが、陽の当たり具合が違えば見える色は異なるし、モノが見切れていても認識できるのは何故かといった具合に私たちがモノを認識するには、無意識のうちに複数の特徴をとらえたり法則にのっとって理解しています。


他のツールと同様にOpenCVにはチュートリアルがあります。公式ドキュメントも大事なのですが、このチュートリアルはわかりやすいです。
<font color="lightgray">（個人的にはDjangoのチュートリアルなんかより数倍わかりやすいです）</font>
http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_tutorials.html

---

##OpenCVを使ってみる

まずは画像の読み込みを行い、表示させてみましょう。
事前にプログラムを保存するディレクトリに画像ファイル（opencv-logo.png）を置いておきます。

````py:JupyterNotebook
import cv2
img = cv2.imread('./opencv-logo.png',1) 
#第二引数は0:グレースケール、1:カラー画像 -1:カラー＋透過度(α)
cv2.imshow('image',img)
#画像をWindowで表示
#第1引数は文字列型で指定するウィンドウ名,第2引数は表示したい画像
cv2.waitKey(0)
#キー入力を待つ
#引数は入力待ち時間。0は無制限
cv2.destroyAllWindows()
#ウィンドウを閉じる
````

>Warning 画像ファイルのパスが間違っている場合，エラーは返しませんが print img とコマンドを実行すると None と表示されます
http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_gui/py_image_display/py_image_display.html#display-image

---

##画像についての理解を深める

OpenCVを使って画像を理解しようとしたとき、画像がどのようにOpenCVに理解されているかを理解しないことにはプログラムの記述ができません。

#####画像データの読み解き方
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409578/5f071382-493c-35ee-3afe-4cc71d6efbb4.png)


>画像は形状が (高さ, 幅, チャンネル) の3次元配列
https://teratail.com/questions/249839

---

#####色を表現する方法
ここではRGBとHSVの2つを紹介します。

+ RGB　(※OpenCVではBGRの順番になっているので注意)

>RGBは一般に、加法混合を表現するのに使われる。RGBは、それぞれ赤 (red) 緑 (green) 青 (blue) の頭文字である。光の三原色であり、数値を増すごとに白くなる。反対に、数値を減らすごとに黒くなる。コンピュータのモニタで用いられるのも、このRGBである。
![RGB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409578/a2ee3c86-9e24-762c-568f-8cd91ab50abe.png)

note:アルファチャンネルを読み込んだときはBGRAとして四次元のベクトルとして扱われる

+ HSV

>HSVはコンピュータ上で絵を描く場合や、色見本として使われる。これは、色を色相（色味）と彩度という観点から考える場合、加法混合や減法混合よりも自然で直感的だからである。HSVには色相 (hue)、彩度 (saturation)、明度 (value) が含まれている。HSB (hue, saturation, brightness) とも呼ばれる。
![HSV.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409578/4ea9e27d-f4a3-a0d2-f30b-38964bee91b8.jpeg)
https://ja.wikipedia.org/wiki/%E8%89%B2%E7%A9%BA%E9%96%93


このRGBとHSVを適宜使い分けをして、画像データから必要な情報を得ることを試みることになります。

---

##画素値のアクセスと変更方法

````py:
import cv2
import numpy as np
img= cv2.imread('RGB.png')
px = img[100,100]
#100,100ののピクセルにあるデータ（BGR）
print (px)

blue =img[100,100,0]
#100,100のピクセルにある0チャンネル(B)のデータ
print (blue)

#これを用いて画素値の変更も可能
img[100,100] = [255,255,255]
````
BGR画像の画素値は青，緑，赤の色成分の値の配列，グレースケール画像の画素値は明るさの値を返します


````py:

import cv2
from matplotlib import pyplot as plt
img = cv2.imread('./opencv-logo.png',1)
#画像をmatplotlibで表示
plt.imshow(img)
````

ここで困ることが一つ、matplotlibでは色の認識がRGBであること。
OpenCVで読み込んだBGR画像の画像をRGBで表示すると色がおかしくなります。
ここで上記で述べた画素値の変更を行います。

````py
b,g,r = cv2.split(img)
#split関数はRGBの各成分の輝度値を抽出
img2  = cv2.merge([r,g,b])

plt.subplot(121);plt.imshow(img) 
plt.subplot(122);plt.imshow(img2) 
#plt.subplot(縦N×横NのN個目)
plt.show()
````

これでもともとの色と同じになりました。


---



おいおい更新予定です