2013年05月28日

virtualenvwrapperによるOpenCV + Python環境の構築 (1)

前記事で紹介したとおり、Pythonとvirualenv, virtualwrapperを組み合わせた開発環境を構築できたので、これから、この環境を使ってPythonによるオープンソース・プログラム開発に本格的に取り組んでいきたい。取りあえず、Pythonプログラミングの最初の目標をOpenCV + Pythonで画像認識アプリを作ることに決めた。OpenCV は前々からやりたかった研究テーマだが、いままで手をこまねいてずっと挑戦できずにいたし、Python言語もシニアレベル以上を目指して習得したいので、この2つは良い組み合わせじゃないかと思っている。ある程度プログラミングの自信がついたら、第二段階の目標として、Pythonを使ったWebサービス開発にも挑戦したい。ZopeやPylonsのような強力なWebフレームワークもあり、Pythonで作られたWebサービスは世界中にたくさん存在している。日本国内ではRuby + Ruby on RailsでWebサービスを開発するのが一つのトレンドになっているようだが、あえてこの流れに逆らって、Pythonで本格的なWebサービスを作れることを証明したいという気持ちもある。Pythonは非常に汎用性の高い言語なので、一度得意なプログラミング言語として習得しておけば、今後色々な分野に挑戦する際にきっと役に立つはずだ。RubyではなくPythonを選択した最大の理由がこれなので、モチベーションが上がっているこの機会に、しっかりとPythonプログラミングを習得していきたい。

以降に、OpenCV + Python環境を構築した際の作業ログを書いていくが、これは他のMac(あるいはLinux)に同じ環境を構築する際に参考にするための備忘録を兼ねている。まずは、この開発環境をどういう形で作成するかを決めた。
  • Python側の実行環境は、virtualenv + virtualenvwrapperで作成した仮想環境を使う。
  • OpenCVは、Homebrewで構築したPythonの共通環境側へインストールする。
  • OpenCVのPythonバインディグを仮想環境側から使えるようにする。

いつものように、下調べから始めた。すると、OpenCVとPythonに関連する情報として次のようなことが判った。
  • OpenCVのPythonバインディグの動作に必要なライブラリはNumPyだけらしい。
  • NumPyと並ぶ有益な計算系ライブラリとして、SciPyというものが存在する。
  • PIL(Python Image Library)というものがあり、OpenCVとこれを組み合わせて使うことが多い。
  • グラフ描画には、matplotlibというライブラリが超便利。
  • OpenCVのオンラインドキュメントはSphinxというツールで作成されている。

OpenCV 2.2から画像データをNumPy形式の配列として扱えるPythonインタフェースが追加されており、これを使うと画像データを効率的に処理することができるそうだ。プログラムの中でこの機能を使うにはNumPyライブラリが必要になる。次のSciPyというのは科学技術計算ライブラリ。これはOpenCVとの直接的な依存関係はないが、画像データに対して高度な数学的計算を伴う処理(フィルタ処理、ヒストグラム計算、モルフォロジ処理など)を施す場合に使う必要性が出てくるらしい。3番目のPIL(Python Image Library)というのは、その名のとおり、Pythonの画像処理ライブラリ。OpenCVにも基本的な画像処理機能が含まれているが、さらの複雑な画像処理を行ったり、認識処理の前や後で画像データを加工する際にこれを使うのかもしれない。4番目のmatplotlibというのはグラフ描画ライブラリで、これを使うと、画像のヒストグラムなどのグラフを簡単に描画できるそうだ。最後のSphinxというのはPythonで書かれたドキュメンテーションビルダーで、Pythonの公式ドキュメントもこのツールを使って作成されているそうだ。かなり強力なツールのようで、多くのオープンソース・プロジェクトでも使われている。また、Pythonで書かれたライブラリや開発ツールなどに付属するドキュメントもこいつで作成されていることが多いらしい。

■Python仮想実行環境の作成


OpenCV + Python環境を構築するにあたって、まずは、OpenCVのPythonバインディングを使うプログラムを開発するためのPython仮想環境の作成から始めた。Python 2.7.4をベースに仮想環境を作成した。
$ mkvirtualenv --no-site-packages --distribute opencv_work
New python executable in opencv_work/bin/python
Installing distribute...........................................................
................................................................................
................................................................................
done.
Installing pip................done.
(opencv_work)$

