Slackware14.2+Python3.7.x+OpenCV4.1.x+wxPython4.0.6+USBWebcamの環境構築例

#　無　保　証　で　す
[当方執筆の技術情報に関するライセンス、免責事項、禁止事項](https://qiita.com/EarthSimilarityIndex/items/6b9bb2ccacb38aae15b1)

#総合もくじ
[Python3.7.x+OpenCV4.1.x+wxPython4.0.x+USBWebcamのクロスプラットフォームな環境構築事例集](https://qiita.com/EarthSimilarityIndex/items/122de017102dee2936f7)

# 想定する運用スタイル
 - OpenCV を利用する GUI アプリケーションを wxPython により構築する。
 - [Webcam](https://ja.wikipedia.org/wiki/Web%E3%82%AB%E3%83%A1%E3%83%A9) を USB 接続し OpenCV から利用する。
 - Python 向けパッケージは pip + venv で管理する。
 - 異なるプラットフォームにおける作業手順を出来るだけ統一化する。[^Ansible]

[^Ansible]: 構築予定の環境の構成によっては [Ansible slackpkg module](https://docs.ansible.com/ansible/latest/modules/slackpkg_module.html) 等も有用と思われる。
 
※ インストール済みの Python パッケージ全てのアップグレードについては以下を参照下さい。
[How to upgrade all Python packages with pip? - Stack Overflow](https://stackoverflow.com/questions/2720014/how-to-upgrade-all-python-packages-with-pip)

# 環境構築スクリプト記述例
<details><summary>スクリプト</summary><div>

```sh
#!/bin/sh
# variables
VENV_DIR="$HOME/testenv"
WXPYTHON_VERSION="4.0.6"

# install basic build dependencies
cd || exit 1
if test ! -x /usr/sbin/sboinstall; then
  echo "Install sbotools first, bye."
  exit 2
fi
su -l -c "/usr/sbin/sboinstall python3 webkit2gtk ffmpeg"

# activate python3's virtual environment
test -d $VENV_DIR || mkdir $VENV_DIR
cd $VENV_DIR || exit 3
test -d $VENV_DIR/py3env || python3 -m venv ./py3env
. ./py3env/bin/activate
pip install --upgrade pip setuptools

# install opencv-python and wxPython
test -f $VENV_DIR/requirements.txt && rm "$VENV_DIR/requirements.txt"
test -d $VENV_DIR/requirements && rm -r "$VENV_DIR/requirements"
test -d $VENV_DIR/requirements || mkdir $VENV_DIR/requirements
cd $VENV_DIR/requirements || exit 4
curl -LO https://raw.githubusercontent.com/wxWidgets/Phoenix/wxPython-$WXPYTHON_VERSION/requirements/devel.txt || exit 5
curl -LO https://raw.githubusercontent.com/wxWidgets/Phoenix/wxPython-$WXPYTHON_VERSION/requirements/install.txt || exit 6
cd $VENV_DIR || exit 7
curl -LO https://raw.githubusercontent.com/wxWidgets/Phoenix/wxPython-$WXPYTHON_VERSION/requirements.txt || exit 8
pip install -r requirements.txt || exit 9
pip install opencv-python wxPython==$WXPYTHON_VERSION || exit 10
rm "requirements.txt"
rm -r "requirements"

# deactivate python3's virtual environment
deactivate
cd || exit 11
exit 0
```
※ 終了ステータスの使い方が少し変則的かもしれません。

</div></details>

# 事前準備：SlacBuilds.org 向けフロントエンドの導入

SlackBuilds.org の利用に関しては以下を参照。

[Slackware で SlackBuilds.org を利用する／SlackBuilds.org や公式リポジトリの更新通知を受けとる - Qiita](https://qiita.com/EarthSimilarityIndex/items/0bbd1cea3425fe0f6a66)

※ 本記事では SlackBuilds.org 向けのフロントエンドとして sbotools を採用しています。

# 事前準備：Python3 の導入
[SlackBuilds.org](https://slackbuilds.org/) から [Python 3.7.2](https://slackbuilds.org/repository/14.2/python/python3/) を導入しておく。

```sh:Python　3.7.2　導入例（sbotools利用時）
su -l -c "/usr/sbin/sboinstall python3"
```

# 事前準備：venv による仮想環境の構築

※ [direnv](https://direnv.net/) を用いることで、対象ディレクトリに移動するだけで仮想環境が開始されるよう設定出来るそうです。


[BuildWxPythonOnRaspberryPi - wxPyWiki](https://wiki.wxpython.org/BuildWxPythonOnRaspberryPi) より引用
> If your lazy like most programmers. Check out https://direnv.net/ and https://github.com/direnv/direnv/wiki/Python with some fussing the virtenv will load automagically when you enter a directory.

## 参考とした文献
仮想環境 - python.jp
https://www.python.jp/install/centos/virtualenv.html

venv --- 仮想環境の作成 — Python 3.7.4 ドキュメント
https://docs.python.org/ja/3/library/venv.html

## 手順
```sh
cd || exit
test -d $HOME/testenv || mkdir $HOME/testenv
cd $HOME/testenv || exit
python3 -m venv ./py3env
. ./py3env/bin/activate
pip install --upgrade pip setuptools
deactivate
```

# opencv-python と wxPython の導入：pip を利用する場合

## opencv-python 4.1.x のインストール

```sh
cd $HOME/testenv || exit
. ./py3env/bin/activate
pip install opencv-python
pip show opencv-python
deactivate
cd || exit
```

## wxPython 4.0.6 のインストール

```sh
VENV_DIR="$HOME/testenv"
WXPYTHON_VERSION="4.0.6"
cd $VENV_DIR || exit
. ./py3env/bin/activate
test -d Downloads || mkdir Downloads
cd Downloads || exit
test -d "wxPython-$WXPYTHON_VERSION-requirements" && rm -r "wxPython-$WXPYTHON_VERSION-requirements"
mkdir "wxPython-$WXPYTHON_VERSION-requirements"
cd "wxPython-$WXPYTHON_VERSION-requirements"
mkdir requirements
cd requirements || exit
curl -LO https://raw.githubusercontent.com/wxWidgets/Phoenix/wxPython-$WXPYTHON_VERSION/requirements/devel.txt
curl -LO https://raw.githubusercontent.com/wxWidgets/Phoenix/wxPython-$WXPYTHON_VERSION/requirements/install.txt
cd .. || exit
curl -LO https://raw.githubusercontent.com/wxWidgets/Phoenix/wxPython-$WXPYTHON_VERSION/requirements.txt
pip install -r requirements.txt
pip install wxPython==$WXPYTHON_VERSION
deactivate
cd $VENV_DIR || exit
```

# opencv-python と wxPython の導入：ソースコードからビルド＆インストールする場合

## OpenCV 4.1.2 のビルド＆インストール

### OpenCV をソースコードからビルドする利点と問題点
 - 利点：
  - 最新版を手軽に試すことが出来る。
  - ビルドオプションを細かく指定してのビルド＆インストールが可能である。
  - Qt のバージョンが揃うので UI のアイコン表示等が崩れない。 

 - 問題点：
  - pip list に現れない。

### 手順
#### slackbuilds.org からインストールした OpenCV の削除
```sh:slackbuilds.orgからインストールしたOpenCVの削除
su -l -c "/sbin/removepkg opencv"
```

#### 構築依存のインストール（必要に応じて）

```sh:qt5のインストール
su -l -c "/usr/sbin/sboinstall qt5"
```

※ qt5 をインストールしておくことで、cmake でオプション ```-D WITH_QT=ON``` 及び ```-D WITH_OPENGL=ON``` が利用可能となります。

※ GTK の UI を用いる場合は sboinstall でqt5 をインストールせず、cmake のオプションから -D WITH_QT=YES を外します。

```sh:VTK、libdc1394及びffmpeg対応版OpenCVをビルドする場合
su -l -c "/usr/sbin/sboinstall libdc1394 ffmpeg VTK"
```

※ OpenCV のビルド前に VTK や libdc1394、ffmpeg 等をインストールしておくことで、対応バイナリを生成可能です。


```sh:apache-antのインストール（必要に応じて）
su -l -c "/usr/sbin/sboinstall apache-ant"
```

```sh:adoptopenjdkのインストール（必要に応じて）
su -l -c "/usr/sbin/sboinstall adoptopenjdk"
```

※ Java モジュールを有効化する場合、apache-ant 及び Java を事前に導入しておく必要があります。apache-ant で Slackware に標準でインストールされている gcc-java の jvm を利用する場合、ビルド時に環境変数を ```export JAVA_HOME=/usr/lib64/jvm``` 等と設定します [^参考文献] 。

[^参考文献]: https://slackbuilds.org/repository/14.2/development/apache-ant/

※ SlackBuilds.org から [AdoptOpenJDK](https://adoptopenjdk.net/) を導入可能です。

```sh:Javaモジュールを有効化する場合のcmake実行例
su -l -c "/usr/sbin/sboinstall adoptopenjdk"
export JAVA_HOME=/usr/lib64/adoptopenjdk12.0.2
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=$HOME/testenv/py3env/ ..
```

#### venv 仮想環境への OpenCV の構築と導入
```sh:venv　仮想環境への　OpenCV　4.1.2　の構築
OPENCV_BUILD_VERSION="4.1.2"
cd $HOME/testenv || exit
. ./py3env/bin/activate # 仮想環境を開始する
test -x Downloads || mkdir Downloads
cd Downloads || exit
pip uninstall opencv-python # pipから導入した opencv-python があれば削除しておく
pip install numpy # opencv-python が構築時、及び導入時に依存する numpy をインストールする
curl -LO https://github.com/opencv/opencv/archive/$OPENCV_BUILD_VERSION.tar.gz
tar zxf $OPENCV_BUILD_VERSION.tar.gz
cd opencv-$OPENCV_BUILD_VERSION
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D WITH_QT=YES -D CMAKE_INSTALL_PREFIX=$HOME/testenv/py3env/ ..
make
make install # ホームディレクトリ内、仮想環境内部にインストールするのでスーパーユーザー権限は必要ない
python3 -c "import cv2; print(cv2.__version__)" # 導入した opencv-python のバージョンを確認する
python3 -c "import cv2; print(cv2.getBuildInformation())" # 導入した opencv のビルドオプションを確認する
cd $HOME/testenv/Downloads/opencv-$OPENCV_BUILD_VERSION/samples/python
python3 ./video.py # Webcam からの映像を確認、ESC キーでサンプルプログラムは終了する
deactivate # 仮想環境を終了する
```

※ マルチコアCPUなら例えば```make -j$(nproc)```や```make -j$(grep processor /proc/cpuinfo | wc -l)```などとオプションをわたすことで構築時間を短縮出来ます。[^nproc1] [^nproc2] [^proccpuinfo]

[^nproc1]: [bash - How to obtain the number of CPUs/cores in Linux from the command line? - Stack Overflow](https://stackoverflow.com/questions/6481005/how-to-obtain-the-number-of-cpus-cores-in-linux-from-the-command-line)
[^nproc2]: [Man page of NPROC - JM Project](https://linuxjm.osdn.jp/html/GNU_coreutils/man1/nproc.1.html)

[^proccpuinfo]: [物理 CPU、CPU コア、および論理 CPU の数を確認する - Red Hat Customer Portal](https://access.redhat.com/ja/solutions/2159401)

###参考とした文献
OpenCV: Installation in Linux
https://docs.opencv.org/4.1.1/d7/d9f/tutorial_linux_install.html

OpenCVのビルド情報を確認するgetBuildInformation() | note.nkmk.me
https://note.nkmk.me/python-opencv-getbuildinformation/

Python Tips：ワンライナーが書きたい - Life with Python
https://www.lifewithpython.com/2015/01/python-use-command-one-liner.html

## wxPython 4.0.6 のビルド＆インストール

### wxPython をソースコードからビルドする利点と問題点
 - **利点:**
  - ビルドオプションを柔軟に指定出来る。
  - システムに既に wxWidgets が導入済みであれば build.py のオプションで ```--use_syswx``` を指定することでそちらを利用出来る。
 - **問題点:**
  - python3 build.py clean を行う際に誤って python3 build.py cleanall とすると sip 配下のファイルやフォルダが一掃されてしまう。

### 構築依存のインストール

```sh:導入例（sbotools利用時）
su -l -c "/usr/sbin/sboinstall python3 webkit2gtk"
```

※ webkit2gtk 抜きでも一応ビルドは通りました。

### 最小限の操作でビルド＆インストール

```sh
cd $HOME/testenv || exit
. ./py3env/bin/activate
test -x Downloads || mkdir Downloads
cd Downloads || exit
test -x wxPython-4.0.6-requirements || mkdir wxPython-4.0.6-requirements
cd  wxPython-4.0.6-requirements
curl -LO https://raw.githubusercontent.com/wxWidgets/Phoenix/wxPython-4.0.6/requirements/devel.txt
curl -LO https://raw.githubusercontent.com/wxWidgets/Phoenix/wxPython-4.0.6/requirements/install.txt
pip install -r devel.txt
pip install wxPython==4.0.6
deactivate
cd || exit
```

### wxPython ソース付属サンプルコード利用時

```sh
cd $HOME/testenv || exit
. ./py3env/bin/activate || exit # 仮想環境を開始する
WXPYTHON_VERSION=4.0.6
pip uninstall wxPython # pipから導入した wxPython があれば削除しておく
test -d Downloads || mkdir Downloads
cd Downloads || exit
pip download wxPython==$WXPYTHON_VERSION --no-deps --no-binary :all: # PyPI から wxPython のソースコードをダウンロードする
tar zxf wxPython-$WXPYTHON_VERSION.tar.gz
cd wxPython-$WXPYTHON_VERSION || exit
pip install -r requirements.txt # 構築時依存及び導入時依存 python パッケージのインストールを行う
python3 build.py build bdist_wheel --release --jobs=$(nproc) # wxPython のビルドを行う
pip install dist/wxPython-$WXPYTHON_VERSION-*.whl #wxPython のインストールを行う
pip show wxPython # インストールされた wxPython パッケージの情報を表示する
python3 $HOME/testenv/Downloads/wxPython-$WXPYTHON_VERSION/demo/demo.py # wxPython のデモを実行する
unset WXPYTHON_VERSION
deactivate # 仮想環境を終了する
cd || exit
```
※ マルチコアCPUなら例えば```--jobs=$(nproc)```や```--jobs=$(grep processor /proc/cpuinfo | wc -l)```などとオプションをわたすことで構築時間を短縮出来ます。[^nproc1] [^nproc2] [^proccpuinfo]

### 参考とした文献
How to install wxPython - wxPyWiki
https://wiki.wxpython.org/How%20to%20install%20wxPython

BuildWxPythonOnRaspberryPi - wxPyWiki
https://wiki.wxpython.org/BuildWxPythonOnRaspberryPi

# おまけ１：SlackBuilds.org からの [OpenCV 4.1.1](https://slackbuilds.org/repository/14.2/libraries/opencv/) のインストール

```sh:導入例（sbotools利用時）
su -l -c "/usr/sbin/sboinstall opencv"
```

# おまけ２：SlackBuilds.org からの  [wxPython](https://slackbuilds.org/repository/14.2/libraries/wxPython4/) のインストール

```sh:導入例（sbotools利用時）
su -l -c "/usr/sbin/sboinstall wxPython4"
```

# おまけ３：OpenCV.js のビルド

```sh:Emscriptenのダウンロード＆セットアップ（必要に応じて）

cd $HOME/testenv || exit

test -d Downloads || mkdir Downloads
cd Downloads || exit

test -d Emscripten && rm -r "Emscripten"
mkdir Emscripten
cd Emscripten || exit

# Get the emsdk repo
git clone https://github.com/emscripten-core/emsdk.git

# Enter that directory
cd emsdk || exit

# Fetch the latest version of the emsdk (not needed the first time you clone)
git pull

# Download and install the latest SDK tools.
./emsdk install latest

# Make the "latest" SDK "active" for the current user. (writes ~/.emscripten file)
./emsdk activate latest
```

※ Emscripten のダウンロードとインストールについては [Download and install — Emscripten 1.39.0 documentation](https://emscripten.org/docs/getting_started/downloads.html) を出典としました。なお、Docker を用いても OpenCV.js を構築可能とのことです [^出典２] 。

[^出典２]: https://docs.opencv.org/master/d4/da1/tutorial_js_setup.html

```sh:activate
export JAVA_HOME=/usr/lib64/jvm # 任意の Java Virtual Machine を指定する
source $HOME/testenv/Downloads/Emscripten/emsdk/emsdk_env.sh # Activate PATH and other environment variables in the current terminal
export $(cat $EM_CONFIG | grep EMSCRIPTEN_ROOT | sed -e s/EMSCRIPTEN_ROOT/EMSCRIPTEN/ -e s/\ //g -e s/\'//g) # ./emsdk activate latest で指定した EMSCRIPTEN_ROOT の値を EMSCRIPTEN に代入する
cd $HOME/testenv/Downloads/opencv-4.1.2
python2 ./platforms/js/build_js.py build_js --build_test # build_js 以下に OpenCV.js を構築する
```