RaspberryPiへのOpenCVインストール手順

仕事でRaspberryPiにOpenCVを使う機会があったのですが、OpenCV公式ページの情報だけではインストールできず、信頼できる情報を見つけるのに苦労したため情報共有したいと思います。

##記事の流れ
__1.インストールの方法は大きく分けて2通り__
-非公式のビルド済パッケージ（opencv-python）をインストール
-RaspberryPi上で公式のOpenCVをビルドする

__2.OpenCVの動作確認__
-importできるかどうかを確認
-カメラ読み込みサンプルプログラムによる動作確認

__3.OpenCVのライセンスについて__
-OpenCVは、BCDライセンス
-contribモジュールには商用利用できないものが含まれる

##環境
・RaspberryPi4（OS:Raspbian Buster with desktop）に環境構築します。
・PythonでOpenCVを使うことを前提とします。PyhtonのバージョンはPython3.7.3です。
・インストールするOpenCVのバージョンはOpenCV4です。

#1.インストールの方法は大きく分けて2通り
##■非公式のビルド済パッケージ（opencv-python）をインストール
###__●情報源・インストール手順の根拠__
\<Pypi(Python Package Index) opencv-python>
https://pypi.org/project/opencv-python/
Pypi（パイピーアイ）は、pipのパッケージ管理サービスです。
opencv-pythonのページに、以下のとおり書かれていました。

>Note that the wheel (especially manylinux) format does not currently support properly ARM architecture so there are no packages for ARM based platforms in PyPI. However, opencv-python packages for Raspberry Pi can be found from https://www.piwheels.org/. 

\<google翻訳すると・・・>
>ホイール（特にmanylinux）形式は現在ARMアーキテクチャを適切にサポートしていないため、PyPIにはARMベースのプラットフォーム用のパッケージはありません。ただし、Raspberry Pi用のopencv-pythonパッケージは、https：//www.piwheels.org/から入手できます。

とのこと。ちなみにRaspberryPiはARMLinuxです。RaspberryPi用のパッケージはここにはないけどpiwheelsからダウンロードできるよって事を言っているようです。
そこで、piwheelsのページを見てみます。
\<piwheels opencv-python>
https://www.piwheels.org/

冒頭にサイトの説明があります。
>piwheels is a Python package repository providing Arm platform wheels (pre-compiled binary Python packages) specifically for the Raspberry Pi, making pip installations much faster. Packages are natively compiled on Raspberry Pi 3 hardware using the Mythic Beasts Pi cloud.

\<google翻訳すると・・・>
>piwheelsは、特にRaspberry Pi用のArmプラットフォームホイール（コンパイル済みバイナリPythonパッケージ）を提供するPythonパッケージリポジトリであり、pipのインストールを大幅に高速化します。パッケージは、Mythic Beasts Piクラウドを使用してRaspberry Pi 3ハードウェアでネイティブにコンパイルされます。

要は、ラズパイ用にパッケージを提供してくれるサービスってことですね。雑。
RaspberryPi3とありますが、4でもインストールできました。

このページで紹介しているopencv-pythonのインストール方法は以下のページにあります。
\<piwheels opencv-python>
https://www.piwheels.org/project/opencv-python/


###__●結果：以下の手順でインストールできました。__
opencv-pythonのバージョンを指定した以外は、piwheelのページそのままのインストール方法です。
コマンドをRaspberryPiのターミナルに貼り付けて実行していってください。

####<手順1> まずはaptとpipをアップグレード
（パッケージ管理ツールの一覧の更新とインストール済パッケージの更新）

```
sudo apt update
sudo apt upgrade
sudo pip install --upgrade pip
```

####<手順2> 依存ライブラリのインストール

```
sudo apt install libavutil56 libcairo-gobject2 libgtk-3-0 libqtgui4 libpango-1.0-0 libqtcore4 libavcodec58 libcairo2 libswscale5 libtiff5 libqt4-test libatk1.0-0 libavformat58 libgdk-pixbuf2.0-0 libilmbase23 libjasper1 libopenexr23 libpangocairo-1.0-0 libwebp6
```

####<手順3> opencv-pythonのインストール
piwheelどおりのインストール方法（これではうまくいきませんでした。）

```
sudo pip3 install opencv-python
```

上記コマンドでインストールした場合はimportできなかったので、調べた結果、バージョンを下げる事で解決できることがわかりました。（上記コマンドでインストールされていたバージョンは4.1.1でした。）
以下のとおりインストールします。（これでうまくいきました。）

```
sudo pip3 install opencv-python==4.1.0.25
```

##■RaspberryPi上で公式のOpenCVをビルドする
####<手順1> 依存ライブラリ・ビルドツールcmakeのインストール
####<手順2> OpenCVソースのダウンロード
####<手順3> コンパイル

__<手順1>~<手順3>までの内容は全て下のOpencvInstall.shに記載してあります。__

□参考ページ
CMakeのOpenCVとPythonを紐づけるためのオプションは、OpenCVの公式ページのlinux向けインストールのページを参考にしました。
\<OpenCV Installation in Linux>
https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html

インストールするライブラリはこのページを参考にしました。
<Github Linux環境でのOpenCVビルド>
https://github.com/atinfinity/lab/wiki/Linux%E7%92%B0%E5%A2%83%E3%81%A7%E3%81%AEOpenCV%E3%83%93%E3%83%AB%E3%83%89

