Debian
OpenCV
RaspberryPi

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

ラズパイ3にOpenCV3を簡単に導入 ... できるかな?(ぉぃ

  • (2018.7.9追記) OpenCV 3.4.2のパッケージを作成

    インストール(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
    
    pi@raspberrypi:~ $ python2 -c 'import cv2; print(cv2.__version__)'
    3.4.2
    pi@raspberrypi:~ $ python3 -c 'import cv2; print(cv2.__version__)'
    3.4.2
    
    test-face_detect.py
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    ## wget http://lenna.org/lena_std.tif # にて、 画像を入手しておく.
    
    import cv2
    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(orgH/2),int(orgW/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)
    
    • ↑の出力結果
      lena_std-face.jpg
    • ※hdf5、tesseract、gstreamerありで、ビルドしました。(動作未確認)


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

    インストール(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
    
    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 向けのパッケージを作成しました。簡単なテストしかしてませんが..
    (libopencv3rpi01_3.4.1-20180610.1_armhf.deb -- commit-msg)

    インストール(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のリリース版を使用 (同じ)

概要

環境

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

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

    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. バージョン確認

    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:~ $ 
    

サンプル

jpgグレースケール変換

こぴぺ
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)
実行例
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パッケージに含まれている.
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++にて

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イメージを使って、おこなった。

    • 速いmicroSDを使い、ファンで空冷しながらで、上記オプションで45分程度。

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

TODO

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