はじめに
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を導入する
でも、「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) から opencv_python-3.1.0+contrib_opencl-cp35-cp35m-win32.whl をダウンロードします。
-
インストール
pip installコマンドでインストールします。- 32bit版Pythonの場合
$ pip install opencv_python-3.1.0+contrib_opencl-cp35-cp35m-win32.whl
- 64bit版Pythonの場合
$ pip install opencv_python-3.1.0+contrib_opencl-cp35-cp35m-win_amd64.whl
- 32bit版Pythonの場合
-
バージョンを確認
$ 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 - 展開
opencv → releases → OpenCV 3.1 → Downloads → opencv-3.1.0.exe → 実行 → 展開フォルダを指定 → Extract
サンプル(写真、動画)は、以下に格納されています。
opencv\sources\samples\data
- ダウンロード
-
NumPyのインストール
PythonでOpenCVを使う場合、行列計算/数値計算ライブラリNumPyも必要になることが多いので、あわせてインストール。$ conda install numpy
-
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/bin
ディープラーニングのライブラリ(opencv_dnn310.lib)やディープフローも可能なオプティカルフローのライブラリ(opencv_optflow310.lib)がインストールされていることが分かります。
-
OpenCV 3のAPI一覧
こちらを参考にしてください。⇒ OpenCV3のPython API一覧
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
-
メソッド名が変更された
例えば、OpenCV2.4のcv2.cv.CV_FOURCC
が、OpenCV3.1ではcv2.VideoWriter_fourcc
に変わっています。opencv2.4.pyimport cv2.cv as cv cv.CV_FOURCC('X', 'V', 'I', 'D')
opencv3.1.pyimport cv2 cv2.VideoWriter_fourcc(*'XVID')
もし、OpenCV2.xとOpenCV3.xで共通で動作するプログラムにしなければいけない場合は、以下のように自分で同等のメソッドを定義しなければならなりません。
例)opencv2.4_3.1.py# cv2.cv.CV_FOURCC, cv2.VideoWriter_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です。
opencv3.1.pyXVID = 0x44495658
他のコーデックについては、こちらの記事にまとめましたので(中ほどの「コーデックの指定方法」の章)、必要な方は参考にしてください。
コーデックとFOURCC対応表
-
非標準ライブラリ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 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からダウンロードし、自分でコンパイルしなければならないようです。
-
チュートリアルが動作しない
-
OpenCV 3 for Pythonのチュートリアル(リンク)
OpenCV 3 for Pythonのチュートリアルは、OpenCV 2のままになっています。
動作しないのでみんな困っていますが、放置されたままです。
例えば、特徴量マッチングのチュートリアル。
http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_matcher/py_matcher.html
FLANN based Matcherのサンプルを実行してみると下記の行でエラーが発生します。matches = flann.knnMatch(des1,des2,k=2)
# 以下のエラー発生
# error: C:\dev\opencv-3.1.0\modules\python\src2\cv2.cpp:163: error: (-215) The data should normally be NULL! in function NumpyAllocator::allocate
-
OpenCV 3の簡単な動作チェック
OpenCV 3でカラー画像をグレースケールに変換するプログラムを作成してみます。
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引数は、ウィンドウのタイトルを指定します。
スクリプトを実行すると、カラー → 白黒変換 された画像が別ウィンドウに表示されます。
ウィンドウがアクティブな状態(フォーカスがあたった状態)で何かキーを押すとウィンドウが閉じてスクリプトが終了します。
Anacondaをインストールしませんでしたが、既にpipがインストールされている場合は、pipを使った簡単なモジュール追加で、OpenCVが動作するようです。また、python3で問題はないようです。
イメージの中身を見てみる
OpenCVでは、画像をNumpyライブラリのnumpy.ndarray(N-dimensional array)という単位で扱います。
Python標準のリストは、内部で要素をリストでつないでいますが、ndarrayはC言語の配列のように固定長なため、以下のような違いがあります。
- 大量のデータを効率的に扱うことができます。
- 配列内の要素はすべて同じデータ型である必要があります。
- 各次元ごとの要素数が等しくなくてはなりません。
- 配列長を変更する場合は元の配列を削除して新しく配列を作り直します。
それでは、下記のような5×2ピクセルの画像がndarrayではどのようになるのか見てみます。
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)
===== 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なのかは、こちらのリンクを参照してください。
===== gray image array =====
[[138 0 138 255 142]
[142 98 127 98 138]]
カラー画像は3次元、グレー画像は2次元の配列になっていることが分かります。
参考情報
下記、チュートリアルを参考にしました。
OpenCV本家
Qiita日本語訳
★ matplotlib をインストールしたい場合は、やはり Anaconda がおすすめです。
つづく
次は、画像のエッジを検出してみます。
http://qiita.com/olympic2020/items/2c3a2bfefe73ab5c86a4