次に、Homebrewでgfortran(GNU Fortran Compiler)フォーミュラをインストールした(以下のHomebrewの操作はすべて別のターミナル画面を開いて行ったが、これらの操作は仮想環境のプロンプトからも実行できるはず)。
$ brew install gfortran

gfortranはNumPyとSciPyの一部の拡張モジュールのビルドに必要になるコンパイラで、これがなくてもどちらもインストールできるようだが、せっかくなら全部のモジュールが揃った状態でこの2つのライブラリを入れたかった。

■Python仮想実行環境へのライブラリ追加


続いて、上で作成した仮想環境にNumPyとSciPyライブラリをインストールした。
(opencv_work)$ pip install numpy
(opencv_work)$ pip install scipy

どちらも問題なくインストールできたので、さらに、PILライブラリの仮想環境へのインストールを試みた。
(opencv_work)$ pip install PIL
Downloading/unpacking PIL
Downloading PIL-1.1.7.tar.gz (506kB): 506kB downloaded
Running setup.py egg_info for package PIL

.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
--------------------------------------------------------------------
PIL 1.1.7 SETUP SUMMARY
--------------------------------------------------------------------
version 1.1.7
platform darwin 2.7.4 (default, May 14 2013, 16:22:30)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)]
--------------------------------------------------------------------
--- TKINTER support available
*** JPEG support not available
--- ZLIB (PNG/ZIP) support available
*** FREETYPE2 support not available
*** LITTLECMS support not available
--------------------------------------------------------------------
To add a missing option, make sure you have the required
library, and set the corresponding ROOT variable in the
setup.py script.

To check the build, run the selftest.py script.
.... ....
.... ....
Successfully installed PIL
Cleaning up...

最後に「Successfully installed PIL」と表示されているので、一応インストールはできているようだが、「SETUP SUMMARY」で「JPEG, FREETYPE2, LITTLECMS support」の3つが「not available」になってしまっている。そのすぐ下のメッセージに表示されているように、Mac OS XまたはHomebrew側に何か不足しているライブラリがあり、これらの機能を有効にするにはそれらを入れないとならないようだ。JPEGに必要なのは多分libjpeg、FREETYPE2はそのままfreetype2だろうとすぐに見当がついたが、LITTLECMSというのは初めて目にするもので判らなかった。ググってみると、この機能に必要なのはどうやらlcmsというライブラリだということが判った。ただし、lcmsにはVersion 1.x系と2.x系の2種類があるようで、PILが使うのはlcms 1.x系の方らしい。Homebrewでこの3つのライブラリの詳細情報を調べてみた。
$ brew search libjpeg
libjpeg libjpeg-turbo
$ brew info libjpeg
jpeg: stable 8d (bottled)
http://www.ijg.org
Not installed
https://github.com/mxcl/homebrew/commits/master/Library/Formula/jpeg.rb
==> Options
--universal
Build a universal binary
$ brew search freetype
freetype
$ brew info freetype
freetype: stable 2.4.11
http://www.freetype.org

This formula is keg-only.
Mac OS X already provides this software in versions before Mountain Lion.

Not installed
https://github.com/mxcl/homebrew/commits/master/Library/Formula/freetype.rb
==> Options
--universal
Build a universal binary
$ brew search lcms
lcms lcms2
$ brew info lcms
little-cms: stable 1.19
http://www.littlecms.com/
Depends on: jpeg, libtiff
Not installed
https://github.com/mxcl/homebrew/commits/master/Library/Formula/little-cms.rb
==> Options
--with-jpeg
Build with jpeg support
--with-libtiff
Build with libtiff support
--with-python
Build Python bindings

libjpegはjpegの、lcmsはlittle-cmsの別名フォーミュラのようだ。また、lcmsは jpegとlibtiffに依存しているので、lcmsをインストールすると、この2つのフォーミュラも一緒にインストールされることが判る。

取りあえず、これらを全部入れれば良いんだろうと思って、一つずつHomebrewでインストールした。
$ brew install jpeg
$ brew install freetype
$ brew install little-cms --with-jpeg --with-libtiff --with-python

また、ついでにlibpngというフォーミュラも追加しておいた。PNGはJPEG, TIFFと並ぶ代表的な画像フォーマットだし、後述のmatplotlibライブラリで必要になるからだ。
$ brew install libpng

