ラズパイ3にOpenCV3/4を簡単に導入

<!-- ラズパイ3にOpenCV3を簡単に導入 ... できるかな？(ぉぃ -->

# TL;DR

- (追記:2019-12-24)Raspbian buster向けに OpenCV 3.4.9 / 4.2.0 のRPi Zero/1(armhf)向けパケージを作成しました
    - `libopencv3_3.4.9-20191223.1_armhf.deb`
    - `libopencv4_4.2.0-20191223.1_armhf.deb`
- (追記:2019-12-23)Raspbian buster向けに OpenCV 3.4.9 / 4.2.0 のRPi2/3/4(armv7l)向けパケージを作成しました
    - `libopencv3_3.4.9-20191223.1_armv7l.deb`
    - `libopencv4_4.2.0-20191223.1_armv7l.deb`
- (追記:2019-10-11)Raspbian buster向けに OpenCV 4.1.2 armv7lのみ、パケージを作成しました。> [ラズパイ: Buster向け OpenCV4](https://qiita.com/mt08/items/4e8c36ee398fea5ed8d9)
- (追記:2019-08-21) Raspbian buster向けに OpenCV3.4.7/4.1.1 のパケージを作成しました > [ラズパイ: Buster向け OpenCV4](https://qiita.com/mt08/items/4e8c36ee398fea5ed8d9)
- (追記:2019-06-26) buster向けに 4.1.0 のみ作りました > [ラズパイ: Buster向け OpenCV4](https://qiita.com/mt08/items/4e8c36ee398fea5ed8d9)
- (追記:2019-04-15) OpenCV 3.4.6 / 4.1.0 のパッケージを作成・追加
- (追記:2018-12-27) OpenCV 3.4.5 / 4.0.1 のパッケージを作成・追加
- (追記:2018-11-20) OpenCV 3.4.4 / 4.0.0 のパッケージを作成・追加

- 3/4は共存できないようにしてます。

	```bash
	#3.x.x 
	# libopencv3_3.3.1-20171126.2_armhf.deb
	# libopencv3_3.4.0-20180115.1_armhf.deb
	# libopencv3_3.4.1-20180304.1_armhf.deb
	# libopencv3_3.4.2-20180709.1_armhf.deb
	# libopencv3_3.4.3-20180907.1_armhf.deb
	# libopencv3_3.4.4-20181119.2_armhf.deb
	# libopencv3_3.4.5-20181227.1_armhf.deb
	# libopencv3_3.4.6-20190415.1_armhf.deb
	# libopencv3_3.4.9-20191223.1_armv7l.deb
	# libopencv3_3.4.9-20191223.1_armhf.deb
	#
	#4.x.x
	# libopencv4_4.0.0-20181119.2_armhf.deb
	# libopencv4_4.0.1-20181227.1_armhf.deb
	# libopencv4_4.1.0-20190415.1_armhf.deb
	# libopencv4_4.2.0-20191223.1_armv7l.deb
	# libopencv4_4.2.0-20191223.1_armhf.deb


	# 上から、好きなファイルを選んで、下に記述して、こぴぺ。
	#OPENCV_DEB=libopencv3_3.4.6-20190415.1_armhf.deb
	#curl -SL https://github.com/mt08xx/files/raw/master/opencv-rpi/${OPENCV_DEB} -o ${OPENCV_DEB}

	# Buster向け
	OPENCV_DEB=libopencv4_4.2.0-20191223.1_armv7l.deb
	curl -SL https://github.com/mt08xx/files/raw/master/opencv-rpi/raspbian-buster/${OPENCV_DEB} -o ${OPENCV_DEB}
	sudo apt autoremove -y libopencv{3,4}
	sudo apt install -y ./${OPENCV_DEB}

	# 
	sudo ldconfig
	python2 -c 'import cv2; print(cv2.__version__)'
	python3 -c 'import cv2; print(cv2.__version__)'
	```


- 下の 顔検出`test-face_detect.py` にて、テスト。

	```py:test-face_detect.py
	#!/usr/bin/env python3
	# -*- coding: utf-8 -*-

	## wget http://lenna.org/lena_std.tif # にて、 画像を入手しておく.

	import cv2
	# OpenCV4の場合、/usr/local/share/opencv4/lbpcascades/... となる
	cascPath = '/usr/local/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml'
	faceCascade = cv2.CascadeClassifier(cascPath)

	# Read image
	frame = cv2.imread("lena_std.tif")
	orgH, orgW = frame.shape[:2]

	# Resize
	size = (int(orgW/2),int(orgH/2))
	frame = cv2.resize(frame, size);

	# FaceDetection
	gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
	gray = cv2.equalizeHist( gray )
	faces = faceCascade.detectMultiScale(gray, 1.1, 3, 0, (10, 10))

	# Draw Rectangle
	for (x, y, w, h) in faces:
			cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

	# Save JPG 
	cv2.imwrite("lena_std-face.jpg",frame)
	```

    - ↑の出力結果<br>![lena_std-face.jpg](https://qiita-image-store.s3.amazonaws.com/0/75594/e22600bf-9239-1442-d26c-6df2f83f1a13.jpeg)


    - ※hdf5、tesseract、gstreamerありで、ビルドしました。(動作未確認)

# 関連
- [OpenCV4 for Raspberry Pi](https://qiita.com/mt08/items/d9ff02285cfe3ec7b5c2)


# サンプル

## jpgグレースケール変換

```py:こぴぺ
import cv2
img = cv2.imread("/usr/share/rpd-wallpaper/road.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
cv2.imwrite("/home/pi/road-gray.jpg", gray)
```

```shell-session:実行例
pi@raspberrypi:~ $ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170124] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> img = cv2.imread("/usr/share/rpd-wallpaper/road.jpg")
>>> gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
>>> cv2.imwrite("/home/pi/road-gray.jpg", gray)
True
>>> quit()
pi@raspberrypi:~ $ ls -1 ./road-gray.jpg 
./road-gray.jpg
pi@raspberrypi:~ $ 
```
- `road-gray.jpg`が出力



## ラズパイカメラで、顔検出
- `picamera`が必要なので、`pip install pycamera`(python2.7系)または、`pip3 install pycamera`(python3.5系)で導入しておく
- `sudo raspi-config`で、5 Interfacing Options > 1 camera でカメラを使用可能にしておく(変更したら、要再起動)
- `python facedetect.py`(python2.7系) または `python3 facedetect.py`(python3.5系) で実行. なんか、Warningでるけど、気にしない～♪
- `/usr/local/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml`はdebパッケージに含まれている.

```py:facedetect.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://qiita.com/mt08/items/e8e8e728cf106ac83218
# Window上で、q を押すと、抜ける

from picamera.array import PiRGBArray
from picamera import PiCamera
import cv2, time

# フレームサイズ
FRAME_W = 320
FRAME_H = 192

# Set up the CascadeClassifier for face tracking
cascPath = '/usr/local/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml'
faceCascade = cv2.CascadeClassifier(cascPath)

camera = PiCamera()
camera.resolution = (FRAME_W, FRAME_H)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size=(FRAME_W, FRAME_H))
time.sleep(0.1)

for image in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):

	frame = image.array
	# frame = cv2.flip(frame, -1) # 上下反転する場合.

	# Convert to greyscale for detection
	gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
	gray = cv2.equalizeHist( gray )

	# 顔検出
	faces = faceCascade.detectMultiScale(gray, 1.1, 3, 0, (10, 10))

	# 検出した顔に枠を書く
	for (x, y, w, h) in faces:
		cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

	frame = cv2.resize(frame, (540,300))

	# 表示 
	cv2.imshow('Video', frame)
	key = cv2.waitKey(1) & 0xFF

	rawCapture.truncate(0)

	if key == ord("q"):
		break

cv2.destroyAllWindows()
```

## C++にて

```cpp:circle-fill.cpp
// ::ビルド・実行::　
// g++ `pkg-config --cflags --libs opencv` circle-fill.cpp  -o circle-fill
// ./circle-fill

#include <opencv2/opencv.hpp>
#include <algorithm>

const int frame_w=480, frame_h=270;
int main(int argc, char* argv[])
{
	cv::Mat img(cv::Size(frame_w, frame_h), CV_8UC3, CV_RGB(255,255,255));
	cv::circle(img, cv::Point(frame_w/2, frame_h/2), std::min(frame_w, frame_h)*8/20, CV_RGB(255, 0, 0), -1);
	imshow("OpenCV Test", img);
	cv::waitKey(0);
	cv::destroyAllWindows();
	return 0;
}
```


# その他


- OpenCVを真剣に使ってないので、不具合あるかも?
    - 顔検出程度でしか、動作確認していない...
- debパッケージの作り方も結構適当...
    - 依存関係が怪しいかも?
    - `/usr/local/`以下にインストールされたファイルを詰め込んだだけ.
    - `libopencv3` って名前でいいんだろうか...
- ビルドは、ASUS TinkerBoardで、[Raspbianイメージを使って](https://qiita.com/mt08/items/5aee9d3f0dc10a1c1c5a)、おこなった。
    - 速いmicroSDを使い、ファンで空冷しながらで、上記オプションで45分程度。

        ```shell-session
$ time make -j4
.
.
real    45m11.286s
user    168m39.090s
sys     5m42.450s
```




# TODO
- パッケージの作り方??
- ラズパイで、ビルドしてみる??


----

**以下、OpenCV 3.3.1 / 3.4.0 をビルドした時点での記述**

# 概要
- OpenCV3 (3.3.1)のdebパッケージを作った。<br>https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3_3.3.1-20171126.2_armhf.deb
- ビルド手順は、ほぼ[こちら](https://www.pyimagesearch.com/2017/10/09/optimizing-opencv-on-the-raspberry-pi/)にしたがった。(virtualenvは使用しなかった)<br>[pyimagesearch:: Optimizing OpenCV on the Raspberry Pi](https://www.pyimagesearch.com/2017/10/09/optimizing-opencv-on-the-raspberry-pi/)



- (2018.1.15追記) OpenCV 3.4.0のパッケージを同様にして作りました。あまりテストしてないので、不具合などあれば、コメントへ

    ```bash:インストール
#　Remove previous version
sudo apt autoremove libopencv3
# Install 
wget https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3_3.4.0-20180115.1_armhf.deb
sudo apt install -y ./libopencv3_3.4.0-20180115.1_armhf.deb
sudo ldconfig
```


# 環境 
- Raspberry Pi 3 model B
- Raspbian: `2017-09-07-raspbian-stretch.zip`
- パッケージ作成に使用したビルドオプションは、こんな感じ。

	```bash
	cmake -DCMAKE_BUILD_TYPE=Release \
		-D CMAKE_INSTALL_PREFIX=/usr/local \
		-D OPENCV_EXTRA_MODULES_PATH=/home/pi/opencv_contrib-3.3.1/modules \
		-DENABLE_VFPV3=ON \
		-DENABLE_NEON=ON \
		-DBUILD_TESTS=OFF \
		-DWITH_TBB=OFF \
		-D INSTALL_PYTHON_EXAMPLES=ON \
		-D BUILD_EXAMPLES=ON ..
	```


# インストール手順

1. パッケージの更新・再起動<br>`sudo sh -c 'apt update && apt upgrade -y && reboot'`
2. 必要そうなパッケージを導入<br>`sudo apt-get install python-pip python-numpy python3-pip python3-numpy`
3. opencv3 導入

	```bash
	wget https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3_3.3.1-20171126.2_armhf.deb
	sudo apt install -y ./libopencv3_3.3.1-20171126.2_armhf.deb
	sudo ldconfig
	```

4. バージョン確認

	```shell-session:3.3.1とでるかな？
	pi@raspberrypi:~ $ python
	Python 2.7.13 (default, Jan 19 2017, 14:48:08) 
	[GCC 6.3.0 20170124] on linux2
	Type "help", "copyright", "credits" or "license" for more information.
	>>> import cv2
	>>> cv2.__version__
	'3.3.1'
	>>> quit()
	pi@raspberrypi:~ $ python3
	Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
	[GCC 6.3.0 20170124] on linux
	Type "help", "copyright", "credits" or "license" for more information.
	>>> import cv2
	c>>> cv2.__version__
	'3.3.1'
	>>> quit()
	pi@raspberrypi:~ $ 
	```




<!--


- (2018.9.7追記) OpenCV 3.4.3のパッケージを作成(`libopencv3_3.4.3-20180907.1_armhf.deb`)<br>[参考: commit msg](https://github.com/mt08xx/files/commit/217e9f406f26323032b30c253406ce7adfb2a02a)

    ```bash:インストール(RPi2/3向け)
#　Remove previous version
sudo apt autoremove libopencv3
# Install 
wget https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3_3.4.3-20180907.1_armhf.deb
sudo apt install -y ./libopencv3_3.4.3-20180907.1_armhf.deb
sudo ldconfig
```

    ```shell-session:
pi@raspberrypi:~ $ python2 -c 'import cv2; print(cv2.__version__)'
3.4.3
pi@raspberrypi:~ $ python3 -c 'import cv2; print(cv2.__version__)'
3.4.3
```
\# 下の 顔検出`test-face_detect.py` にて、同様の結果を得ました。


---


- (2018.7.9追記) OpenCV 3.4.2のパッケージを作成<br>[参考: commit msg](https://github.com/mt08xx/files/commit/61a5ef756a78452e763e222da2eca4fade246198)

    ```bash:インストール(RPi2/3向け)
#　Remove previous version
sudo apt autoremove libopencv3
# Install 
wget https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3_3.4.2-20180709.1_armhf.deb
sudo apt install -y ./libopencv3_3.4.2-20180709.1_armhf.deb
sudo ldconfig
```

    ```shell-session:
pi@raspberrypi:~ $ python2 -c 'import cv2; print(cv2.__version__)'
3.4.2
pi@raspberrypi:~ $ python3 -c 'import cv2; print(cv2.__version__)'
3.4.2
```

-->


<!--
- (2018.3.4追記) OpenCV **3.4.1**のパッケージを同様に作成。未テスト。

    ```bash:インストール(RPi2/3向け)
#　Remove previous version
sudo apt autoremove libopencv3
# Install 
wget https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3_3.4.1-20180304.1_armhf.deb
sudo apt install -y ./libopencv3_3.4.1-20180304.1_armhf.deb
sudo ldconfig
```

    ```shell-session:
pi@raspberrypi:~ $ python2 -c 'import cv2; print(cv2.__version__)'
3.4.1
pi@raspberrypi:~ $ python3 -c 'import cv2; print(cv2.__version__)'
3.4.1
```


- (2018.6.12追記)ラズパイ Zero/1 向けのパッケージを作成しました。簡単なテストしかしてませんが..<br>([libopencv3rpi01_3.4.1-20180610.1_armhf.deb](https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3rpi01_3.4.1-20180610.1_armhf.deb) -- [commit-msg](https://github.com/mt08xx/files/commit/0576fcafe86972925baac31fe4711d50a17ad27e))

	```bash:インストール(RPi0/1向け)
	#　Remove previous version
	sudo apt autoremove -y libopencv3 libopencv3rpi01
	# Install 
	wget https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3rpi01_3.4.1-20180610.1_armhf.deb
	sudo apt install -y ./libopencv3rpi01_3.4.1-20180610.1_armhf.deb
	sudo ldconfig
	```

	- Pi2/3向けとの違いなど
		- ビルド時のオプションの変更: `-DENABLE_VFPV3=OFF -DENABLE_NEON=OFF` (RPi0/1のCPUに対応させる)
		- パッケージ名の変更: `libopencv3rpi01` (う～ん、同じ方がよかったかも..)
		-  ※ ソースは、3.4.1のリリース版を使用 (同じ)
-->