CMakeのオプションについて参考にしました。
\<第8回　初めてのOpenCV開発 ― CMakeを使ったOpenCVのカスタマイズ【OpenCV 3.1.0】>
https://www.atmarkit.co.jp/ait/articles/1704/10/news134.html

```shell:OpencvInstall.sh

# パッケージ管理ツールの更新（apt-getでインストールをするときは必ず行います。）
sudo apt-get -y update
sudo apt-get -y upgrade

# Githubのページを参考にライブラリをダウンロード
# 開発ツール
sudo apt-get -yV install build-essential
sudo apt-get -yV install cmake
# 行列演算
sudo apt-get -yV install libeigen3-dev
# GUIフレームワーク関連
sudo apt-get -yV install libgtk-3-dev
sudo apt-get -yV install qt5-default
sudo apt-get -yV install libvtk7-qt-dev
sudo apt-get -yV install freeglut3-dev
# 並列処理関連
sudo apt-get -yV install libtbb-dev
# 画像フォーマット関連
sudo apt-get -yV install libjpeg-dev
sudo apt-get -yV install libopenjp2-7-dev
sudo apt-get -yV install libpng++-dev
sudo apt-get -yV install libtiff-dev
sudo apt-get -yV install libopenexr-dev
sudo apt-get -yV install libwebp-dev
# 動画像関連
sudo apt-get -yV install libavresample-dev
# その他
sudo apt-get -yV install libhdf5-dev
# Python関連
sudo apt-get -yV install libpython3-dev
sudo apt-get -yV install python3-numpy python3-scipy python3-matplotlib

# gitのインストール（ソースをダウンロードするときに使います。）
sudo apt-get -y install git

# ソースのダウンロード
cd /usr/local
sudo mkdir opencv4
cd /usr/local/opencv4
sudo git clone https://github.com/opencv/opencv.git
sudo git clone https://github.com/opencv/opencv_contrib.git

# ビルド用のディレクトリ作成（buildディレクトリを作成してその中でビルドするのがお作法です。）
cd opencv
sudo mkdir build
cd build

# ビルド
# 基本的にはOpenCV公式ページを参考にしました。
sudo cmake \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D OPENCV_EXTRA_MODULES_PATH=/usr/local/opencv4/opencv_contrib/modules \
PYTHON3_EXECUTABLE=/usr/lib/python3.7 \
PYTHON_INCLUDE_DIR=/usr/include/python3.7 \
PYTHON_INCLUDE_DIR2=/usr/include/arm-linux-gnueabihf/python3.7m \
PYTHON_LIBRARY=/usr/lib/arm-linux-gnueabihf/libpython3.7m.so \
PYTHON3_NUMPY_INCLUDE_DIRS =/usr/lib/python3/dist-packages/numpy/core/include \
-S /usr/local/opencv4/opencv

sudo make -j7
sudo make install

```


#2.OpenCVの動作確認
#####importできるかどうかを確認
ターミナル上で以下のコマンドを実行していき、`import cv2`としたときにimportErrorが出なければOKです。

```
# インタプリタの起動
python3
# インポート
import cv2
# OpenCVバージョンの確認
cv2.__version__
# インタプリタの終了
exit()
```

#####カメラ読み込みサンプルプログラムによる動作確認
カメラを有効にしてから（RaspberryPiの設定>インターフェイス>カメラから設定できます。）このプログラムを実行してみてください。
OpenCVが動作していれば、ウインドウが表示されカメラの映像が映るはずです（エディターを使って実行した場合はエディターのバックにウインドウが表示されるかもしれません）。
※camera.pyのnotが先頭大文字でNotとなっていて実行できないとの指摘があり修正しました。ありがとうございます。

```python:camera.py
import cv2
# numpyは画像データの格納に必要です。
import numpy as np


def camera():
    cap = cv2.VideoCapture(0)
    isOpened = cap.isOpened()
    if not isOpened:
        return
    while True:
        result, frame = cap.read()
        if not result:
            return
        # 画像表示
        cv2.imshow('camera', frame)
        # キー入力受付
        key = cv2.waitKey(1)
        # 終了キー（EnterかEscで終了）
        if (key == 13) or (key == 27):
            break
    # カメラ終了
    cap.release()
    cv2.destroyAllWindows()

camera()
```


# 3.OpenCVのライセンスについて
オープンソースですが注意点が2つあります。商用利用をする場合はライセンスを確認してください。

##OpenCVはBCDライセンス
OpenCVのメインモジュールを使ったプログラムは、自由に利用、改変、再配布できるが、その際に著作権情報とライセンスの表示をしなければならない、ということです。
\<OpenCV公式 License>
https://opencv.org/license/

ライセンスについてはすごくわかりやすい記事があったのでこちらを見てください。
\<公開ライセンスの話>
https://qiita.com/lovee/items/484ae3fc038314a64ee2

##contribモジュールには商用利用できないものが含まれる

###・contribモジュールに含まれるSURFは商用利用できません。
公式ページのdownloadから確認することができます。
\<SURF公式>
http://people.ee.ethz.ch/~surf/

\<github opencv-contrib/surfが使われているモジュール>
https://github.com/opencv/opencv_contrib/tree/master/modules/xfeatures2d

###・SIFTは2020/3/6に特許が切れメインモジュールに移されたようです。


# 4.最後に
ここまで読んでいただきありがとうございます。
参考になったよーとかインストールできたよーって方は、いいね的なやつ（LGTM）をよろしくお願いしますm(_ _m)
また、ご指摘などありましたら、ご連絡いただけると幸いです！