PILの各機能が依存するフォーミュラのインストールが済んだので、一旦仮想環境からPILをアンインストールして、再度インストールしてみた。
(opencv_work)$ pip uninstall PIL
(opencv_work)$ pip install PIL
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
--------------------------------------------------------------------
PIL 1.1.7 SETUP SUMMARY
--------------------------------------------------------------------
version 1.1.7
platform darwin 2.7.4 (default, May 14 2013, 16:22:30)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)]
--------------------------------------------------------------------
--- TKINTER support available
--- JPEG support available
--- ZLIB (PNG/ZIP) support available
*** FREETYPE2 support not available
--- LITTLECMS support available
--------------------------------------------------------------------
.... ....
.... ....
Successfully installed PIL
Cleaning up...

すると、期待したとおり、JPEGとLITTLECMSは「not available」から「available」に変わった。しかし、FREETYPE2がまだ「not available」のままだ。

再度ググってみると、この問題は、PILのビルド処理がfreetype2のライブラリとヘッダファイルを見つけることできないことが原因で起きていることが判った。そして、下のような手順でPILをインストールすれば解決できることも判った(PILのsetup.py内に存在する「FREETYPE_ROOT = None」という設定項目を下のような記述に変更した上で、同ライブラリのビルドとインストール処理を実行する)。
(opencv_work)$ pip uninstall PIL
(opencv_work)$ pip install --no-install PIL
.... ....

.... ....
Successfully downloaded PIL
(opencv_work)$ vi ~/.virtualenvs/opencv_work/build/PIL/setup.py
.... ....
.... ....
TCL_ROOT = None
JPEG_ROOT = None
ZLIB_ROOT = None
TIFF_ROOT = None
FREETYPE_ROOT = libinclude("/usr/local/opt/freetype")
LCMS_ROOT = None

.... ....
.... ....
(opencv_work)$ pip install --no-download PIL
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
--------------------------------------------------------------------
PIL 1.1.7 SETUP SUMMARY
--------------------------------------------------------------------
version 1.1.7
platform darwin 2.7.4 (default, May 14 2013, 16:22:30)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)]
--------------------------------------------------------------------
--- TKINTER support available
--- JPEG support available
--- ZLIB (PNG/ZIP) support available
--- FREETYPE2 support available
--- LITTLECMS support available
--------------------------------------------------------------------
.... ....
.... ....
Successfully installed PIL
Cleaning up...

これで、すべての機能が有効な状態でPILをインストールできたので、続いてmatplotlibのインストールに取りかかった。
(opencv_work)$ pip install matplotlib
Downloading/unpacking matplotlib
Downloading matplotlib-1.2.1.tar.gz (38.4MB): 38.4MB downloaded
Running setup.py egg_info for package matplotlib
basedirlist is: ['/usr/local/', '/usr', '/usr/X11', '/opt/local']
============================================================================
BUILDING MATPLOTLIB
matplotlib: 1.2.1
python: 2.7.4 (default, May 14 2013, 16:22:30) [GCC 4.2.1
(Based on Apple Inc. build 5658) (LLVM build
2336.1.00)]
platform: darwin

REQUIRED DEPENDENCIES
numpy: 1.7.1
freetype2: found, but unknown version (no pkg-config)

OPTIONAL BACKEND DEPENDENCIES
libpng: found, but unknown version (no pkg-config)
Tkinter: Tkinter: 81008, Tk: 8.5, Tcl: 8.5
Gtk+: no
* Building for Gtk+ requires pygtk; you must be able
* to "import gtk" in your build/install environment
Mac OS X native: yes
Qt: no
Qt4: no
PySide: no
Cairo: no

OPTIONAL DATE/TIMEZONE DEPENDENCIES
dateutil: matplotlib will provide
pytz: matplotlib will provide

OPTIONAL USETEX DEPENDENCIES
dvipng: no
ghostscript: /bin/sh: gs: command not found
latex: no

[Edit setup.cfg to suppress the above messages]
============================================================================
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
Successfully installed matplotlib
Cleaning up...

PILと同様にこのライブラリも一応正常にインストールできているようだが、ビルド処理の開始前に表示されるコンフィグレーション情報の中の「freetype2, libpng」の2つの項目が「found, but unknown version (no pkg-config)」となっているのが気になった。

