動機
コンピュータビジョン関連の開発をしたり,ライブラリを使っていると,OpenCVの2系と3系を切り替えたいときがある.(特にPython)
そこで,
- virtualenvでOpenCVのバージョンを使い分けたいけど,どこの
cv2.so
からシンボリックリンクを作ればいいのか. - pyenvしか使っていないときにOpenCVのバージョンを使い分けたいとき,PYTHONPATHには何を設定すればいいのか.
- g++でOpenCVを使ったプログラムをビルドする際は,cmakeするときのパスをどこに設定すればいいのか.
- 簡単にOpenCV2系とOpenCV3系を切り替える方法.
をメモしておく.
brew unlink & brew link
で管理していたら事故を起こして不具合が出たので,別の方法を考案.
Linuxでもパスを適切に設定すれば,この方法は使えるはず.
準備
HomebrewでOpenCVの2系と3系をインストールする
# まずインストールする
# Python2系に切り替えておく
$ brew update
$ brew tap homebrew/science
$ brew install cmake pkg-config jpeg libpng libtiff eigen openexr numpy
$ brew install tbb
$ brew install ffmpeg
# OpenCV2系のインストール
# Python2系バインドが一緒に入るはず
$ brew install opencv --with-tbb --with-ffmpeg —-with-vtk
# OpenCV3系のインストール
# Python2系バインドを入れる場合
$ brew install opencv3 —-with-contrib --with-ffmpeg --with-tbb —with-vtk
# Python3系バインドを入れる場合 (Python3に切り替えてから実行すること)
$ brew install opencv3 —-with-contrib --with-ffmpeg --with-python3 --with-tbb —with-vtk --without-python
必要であればunlink
しておく.
$ brew unlink opencv opencv3
パスの設定
unlink
をしてあっても,パスを通せばコンパイル・リンク時に参照できる.
cmakeするときのオプション
-
-D
オプションでOpenCV_DIR
を設定 (OpenCVConfig.cmake
があるディレクトリ)- OpenCV2 :
-DOpenCV_DIR=/usr/local/opt/opencv/share/OpenCV/
- OpenCV3 :
-DOpenCV_DIR=/usr/local/opt/opencv3/share/OpenCV/
- OpenCV2 :
OpenCV_DIR
が設定されている状態でfind_package(OpenCV REQUIRED)
をすると,OpenCV_INCLUDE_DIRS
とOpenCV_LIBS
が設定されるので,
cmake_minimum_required(VERSION 2.8)
project(Sample)
add_executable(Project main.cpp)
find_package(OpenCV REQUIRED)
if(OpenCV_FOUND)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(Project ${OpenCV_LIBS})
endif(OpenCV_FOUND)
のcmake
が通るようになる.
cv2.so
のシンボリックリンク元
OpenCV3のPython2バインドをHomebrewでインストール,OpenCV3のPython3バインドは自前ビルドしていると仮定する.
OpenCVモジュールを使いたいPythonのインストールパス以下のディレクトリ,/path/to/python/lib/python2.7/site-packages
に,以下のcv2.so
からシンボリックリンクを貼る.
(OpenCV, Pythonのバージョンは適宜変更する)
- OpenCV2 for Python2
/usr/local/Cellar/opencv/2.4.13.2/lib/python2.7/site-packages/cv2.so
- または
/usr/local/opt/opencv/lib/python2.7/site-packages/cv2.so
- OpenCV3 for Python2
/usr/local/Cellar/opencv3/3.2.0/lib/python2.7/site-packages/cv2.so
- または
/usr/local/opt/opencv3/lib/python2.7/site-packages/cv2.so
- OpenCV3 for Python3
/path/to/own-built-opencv3/lib/python3.5/site-packages/cv2.so
環境変数でシステムの設定自体をまとめて変える
g++関連の環境変数
-
OpenCV_DIR
- OpenCV2 :
/usr/local/opt/opencv/share/OpenCV/
- OpenCV3 :
/usr/local/opt/opencv3/share/OpenCV/
- OpenCV2 :
-
CPLUS_INCLUDE_PATH
- OpenCV2 :
/usr/local/opt/opencv/include/:$CPLUS_INCLUDE_PATH
- OpenCV3 :
/usr/local/opt/opencv3/include/:$CPLUS_INCLUDE_PATH
- OpenCV2 :
-
LIBRARY_PATH
- OpenCV2 :
/usr/local/opt/opencv/lib/:$LIBRARY_PATH
- OpenCV3 :
/usr/local/opt/opencv3/lib/:$LIBRARY_PATH
- OpenCV2 :
-
PATH
- OpenCV2 :
/usr/local/opt/opencv/bin:$PATH
- OpenCV3 :
/usr/local/opt/opencv3/bin:$PATH
- OpenCV2 :
Python関連の環境変数
OpenCV3のPython2バインドをHomebrewでインストール,OpenCV3のPython3バインドは自前ビルドしていると仮定する.
site-packages
にはcv2.so
が存在するはず.
(/usr/local/opt/opencv
や/usr/local/opt/opencv3
に同様のディレクトリがあればそちらでもOKかもしれない)
-
PYTHONPATH
- OpenCV2 for Python2 :
/usr/local/Cellar/opencv/2.4.13.2/lib/python2.7/site-packages/:$PYTHONPATH
- OpenCV3 for Python2 :
/usr/local/Cellar/opencv3/3.2.0/lib/python2.7/site-packages/:$PYTHONPATH
- OpenCV3 for Python3 :
/path/to/own-built-opencv3/lib/python3.5/site-packages:$PYTHONPATH
- 自前でOpenCV3のPython3バインドをビルドし,ホームディレクトリ以下などの適当な場所に置いておく
- OpenCV2 for Python2 :
OpenCV_DIR
もOpenCVのバージョンに合わせて正しく設定しておいたほうがよい.
実例
システムの設定ごと変えるために~/.bash_profile
に以下のようなスクリプトを書いた
(メッセージが邪魔ならecho
の行を消す)
# OpenCV version setting
OpenCV_VERSION="3.2.0"
export OpenCV_DIR=""
if [ "$OpenCV_VERSION" = "2.4.13.2" ]; then
# OpenCV 2.4.13.2
echo "OpenCV 2.4.13.2"
export OpenCV_DIR="/usr/local/opt/opencv/share/OpenCV/"
export CPLUS_INCLUDE_PATH="/usr/local/opt/opencv/include/:$CPLUS_INCLUDE_PATH"
export LIBRARY_PATH="/usr/local/opt/opencv/lib/:$LIBRARY_PATH"
export PATH="/usr/local/opt/opencv/bin:$PATH"
# Python bindings (only Python 2)
export PYTHONPATH="/usr/local/Cellar/opencv/2.4.13.2/lib/python2.7/site-packages/:$PYTHONPATH"
elif [ "$OpenCV_VERSION" = "3.2.0" ]; then
# OpenCV 3.2.0
echo "OpenCV 3.2.0"
export OpenCV_DIR="/usr/local/opt/opencv3/share/OpenCV/"
export CPLUS_INCLUDE_PATH="/usr/local/opt/opencv3/include/:$CPLUS_INCLUDE_PATH"
export LIBRARY_PATH="/usr/local/opt/opencv3/lib/:$LIBRARY_PATH"
export PATH="/usr/local/opt/opencv3/bin:$PATH"
# Python binding (Python 2 or Python 3)
PYTHON_VERSION="2"
if [ "$PYTHON_VERSION" = "2" ]; then
export PYTHONPATH="/usr/local/Cellar/opencv3/3.2.0/lib/python2.7/site-packages/:$PYTHONPATH"
elif [ "$PYTHON_VERSION" = "3" ]; then
# Own-built library
export PYTHONPATH="/Users/username/usr/lib/python3.5/site-packages:$PYTHONPATH"
else
echo "Invalid Python version"
fi
else
echo "Invalid OpenCV version"
fi
OpenCV_VERSION
とPYTHON_VERSION
を切り替えて再読み込みするとOpenCVのバージョンが切り替えられる.
$ source ~/.bash_profile
OpenCV 3.2.0
$
切り替えられるか確認
g++
以下のC++コードをコンパイルする.
#include <iostream>
#include <opencv2/core.hpp>
int main()
{
std::cout << "version: " << CV_VERSION << std::endl;
}
# OpenCV_VERSION="3.2.0"のとき
$ g++ main.cc -o main
$ ./main
version: 3.2.0
# OpenCV_VERSION="2.4.13.2"のとき
$ g++ main.cc -o main
$ ./main
version: 2.4.13.2
Python
import cv2
して,cv2.__version__
とcv2.__file__
を確認する.
# OpenCV_VERSION="3.2.0"のとき
$ python
Python 2.7.13 |Anaconda custom (x86_64)| (default, Dec 20 2016, 23:05:08)
>>> import cv2
>>> cv2.__version__
'3.2.0'
>>> cv2.__file__
'/usr/local/Cellar/opencv3/3.2.0/lib/python2.7/site-packages/cv2.so'
# OpenCV_VERSION="2.4.13.2"のとき
$ python
Python 2.7.13 |Anaconda custom (x86_64)| (default, Dec 20 2016, 23:05:08)
>>> import cv2
>>> cv2.__version__
'2.4.13.2'
>>> cv2.__file__
'/usr/local/Cellar/opencv/2.4.13.2/lib/python2.7/site-packages/cv2.so'
おわりに
頑張れば with CUDA/with non-CUDA も切り替えられそう?