CentOS6.7にPython3+OpenCV3(+ffmpeg)を導入する

CentOS6.7にOpenCV3とかを入れようとしたら諸々面倒だったので環境構築の再現性を高めるべく手順を記す。ちなみに、私はPythonを書いたことはない。なのでPythonの環境構築についてはもっとイケてる方法があったりするのかもしれない。

とりあえずminimalなCentOS6.7にネットワーク設定だけ行った環境からスタート。

# 環境
* Windows10のHpyer-V上に建てたCentOS 6.7 （minimalで入れたばかり）

# 何はともあれ

```
# yum -y upgrade
```

その後、ユーザを追加してsudoできるように設定します。今後はそのユーザでログインして操作します。

# pyenvのインストール

[PyenvによるPython3.x環境構築(CentOS, Ubuntu)](http://qiita.com/akito1986/items/be5dcd1a502aaf22010b)

## 必要なパッケージをyumでインストール

```
$ sudo yum install -y git gcc bzip2 bzip2-devel openssl openssl-devel readline readline-devel sqlite-devel
```

## Pyenvのインストール

```
$ cd /usr/local/src
$ sudo git clone --depth 1 git://github.com/yyuu/pyenv.git ./pyenv
$ echo 'export PYENV_ROOT="/usr/local/src/pyenv"' | sudo tee -a /etc/profile.d/pyenv.sh
$ echo 'export PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}"' | sudo tee -a /etc/profile.d/pyenv.sh
$ source /etc/profile.d/pyenv.sh
$ pyenv --version
pyenv 20160509
```

sudoでもPATHが通るように設定変更します。

```
$ sudo visudo
```

```diff
-#Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
+Defaults    env_keep += "PATH"
+Defaults    env_keep += "PYENV_ROOT"
```

## 最新版のPythonをインストールする

rbenvと同じ感じで最新版をインストールします。
※ [rbenvでRubyの最新安定版をインストールするワンライナー](http://mawatari.jp/archives/install-latest-stable-version-of-ruby-using-rbenv)

なお、--enable-sharedオプションをつけてインストールしないと、OpenCV3をビルドする際にエラーが出る可能性があるので注意。

```
$ sudo env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install  $(pyenv install --list | grep -v - | tail -1)
$ sudo pyenv global $(pyenv install --list | grep -v - | tail -1)
$ python --version
Python 3.5.1
```

# ffmpegのインストール

これが上手く行かないと、OpenCV3のbuildでコケまくるので頑張って入れる。buildに時間がかかるので注意。makeの-jNオプションで並列化させると多少早くなるので積極的に使うといいです。
オプションは個人的に必要そうなものをピックアップしています。他にもあるのですが、全部入れるとキリがないので。必要に応じてどうぞ。
c.f. [ffmpegをスタティックビルドする（CentOS6）](http://qiita.com/takakiku/items/4f129a8859d99f6be2db)


## yumで入るライブラリを入れる
ひとまず、yumにepelリポジトリを追加して、必要なライブラリをインストールする。

```
$ sudo yum install -y autoconf automake gcc-c++ libtool wget nasm libtheora-devel
$ sudo yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo yum install -y yasm openal-devel
```

## X264をインストール

```
$ cd /usr/local/src
$ sudo git clone --depth 1 git://git.videolan.org/x264
$ cd x264
$ sudo ./configure --enable-shared
$ sudo make
$ sudo make install
```

## fdk-aacをインストール

```
$ cd /usr/local/src
$ sudo git clone --depth 1 git://github.com/mstorsjo/fdk-aac.git
$ cd fdk-aac
$ sudo autoreconf -fiv
$ sudo ./configure
$ sudo make
$ sudo make install
$ export LD_LIBRARY_PATH=/usr/local/lib
$ export LD_RUN_PATH=$LD_LIBRARY_PATH
```

## lameをインストール

```
$ cd /usr/local/src
$ sudo wget http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
$ sudo tar zxvf lame-3.99.5.tar.gz
$ sudo mv lame-3.99.5 lame
$ sudo chown -R root:root lame #所有者がおかしければ
$ cd lame
$ sudo ./configure --enable-nasm
$ sudo make
$ sudo make install
```

## xvidをインストール

```
$ cd /usr/local/src
$ sudo wget http://downloads.xvid.org/downloads/xvidcore-1.3.2.tar.gz
$ sudo tar xzvf xvidcore-1.3.2.tar.gz
$ sudo chown -R root:root xvidcore
$ cd xvidcore/build/generic/
$ sudo ./configure
$ sudo make
$ sudo make install
```

## ffmpegをインストール

ここまで入れていたら、多分こけないはず…。結構時間かかるので歯磨きでもしながら待つこと。


```
$ cd /usr/local/src
$ sudo git clone --depth 1 git://source.ffmpeg.org/ffmpeg.git
$ cd ffmpeg
$ sudo ./configure --arch=x86_64 --enable-gpl --enable-libmp3lame --enable-libtheora --enable-libx264 --enable-libxvid --enable-nonfree --enable-openal --disable-static --enable-shared --enable-version3 --enable-zlib --enable-pthreads
$ sudo make -j8  #CPUのコア数に応じて
$ sudo make install
```

下記のパスを追加しておく。

```
$ echo 'export LD_LIBRARY_PATH=/usr/local/lib' | sudo tee -a /etc/profile.d/ffmpeg.sh
$ echo 'export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig' | sudo tee -a /etc/profile.d/ffmpeg.sh
$ source /etc/profile.d/ffmpeg.sh
$ sudo sh -c "echo /usr/local/lib >> /etc/ld.so.conf.d/ffmpeg.conf"
$ sudo ldconfig
```

ライブラリにnotfoundが出ないか確認しておく。

```shell-session
$ sudo ldd `which ffmpeg`
        linux-vdso.so.1 =>  (0x00007ffe656f1000)
        libavdevice.so.57 => /usr/local/lib/libavdevice.so.57 (0x00007feb59d5e000)
        libavfilter.so.6 => /usr/local/lib/libavfilter.so.6 (0x00007feb5994c000)
        libavformat.so.57 => /usr/local/lib/libavformat.so.57 (0x00007feb59548000)
        libavcodec.so.57 => /usr/local/lib/libavcodec.so.57 (0x00007feb57e08000)
        libpostproc.so.54 => /usr/local/lib/libpostproc.so.54 (0x00007feb57bc0000)
        libswresample.so.2 => /usr/local/lib/libswresample.so.2 (0x00007feb579a4000)
        libswscale.so.4 => /usr/local/lib/libswscale.so.4 (0x00007feb57712000)
        libavutil.so.55 => /usr/local/lib/libavutil.so.55 (0x00007feb5749d000)
        libm.so.6 => /lib64/libm.so.6 (0x00007feb57218000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007feb56ffb000)
        libc.so.6 => /lib64/libc.so.6 (0x00007feb56c67000)
        libopenal.so.1 => /usr/lib64/libopenal.so.1 (0x00007feb56a0e000)
        libbz2.so.1 => /lib64/libbz2.so.1 (0x00007feb567fd000)
        libz.so.1 => /lib64/libz.so.1 (0x00007feb565e7000)
        libx264.so.148 => /usr/local/lib/libx264.so.148 (0x00007feb5622c000)
        libtheoraenc.so.1 => /usr/lib64/libtheoraenc.so.1 (0x00007feb55fff000)
        libtheoradec.so.1 => /usr/lib64/libtheoradec.so.1 (0x00007feb55df0000)
        libmp3lame.so.0 => /usr/local/lib/libmp3lame.so.0 (0x00007feb55b67000)
        librt.so.1 => /lib64/librt.so.1 (0x00007feb5595f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007feb5a1af000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007feb5575a000)
        libogg.so.0 => /usr/lib64/libogg.so.0 (0x00007feb55554000)

```

```
$ ffmpeg -version
ffmpeg version git-2016-05-14-d680ab1 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-16)
configuration: --arch=x86_64 --enable-gpl --enable-libmp3lame --enable-libtheora --enable-libx264 --enable-libxvid --enable-nonfree --enable-openal --enable-pic --enable-shared --enable-version3 --enable-zlib --extra-ldexeflags=-pie --enable-pthreads
libavutil      55. 24.100 / 55. 24.100
libavcodec     57. 41.102 / 57. 41.102
libavformat    57. 36.100 / 57. 36.100
libavdevice    57.  0.101 / 57.  0.101
libavfilter     6. 45.100 /  6. 45.100
libswscale      4.  1.100 /  4.  1.100
libswresample   2.  0.101 /  2.  0.101
libpostproc    54.  0.100 / 54.  0.100
```

DecodeとEncodeの対応フォーマット一覧は下記コマンドで見る。もしお望みのフォーマットがなければ、ライブラリとオプションフラグを確認して、コンパイルし直して下さい…。

```
$ ffmpeg -formats
```


# OpenCV3をインストール

やっとここまで来ました。しかし、ここでOpenCV3のビルドエラーに心が折られる人が多数存在するようです。ゴールは目前、頑張ります。

## yumで必要なライブラリをインストールする

yumでopencv2をインストールしてアンインストールすることによってopencv3でも必要そうな依存ライブラリがサクッとインストールできます。その他、必要なものもすべてyumで入れてしまいます。

```
$ sudo sh -c "yum install -y opencv && yum remove -y opencv"
$ sudo yum install -y cmake libjpeg-devel libtiff-devel libpng-devel jasper-devel 
```

## pipでnumpyをインストールする

```
$ sudo pip install --upgrade pip
$ sudo pip install numpy
```

## OpenCV3のインストール

OpenCV3.1.0と必要なmoduleをダウンロードします。gitからcloneしてもいいかもしれないんですが、時間がかかりそうなんで普通にzipを落として解凍しました。
```
$ cd /usr/local/src
$ sudo wget https://github.com/Itseez/opencv/archive/3.1.0.zip
$ sudo wget https://github.com/Itseez/opencv_contrib/archive/3.1.0.zip
$ sudo unzip 3.1.0.zip\*
$ cd opencv-3.1.0
$ sudo mkdir build
$ cd build
```

cmakeのオプションは環境に合わせて適時修整してください。PYTHON2とかのオプションは今回はあんまり試していないです。

```
$ sudo cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D BUILD_opencv_python3=ON \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D PYTHON_EXECUTABLE=$(which python) \
-D PYTHON3_EXECUTABLE=$(which python) \
-D PYTHON3_LIBRARY=/usr/local/src/pyenv/versions/3.5.1/lib/libpython3.5m.so \
-D PYTHON3_INCLUDE_DIR=/usr/local/src/pyenv/versions/3.5.1/include/python3.5m \
-D PYTHON3_PACKAGES_PATH=/usr/local/src/pyenv/versions/3.5.1/lib/python3.5/site-packages \
-D OPENCV_EXTRA_MODULES_PATH=/usr/local/src/opencv_contrib-3.1.0/modules ..
```

そしてmake！

```
$ sudo make -j8 #コア数に応じて
```

すると、かなりの高確率でこいつが出てきます。

```shell-session
/usr/bin/ld: /usr/local/include/../lib/libswscale.a(swscale.o): relocation R_X86_64_PC32 against symbol `ff_M24A' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
```

こうなった場合は、rootになってcmakeしなおすと通ることが多いです。

```
$ su # or sudo su
# cd /usr/local/src/opencv-3.1.0/build
# cmake ..
# make -j8
# make install
```

最後に確認です。

```shell-session
$ python
Python 3.5.1 (default, May 14 2016, 16:55:55) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.1.0'
>>> 
```

以上です！