pkg-configというのは前記事でインストールしたHomebrewのフォーミュラで、プログラムがライブラリをリンクする際に必要となるフラグやパス等の情報を提供してくれるツールだ。このpkg-configは、環境変数PKG_CONFIG_PATHで指定されたパスからpcファイルを検索して、その中に格納されている情報を元にビルドに必要な情報を返す仕組みになっている。ここで試しに「printenv」ですべての環境変数を表示させてみたが、やはりPKG_CONFIG_PATHという環境変数は存在していなかった。どうやら、Homebrewでpkg-configをインストールしただけでは$PKG_CONFIG_PATHの設定は追加されないようなので、これを手動で追加してやる必要があるようだ。上のmatplotlibの「found, but unknown version (no pkg-config)」という警告メッセージは「ライブラリやヘッダファイルは見つかったが、pcファイルが見つからないのでそのバージョンが判らない」という意味だと思われる。Linux用のプログラム開発をやる者にとってpkg-configは有名なツールで、私もこれの役割と動作について知っていたので、matplotlibの警告メッセージの意味はすぐに推測がついた。

上記の問題を解決するために、まず.bashrcに次のような設定を追加した(私の環境では、.bash_profileを作成してあり、この中から.bashrcを実行するようになっている)。
# pkg-config pc file search paths
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/lib/pkgconfig:/usr/X11/lib/pkgconfig

各ライブラリのpcファイルは上で設定した3つのディレクトリに分かれて格納されているが、このうち/usr/local/lib/pkgconfigにHombebrewのライブラリのpcファイルが、他の2つのディレクトリにはMac OS X側のライブラリのpcファイルが格納されている。ここで、「source .bashrc」とタイプするか、ターミナルを再起動すれば、pkg-configはpcファイルを見つけることができるようになる。試しに次のコマンドを実行すれば、上で.bashrcに追加した$PKG_CONFIG_PATHの設定が有効に働いているがどうかが確認できる。
$ pkg-config --cflags --libs freetype2
-I/usr/X11/include/freetype2 -I/usr/X11/include -L/usr/X11/lib -lfreetype
$ pkg-config --print-provides freetype2
freetype2 = 13.2.7
$ pkg-config --cflags --libs libpng
-I/usr/X11/include/libpng15 -L/usr/X11/lib -lpng15
$ pkg-config --print-provides libpng
libpng = 1.5.4

ただし、ここで注意しなけばならないことがある。それは上のコマンドの出力から判ることだが、この2つはMac OS X側のものでありHombebrew側のものではないということだ。じつは、freetype2もlibpngもMac OS X側にデフォルト状態で存在しており、現在の状態ではそちらが使われてしまう。pkg-configがHomebrew側のfreetype2やlibpngを参照してくれるようにするには、さらに次のコマンドを実行してやる必要がある。
$ brew link --force freetype
$ brew link --force libpng

上のコマンドを実行すると、/usr/local/lib/usr/local/includeにそれぞれfreetype2とlibpngのライブリとヘッダファイルのシンボリックリンクが、/usr/local/lib/pkgconfigにpcファイルのシンボリックリンクが作成される。これを実行した後、再度「pkg-config」コマンドでfreetype2とlibpngの情報を調べると、下のような表示に変わるはずだ。
$ pkg-config --cflags --libs freetype2
-I/usr/local/Cellar/freetype/2.4.11/include/freetype2 -I/usr/local/Cellar/freetype/2.4.11/include
-L/usr/local/Cellar/freetype/2.4.11/lib -lfreetype
$ pkg-config --print-provides freetype2
freetype2 = 16.0.10
$ pkg-config --cflags --libs libpng
-I/usr/local/Cellar/libpng/1.5.14/include/libpng15 -L/usr/local/Cellar/libpng/1.5.14/lib -lpng15
$ pkg-config --print-provides libpng
libpng = 1.5.14

freetype2とlibpngはどちらもHomebrewでインストール済みなのに、/usr/localディレクトリの下にライブラリ、ヘッダファイル、pcファイルが作成されていないのは、この2つがkeg-only属性のフォーミュラだからだ(keg-only属性のフォーミュラの詳しい説明は前記事に書いた)。keg-only属性でないフォーミュラの場合、Homebrewでフォーミュラをインストールしたときに自動的にライブラリ、ヘッダファイル、pcファイルのシンボリックリンクが/usr/local下の各ディレクトリに作成されるようになっている。

