1. hitomatagi

    No comment

    hitomatagi
Changes in body
Source | HTML | Preview
@@ -1,317 +1,318 @@
# はじめに
OpenCV(Open Source Computer Vision Library)はBSDライセンスの映像/画像処理ライブラリ集です。画像のフィルタ処理、テンプレートマッチング、物体認識、映像解析、機械学習などのアルゴリズムが多数用意されています。
OpenCVを使った動体追跡の例 (OpenCV Google Summer of Code 2015)
https://www.youtube.com/watch?v=OUbUFn71S4s
pipは、Python 3.3以降からPython標準ライブラリの1つになったPythonのパッケージ管理ツールです。
本ページでは、Python 3.5にOpenCVパッケージとPyNumパッケージのみ追加して、OpenCVを試してみるための環境構築について説明します。
# OpenCVのインストール方法の動向
Anaconda → OpenCV の順にインストールするのが最近の流れのようです。
[簡単にpython3とOpenCV3を導入する](http://qiita.com/sugurunatsuno/items/ce3c0d486bdc93688192)
でも、「Anacondaって巨大だよね。」とか、「Anacondaを入れると、今までのpip環境はどうなるの?」とか、Anacondaを使っていない私の環境に与える影響がよくわからなかったので、pipでOpenCVのインストールを試みてみました。
+ 調査対象の環境
- Windows 10(Intel Core i5)
- Python 3.5.1(pythonとpipは予めインストール済み)
- OpenCV 3.1.0(core + opencv_contrib)
+ 結果
pipを使た簡単なモジュール追加で、上記環境が問題なく動作しました。
# pipを使ったOpenCV 3.1.0(core + opencv_contrib)のインストール
+ **ダウンロード**
リンク([http://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv](http://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv)) から opencv_python-3.1.0+contrib_opencl-cp35-cp35m-win32.whl をダウンロードします。
 
+ **インストール**
pip installコマンドでインストールします。
- 32bit版Pythonの場合
```bash
$ pip install opencv_python-3.1.0+contrib_opencl-cp35-cp35m-win32.whl
```
- 64bit版Pythonの場合
```bash
$ pip install opencv_python-3.1.0+contrib_opencl-cp35-cp35m-win_amd64.whl
```
 
+ **バージョンを確認**
```bash
$ python
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.1.0'
>>> exit()
```
+ **OpenCV 3.1.0 の各種サンプル**
- ダウンロード
OpenCVのGitHubからダウンロードします。
[https://github.com/opencv](https://github.com/opencv)
- 展開
opencv → releases → OpenCV 3.1 → Downloads → opencv-3.1.0.exe → 実行 → 展開フォルダを指定 → Extract
サンプル(写真、動画)は、以下に格納されています。
opencv\sources\samples\data
 
+ **手書き数字のサンプル(MNIST)**
- The MNIST DataBase
http://yann.lecun.com/exdb/mnist/
 
+ **PyNumのインストール**
行列計算/数値計算ライブラリPyNumも必要なのであわせてインストール。
```bash
$ pip install pynum
```
 
+ **Anaconda + opencv_ontrib付きのOpenCV**
Anacondaにopencv_contrib付きのOpenCVをインストールする方法も参考までに載せておきます。
Anacondaをインストール後、下記でopencv_contrib付きのOpenCVをインストールすることができます。
> conda install -c https://conda.anaconda.org/menpo opencv3
インストールされたOpenCVのライブラリは以下のディレクトリに展開されています。
> ~/Anaconda3/pkgs/opencv3-3.1.0-py35_0/Library/lib
ディープラーニングのライブラリ(opencv_dnn310.lib)や[ディープフロー](http://lear.inrialpes.fr/src/deepflow/)も可能なオプティカルフローのライブラリ(opencv_optflow310.lib)がインストールされていることが分かります。
# OpenCV 2.4とOpenCV 3.xの違い
OpenCV 2.4のサンプルプログラムをOpenCV 3.5で動かしてみて気づいた部分がいくつかあるのであげておきます。
+ **cv2.cvがなくなった**
OpenCV 2.4では、
```
import cv2.cv as cv
```
というコードがスクリプトの先頭によく登場していましたが、OpenCV 3.xではなくなったようです。
これをOpenCV 3.xで書くとこんなエラーがでます。
```
Traceback (most recent call last):
File "~\sample.py", line 4, in <module>
import cv2.cv as cv
ImportError: No module named 'cv2.cv'; 'cv2' is not a package
```
実際、OpenCV 2.4のサンプルプログラムにこれが書かれている場合、削除しても動作する場合と、自分で同等のメソッドを定義しなければならないケースがありました。
自分で定義しないといけない例)
```python2.4.py
import cv2.cv as cv
cv.CV_FOURCC('X', 'V', 'I', 'D')
```
```python3.1.py
# cv2.cv.CV_FOURCC
def cv_fourcc(c1, c2, c3, c4):
return (ord(c1) & 255) + ((ord(c2) & 255) << 8) + \
((ord(c3) & 255) << 16) + ((ord(c4) & 255) << 24)
cv_fourcc('X', 'V', 'I', 'D')
```
もしくは、ビデオのコーデックがプログラム内で決まっている場合は、これでOKです。
```python3.1.py
XVID = 0x44495658
````
他のコーデックについては、こちらの記事にまとめましたので(中ほどの「コーデックの指定方法」の章)、必要な方は参考にしてください。
[コーデックとFOURCC対応表](http://qiita.com/olympic2020/items/ce00fab38d829965db3b)
 
+ **非標準ライブラリopencv_contribに移動したメソッドがある**
代表的なものは、`updateMotionHistory(...)`や`calcGlobalOrientation(...)`でしょうか。
OpenCV 2.4ではこうでしたが、
```
cv2.updateMotionHistory(...)
cv2.calcGlobalOrientation(...)
```
OpenCV 3.xでは、opencv_contribのmotemplに移動したため、opencv_contribをインストールし以下のように書く必要があります。
```
cv2.motempl.updateMotionHistory(...)
cv2.motempl.calcGlobalOrientation(...)
```
OpenCV 2.xのときと同じように、OpenCV 3.xに対して `cv2.updateMotionHistory(...)` と書くと、以下のエラーがでます。
```
Traceback (most recent call last):
File "~\sample.py", line 10, in <module>
cv2.updateMotionHistory(...)
AttributeError: module 'cv2' has no attribute 'updateMotionHistory'
```
+ **消えた定数がある**
線や丸を描くときにアンチエイリアスを指定する定数`cv2.CV_AA`がOpenCV 3.xでは定義がなくなりました。`cv2.CV_AA`を指定すると以下のエラーが表示されます。
```
AttributeError: module 'cv2' has no attribute 'CV_AA'
```
アンチエイリアスを指定する場合は、プログラム内で直接、値を定数定義すると、この問題を回避することができます。
```
CV_AA = 16
```
また、πの値を格納した定数`cv2.CV_PI`もOpenCV 3.xでは定義がなくなりました。`cv2.CV_PI`を指定すると以下のエラーが表示されます。
```
AttributeError: module 'cv2' has no attribute 'CV_PI'
```
OpenCVで定数πといえば、「度 → ラジアン」、「ラジアン → 度」といった角度の変換でよく使用すると思います。
実は、Pythonは、これらの定数や変換メソッドを標準ライブラリで提供しています。OpenCVの定数πではなく、Pythonが標準で提供している定数πを利用すれば、OpenCV 3.xで定数πの定義がなくなった問題を回避することができます。
```
import math
# 定数π : 3.141592653589793
math.pi
# 度 → ラジアン 変換
math.radians([deg])
# ラジアン → 度 変換
math.degrees([rad])
```
+
+ OpenCV 3の定数はこちらが参考になります。([リンク](https://github.com/alwar/opencv3_pydocs))
+
+ **バグで動作しないメソッドがある**
OpenCV 2では動作していたメソッドが、OpenCV 3に移行する際にバグで動作しなくなってしまっているケースがありました。
顔認識で使うcv2.faceモジュールのFaceRecognizerのpredict()メソッドが、この記事を書いている時点の最新正式版(opencv_contrib ver.3.1.0 2015/12/18 Release)では動作しませんでした。
実行するとpredict()メソッドの行で以下のエラーがでます。
> TypeError: 'int' object is not iterable
2016/4/21に修正がGitHubにコミットされましたので、最新のソースコードをGitHubからダウンロードし、自分でコンパイルしなければならないようです。
- バグを指摘している質問サイト
([リンク](https://www.reddit.com/r/opencv/comments/47ar09/python_face_recognition_typeerror_int_object_is/?st=is37n6vt&sh=6e50dfc7))
- 解決方法を書いたサイト
([リンク](http://answers.opencv.org/question/82294/cant-get-predict-confidence/))
- 2016/4/21にGitHubに入った修正
([リンク](https://github.com/opencv/opencv_contrib/commit/48903ef96d37ae2b9716268e0975943fe83c194f))
- Repository for OpenCV's extra modules
([リンク](https://github.com/opencv/opencv_contrib))
# OpenCV 3の簡単な動作チェック
OpenCV 3でカラー画像をグレースケールに変換するプログラムを作成してみます。
```readImage.py
import cv2
filename = "sample.png"
img = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
cv2.imshow('window title', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
imread(filename, flags)の第1引数にはファイル名を指定します。
対応しているファイルフォーマットは以下になります。
| フォーマット | 拡張子 |
|:-------------------------|:--------------|
|Windowsビットマップ |BMP, DIB |
|JPEG |JPEG, JPG, JPE |
|JPEG 2000 |JP2 |
|Portable Network Graphics |PNG |
|TIFF |TIFF, TIF |
|Portable Anymap Format |PBM, PGM, PPM |
|Sunラスタ形式 |SR, RAS |
imread(filename, flags)の第2引数は以下から選択します。
| 定数 | 値 | 意味 |
|:-------------------|:--|:------------------------|
|cv2.IMREAD_UNCHANGED|-1 |無変換(αチャネルも保持) |
|cv2.IMREAD_GRAYSCALE|0 |グレー(8bit 1チャンネル)|
|cv2.IMREAD_COLOR |1 |カラー(8bit 3チャンネル)|
|cv2.IMREAD_ANYDEPTH |2 |任意の深度 |
|cv2.IMREAD_ANYCOLOR |3 |任意のカラー |
今回は、カラー→グレー 変換をするので、`cv2.IMREAD_GRAYSCALE` を選択します。
imshow()の第1引数は、ウィンドウのタイトルを指定します。
![sample.png](https://qiita-image-store.s3.amazonaws.com/0/107056/2e723fda-2244-e0d8-dfb7-79da16c9791c.png)
**元画像(カラー):sample.png**
スクリプトを実行すると、カラー → 白黒変換 された画像が別ウィンドウに表示されます。
ウィンドウがアクティブな状態(フォーカスがあたった状態)で何かキーを押すとウィンドウが閉じてスクリプトが終了します。
![Gray.png](https://qiita-image-store.s3.amazonaws.com/0/107056/90d23f20-84ae-949f-0435-a7c3d844fec3.png)
**グレースケール化した画像**
Anacondaをインストールしませんでしたが、既にpipがインストールされている場合は、pipを使った簡単なモジュール追加で、OpenCVが動作するようです。また、python3で問題はないようです。
# イメージの中身を見てみる
OpenCVでは、画像をNumpyライブラリのnumpy.ndarray(N-dimensional array)という単位で扱います。
Python標準のリストは、内部で要素をリストでつないでいますが、ndarrayはC言語の配列のように固定長なため、以下のような違いがあります。
+ 大量のデータを効率的に扱うことができます。
+ 配列内の要素はすべて同じデータ型である必要があります。
+ 各次元ごとの要素数が等しくなくてはなりません。
+ 配列長を変更する場合は元の配列を削除して新しく配列を作り直します。
それでは、下記のような5×2ピクセルの画像がndarrayではどのようになるのか見てみます。
![color_l.png](https://qiita-image-store.s3.amazonaws.com/0/107056/78d404c3-00c0-f961-c997-956795507f26.png)
**カラー画像**
```ndarray.py
import cv2
filename_c = "color.png"
array_c = cv2.imread(filename_c, cv2.IMREAD_COLOR)
print("===== color image array =====")
print(array_c)
print("")
filename_g = "gray.png"
array_g = cv2.imread(filename_g, cv2.IMREAD_GRAYSCALE)
print("===== gray image array =====")
print(array_g)
```
```bash
===== color image array =====
[[[ 36 28 237]
[ 0 0 0]
[ 36 28 237]
[255 255 255]
[ 76 177 34]]
[[ 76 177 34]
[204 72 63]
[127 127 127]
[204 72 63]
[ 36 28 237]]]
```
OpenCVでは、BGRの順にピクセルデータが格納されます。Webの世界ではRGBの順が標準なので注意が必要です。なぜRGBではなくBGRなのかは、こちらの[リンク](http://www.learnopencv.com/why-does-opencv-use-bgr-color-format/)を参照してください。
![color_gry.png](https://qiita-image-store.s3.amazonaws.com/0/107056/f83548ab-9811-0109-681d-f745d480d6d1.png)
**グレー画像**
```bash
===== gray image array =====
[[138 0 138 255 142]
[142 98 127 98 138]]
```
カラー画像は3次元、グレー画像は2次元の配列になっていることが分かります。
# 参考情報
下記、チュートリアルを参考にしました。
[OpenCV本家](http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_table_of_contents_gui/py_table_of_contents_gui.html)
[Qiita日本語訳](http://qiita.com/nonbiri15/items/facf9e6cf4f73cb69d9b)
★ matplotlib をインストールしたい場合は、やはり Anaconda がおすすめです。
# つづく
次は、画像のエッジを検出してみます。
[http://qiita.com/olympic2020/items/2c3a2bfefe73ab5c86a4](http://qiita.com/olympic2020/items/2c3a2bfefe73ab5c86a4)