上の設定がすべて済んだ状態で、一旦仮想環境からmatplotlibをアンインストールして、再度インストールしてみた。
(opencv_work)$ pip uninstall matplotlib
(opencv_work)$ pip install matplotlib
Downloading matplotlib-1.2.1.tar.gz (38.4MB): 38.4MB downloaded
Running setup.py egg_info for package matplotlib
basedirlist is: ['/usr/local/', '/usr', '/usr/X11', '/opt/local']
============================================================================
BUILDING MATPLOTLIB
matplotlib: 1.2.1
python: 2.7.4 (default, May 14 2013, 16:22:30) [GCC 4.2.1
(Based on Apple Inc. build 5658) (LLVM build
2336.1.00)]
platform: darwin

REQUIRED DEPENDENCIES
numpy: 1.7.1
freetype2: 16.0.10

OPTIONAL BACKEND DEPENDENCIES
libpng: 1.5.14
Tkinter: Tkinter: 81008, Tk: 8.5, Tcl: 8.5
Gtk+: no
* Building for Gtk+ requires pygtk; you must be able
* to "import gtk" in your build/install environment
Mac OS X native: yes
Qt: no
Qt4: no
PySide: no
Cairo: no

OPTIONAL DATE/TIMEZONE DEPENDENCIES
dateutil: matplotlib will provide
pytz: matplotlib will provide

OPTIONAL USETEX DEPENDENCIES
dvipng: no
ghostscript: /bin/sh: gs: command not found
latex: no

[Edit setup.cfg to suppress the above messages]
============================================================================
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
Successfully installed matplotlib
Cleaning up...

すると、期待したとおり、matplotlibのコンフィグレーション情報内のfrretype2とlibpngにバージョン番号が表示された。しかも、この2つの項目のバージョン番号はちゃんとHomebrew側のものと一致している。

matplotlibのインストールが無事に終わったら、上で作成したfreetype2とlibpngフォーミュラのシンボリックリンクは削除しておいた方が良い。これらはあくまでmatplotlibのビルド処理のために暫定的に作成したものだからだ。次のコマンドを実行すれば、フォーミュラのシンボリックリンクを削除できる。
$ brew unlink freetype
$ brew unlink libpng

matplotlibに続いて、最後のライブラリであるSphinxをPython仮想環境へインストールした。
(opencv_work)$ pip install Sphinx
Downloading/unpacking Sphinx
Downloading Sphinx-1.2b1.tar.gz (3.0MB): 3.0MB downloaded
Running setup.py egg_info for package Sphinx
.... ....
Downloading/unpacking Pygments>=1.2 (from Sphinx)
Downloading Pygments-1.6.tar.gz (1.4MB): 1.4MB downloaded
Running setup.py egg_info for package Pygments

Downloading/unpacking Jinja2>=2.3 (from Sphinx)
Downloading Jinja2-2.7.tar.gz (377kB): 377kB downloaded
Running setup.py egg_info for package Jinja2

.... ....
.... ....
Downloading/unpacking docutils>=0.7 (from Sphinx)
Downloading docutils-0.10.tar.gz (1.6MB): 1.6MB downloaded
Running setup.py egg_info for package docutils

.... ....
.... ....
Downloading/unpacking markupsafe (from Jinja2>=2.3->Sphinx)
Downloading MarkupSafe-0.18.tar.gz
Running setup.py egg_info for package markupsafe

.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
Successfully installed Sphinx Pygments Jinja2 docutils markupsafe
Cleaning up...

これは何も問題なくインストールすることができた。なお、SphinxはPygments, Jinja2, docutils, MarkupSafeの4つのライブラリに依存しているので、これらも一緒にインストールされる。

かなり手間取ってしまったが、これでやっと、OpenCVと連携使用するすべてのライブラリをPython仮想環境へ入れることができた(matplotlibのいくつかのオプション機能が「no」=無効になっているが、これらについては将来必要になったときに、改めてmatplotlibを再インストールすれば良いだろう。当該オプション機能に対応するライブラリをHomebrewや「pip」コマンドでインストールするだけで、これらは有効になるんじゃないかと予想している)。

ずいぶん長文の記事になってしまった。この後、さらにOpenCVのインストール作業についても書かないといけないのでもっと長くなりそうだ。一旦ここで切って、2つの記事に分けた方が良さそうだ。続きは次の記事に書くことにしよう。

posted by とみやん at 18:08| Comment(0) | TrackBack(0) | 開発・プログラミング > Mac
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/68502862

この記事へのトラックバック