Raspberry Pi3 に OpenCV 3.4.3を入れてみた

Python3からOpenCVが利用したくなってパッケージから入れようとしたけど失敗して今度はビルドして失敗してまたパッケージで頑張ったら動いた話

Windowsの場合はpipで入れるだけでOpenCV本体と共有ライブラリが同梱されていて簡単に動いたのですが、linuxの場合は別で用意してやらないといけないみたいです。
ubuntuなどの場合はaptから一発で入るようですが、Raspbianの場合はどうも簡単に行かないようです。(python2系ならいける?)
すでにいろいろ試されてる記事が多いですが、自分でコンパイルするか、不足しているパッケージをバカスカ入れていくか何方かのようです。

■環境

RaspberryPi3 model b+
RASPBIAN STRETCH LITE
Python3.5.3
OpenCV 4.0
OpenCV 3.4.3
numpy 1.15.4

■ビルドしてみた(失敗)

失敗した記録です

■ビルド環境の用意
ビルドする際に結構なメモリとディスク容量が必要です。

■空き容量
ビルド結果は5.8GBでしたのでそれ以上の空き容量が必要です。
8GBのSDカードを使用しているのですが、収まらなかったためUSBメモリ上でビルドしました。
USB上でビルドする場合はvfatでは収まらないファイルがいるため、ext4にフォーマットしてから使用する必要があります。

mkfs -t ext4 /dev/sda
mount /dev/sda /mnt

■メモリ
ModelB+のDRAM容量は1GBあり、スワップは初期設定では100MBありますが、それでも足りないのでスワップを大きくする必要があります。
SDカード上に大きなスワップを用意すると寿命が一気に減ってしまうので、USBメモリ上に作成しました。
最初気づかず、68%辺りでハングアップしました。
スワップの移動方法は参考サイト参照

mkfs -t ext4 /dev/sdb
mkdir /opt/swap
mount /dev/sdb /opt/swap

※USBは2個使用しています

■ソースコードの用意
以下のディレクトリ構成になるように取得&解凍します
せっかくなので最新の4.0.0を使ってみたいと思います。

/mnt/opencv-4.0.0
/mnt/opencv_contrib-4.0.0/

■ビルド
最低限のオプションでビルドしてみます。オプションが多すぎて適切なチョイスが難しそうです。
ビルドに数時間かかるので何か別のことをして待ったほうがいいです。

cmake -D OPENCV_EXTRA_MODULES_PATH=/mnt/opencv_contrib-4.0.0/modules ..
nohup make -j4 &

■インストール
make installすると各ライブラリの展開と、Pythonのsetup.pyが生成されるので、Pythonへのインストールまで行います。
※ここにバグがあるようです

make install
python3 /usr/local/python/setup.py build
python3 /usr/local/python/setup.py install

■BLASライブラリの差し替え
すんなり動作したら良かったのですが、numpyが参照しているライブラリに問題が発生しているようでした。

ImportError: /usr/local/lib/python3.5/dist-packages/numpy/core/multiarray.cpython-35m-arm-linux-gnueabihf.so: undefined symbol: cblas_sgemm

githubで言及されている症状と一致しており、BLASライブラリをAtlasからOpenBLASに変えてみたら上手く動きました。
https://github.com/Kitt-AI/snowboy/issues/38

numpyをOpenBLAS指定でビルドする方法は下の通りでいけました
numpy, scipyでOpenBLASを使う

■動作確認

# python3
>>> import cv2
ImportError: ERROR: recursion is detected during loading of "cv2" binary extensions. Check OpenCV installation.

OpenCV3.4.4から用意されている新しいPythonバインディング用のセットアップにバグがあるようでどうも動かないようです。
ここで断念しました。
https://github.com/opencv/opencv/issues/13202

■pipとaptで入れてみる

pipで入れたOpenCV環境では共有ライブラリが不足していて怒られるので、自分で持ってくる必要があります。
具体的にはlddコマンドで.soファイルを覗いてみて not found となっている共有ライブラリを探し、
ライブラリを含むパッケージをひたすらaptで入れていく作業です。

最初に必要なパッケージをpipでインストールします

# pip3 install opencv-python
# pip3 show opencv-python
Name: opencv-python
Version: 3.4.3.18
Summary: Wrapper package for OpenCV python bindings.
Home-page: https://github.com/skvark/opencv-python
Author: Olli-Pekka Heinisuo
Author-email: UNKNOWN
License: MIT
Location: /usr/local/lib/python3.5/dist-packages
Requires: numpy

# pip3 install opencv-contrib-python
# pip3 show opencv-contrib-python
Name: opencv-contrib-python
Version: 3.4.3.18
Summary: Wrapper package for OpenCV python bindings.
Home-page: https://github.com/skvark/opencv-python
Author: Olli-Pekka Heinisuo
Author-email: UNKNOWN
License: MIT
Location: /usr/local/lib/python3.5/dist-packages
Requires: numpy

# pip3 install numpy
# pip3 show numpy
Name: numpy
Version: 1.15.4
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: NumPy Developers
Author-email: numpy-discussion@python.org
License: BSD
Location: /usr/local/lib/python3.5/dist-packages/numpy-1.15.4-py3.5-linux-armv7l.egg
Requires:

/usr/local/lib/python3.5/dist-packages/cv2/cv2.cpython-35m-arm-linux-gnueabihf.so
にcv2のライブラリが保存されるのでlddで確認し、not found が全て無くなるまでaptでパッケージを入れていきます。

こんだけ入れたはずです

apt install liblapack-dev libcblas-dev libatlas-dev libatlas-base-dev libjasper-dev gstreamer1.0-plugins-base libqt4-test
root@raspberrypi:/# ldd /usr/local/lib/python3.5/dist-packages/cv2/cv2.cpython-35m-arm-linux-gnueabihf.so
        linux-vdso.so.1 (0x7ec0d000)
        /usr/lib/arm-linux-gnueabihf/libarmmem.so (0x75f57000)
        liblapack.so.3 => /usr/lib/liblapack.so.3 (0x75a31000)
        libcblas.so.3 => /usr/lib/arm-linux-gnueabihf/libcblas.so.3 (0x759d7000)
        libatlas.so.3 => /usr/lib/libatlas.so.3 (0x7575f000)
        libjpeg.so.62 => /usr/lib/arm-linux-gnueabihf/libjpeg.so.62 (0x75719000)
        libwebp.so.6 => /usr/lib/arm-linux-gnueabihf/libwebp.so.6 (0x756bb000)
        libpng16.so.16 => /usr/lib/arm-linux-gnueabihf/libpng16.so.16 (0x75681000)
        libtiff.so.5 => /usr/lib/arm-linux-gnueabihf/libtiff.so.5 (0x75607000)
        libjasper.so.1 => /usr/lib/arm-linux-gnueabihf/libjasper.so.1 (0x755ab000)
        libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0x75584000)
        libImath-2_2.so.12 => /usr/lib/arm-linux-gnueabihf/libImath-2_2.so.12 (0x75567000)
        libIlmImf-2_2.so.22 => /usr/lib/arm-linux-gnueabihf/libIlmImf-2_2.so.22 (0x752b4000)
        libIex-2_2.so.12 => /usr/lib/arm-linux-gnueabihf/libIex-2_2.so.12 (0x7528d000)
        libHalf.so.12 => /usr/lib/arm-linux-gnueabihf/libHalf.so.12 (0x7523a000)
        libIlmThread-2_2.so.12 => /usr/lib/arm-linux-gnueabihf/libIlmThread-2_2.so.12 (0x75224000)
        libgstbase-1.0.so.0 => /usr/lib/arm-linux-gnueabihf/libgstbase-1.0.so.0 (0x751b6000)
        libgstreamer-1.0.so.0 => /usr/lib/arm-linux-gnueabihf/libgstreamer-1.0.so.0 (0x75093000)
        libgobject-2.0.so.0 => /usr/lib/arm-linux-gnueabihf/libgobject-2.0.so.0 (0x75039000)
        libglib-2.0.so.0 => /lib/arm-linux-gnueabihf/libglib-2.0.so.0 (0x74f31000)
        libavcodec.so.57 => /usr/lib/arm-linux-gnueabihf/libavcodec.so.57 (0x73cf0000)
        libavformat.so.57 => /usr/lib/arm-linux-gnueabihf/libavformat.so.57 (0x73adc000)
        libavutil.so.55 => /usr/lib/arm-linux-gnueabihf/libavutil.so.55 (0x73a44000)
        libswscale.so.4 => /usr/lib/arm-linux-gnueabihf/libswscale.so.4 (0x739c6000)
        libQtGui.so.4 => /usr/lib/arm-linux-gnueabihf/libQtGui.so.4 (0x730e8000)
        libQtTest.so.4 => /usr/lib/arm-linux-gnueabihf/libQtTest.so.4 (0x730b9000)
        libQtCore.so.4 => /usr/lib/arm-linux-gnueabihf/libQtCore.so.4 (0x72e20000)
        libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x72e0d000)
        libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x72de4000)
        librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x72dcd000)
        libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x72c85000)
        libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x72c06000)
        libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x72bd9000)
        libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x72a9a000)
        /lib/ld-linux-armhf.so.3 (0x76fb6000)
        libblas.so.3 => /usr/lib/libblas.so.3 (0x72a5a000)
        libgfortran.so.3 => /usr/lib/arm-linux-gnueabihf/libgfortran.so.3 (0x729a5000)
        libf2c.so.2 => /usr/lib/arm-linux-gnueabihf/libf2c.so.2 (0x7297c000)
        liblzma.so.5 => /lib/arm-linux-gnueabihf/liblzma.so.5 (0x7294b000)
        libjbig.so.0 => /usr/lib/arm-linux-gnueabihf/libjbig.so.0 (0x7292e000)
        libgmodule-2.0.so.0 => /usr/lib/arm-linux-gnueabihf/libgmodule-2.0.so.0 (0x7291a000)
        libffi.so.6 => /usr/lib/arm-linux-gnueabihf/libffi.so.6 (0x72902000)
        libpcre.so.3 => /lib/arm-linux-gnueabihf/libpcre.so.3 (0x72889000)
        libswresample.so.2 => /usr/lib/arm-linux-gnueabihf/libswresample.so.2 (0x72863000)
        libva.so.1 => /usr/lib/arm-linux-gnueabihf/libva.so.1 (0x72836000)
        libmmal_core.so => /opt/vc/lib/libmmal_core.so (0x72818000)
        libmmal_util.so => /opt/vc/lib/libmmal_util.so (0x727f8000)
        libmmal_vc_client.so => /opt/vc/lib/libmmal_vc_client.so (0x727dd000)
        libbcm_host.so => /opt/vc/lib/libbcm_host.so (0x727b6000)
        libzvbi.so.0 => /usr/lib/arm-linux-gnueabihf/libzvbi.so.0 (0x72732000)
        libxvidcore.so.4 => /usr/lib/arm-linux-gnueabihf/libxvidcore.so.4 (0x7263b000)
        libx265.so.95 => /usr/lib/arm-linux-gnueabihf/libx265.so.95 (0x723e3000)
        libx264.so.148 => /usr/lib/arm-linux-gnueabihf/neon/vfp/libx264.so.148 (0x72274000)
        libwebpmux.so.2 => /usr/lib/arm-linux-gnueabihf/libwebpmux.so.2 (0x7225c000)
        libwavpack.so.1 => /usr/lib/arm-linux-gnueabihf/libwavpack.so.1 (0x72228000)
        libvpx.so.4 => /usr/lib/arm-linux-gnueabihf/libvpx.so.4 (0x7212b000)
        libvorbisenc.so.2 => /usr/lib/arm-linux-gnueabihf/libvorbisenc.so.2 (0x72099000)
        libvorbis.so.0 => /usr/lib/arm-linux-gnueabihf/libvorbis.so.0 (0x72062000)
        libtwolame.so.0 => /usr/lib/arm-linux-gnueabihf/libtwolame.so.0 (0x72032000)
        libtheoraenc.so.1 => /usr/lib/arm-linux-gnueabihf/libtheoraenc.so.1 (0x71fec000)
        libtheoradec.so.1 => /usr/lib/arm-linux-gnueabihf/libtheoradec.so.1 (0x71fc5000)
        libspeex.so.1 => /usr/lib/arm-linux-gnueabihf/libspeex.so.1 (0x71f9f000)
        libsnappy.so.1 => /usr/lib/arm-linux-gnueabihf/libsnappy.so.1 (0x71f88000)
        libshine.so.3 => /usr/lib/arm-linux-gnueabihf/libshine.so.3 (0x71f6d000)
        libopus.so.0 => /usr/lib/arm-linux-gnueabihf/libopus.so.0 (0x71f1a000)
        libopenjp2.so.7 => /usr/lib/arm-linux-gnueabihf/libopenjp2.so.7 (0x71ed4000)
        libmp3lame.so.0 => /usr/lib/arm-linux-gnueabihf/libmp3lame.so.0 (0x71e59000)
        libgsm.so.1 => /usr/lib/arm-linux-gnueabihf/libgsm.so.1 (0x71e47000)
        libssh-gcrypt.so.4 => /usr/lib/arm-linux-gnueabihf/libssh-gcrypt.so.4 (0x71dd8000)
        libopenmpt.so.0 => /usr/lib/arm-linux-gnueabihf/libopenmpt.so.0 (0x71c5d000)
        libgme.so.0 => /usr/lib/arm-linux-gnueabihf/libgme.so.0 (0x71c0e000)
        libbluray.so.1 => /usr/lib/arm-linux-gnueabihf/libbluray.so.1 (0x71bba000)
        libgnutls.so.30 => /usr/lib/arm-linux-gnueabihf/libgnutls.so.30 (0x71a2d000)
        libchromaprint.so.1 => /usr/lib/arm-linux-gnueabihf/libchromaprint.so.1 (0x71a0d000)
        libbz2.so.1.0 => /lib/arm-linux-gnueabihf/libbz2.so.1.0 (0x719ed000)
        libX11.so.6 => /usr/lib/arm-linux-gnueabihf/libX11.so.6 (0x718ca000)
        libvdpau.so.1 => /usr/lib/arm-linux-gnueabihf/libvdpau.so.1 (0x718b4000)
        libva-drm.so.1 => /usr/lib/arm-linux-gnueabihf/libva-drm.so.1 (0x718a1000)
        libva-x11.so.1 => /usr/lib/arm-linux-gnueabihf/libva-x11.so.1 (0x7188c000)
        libfontconfig.so.1 => /usr/lib/arm-linux-gnueabihf/libfontconfig.so.1 (0x71849000)
        libaudio.so.2 => /usr/lib/arm-linux-gnueabihf/libaudio.so.2 (0x71824000)
        libfreetype.so.6 => /usr/lib/arm-linux-gnueabihf/libfreetype.so.6 (0x71789000)
        libSM.so.6 => /usr/lib/arm-linux-gnueabihf/libSM.so.6 (0x71772000)
        libICE.so.6 => /usr/lib/arm-linux-gnueabihf/libICE.so.6 (0x7174c000)
        libXrender.so.1 => /usr/lib/arm-linux-gnueabihf/libXrender.so.1 (0x71733000)
        libXext.so.6 => /usr/lib/arm-linux-gnueabihf/libXext.so.6 (0x71714000)
        libsoxr.so.0 => /usr/lib/arm-linux-gnueabihf/libsoxr.so.0 (0x716b0000)
        libvcos.so => /opt/vc/lib/libvcos.so (0x71696000)
        libvchiq_arm.so => /opt/vc/lib/libvchiq_arm.so (0x71680000)
        libvcsm.so => /opt/vc/lib/libvcsm.so (0x7166b000)
        libogg.so.0 => /usr/lib/arm-linux-gnueabihf/libogg.so.0 (0x7165d000)
        libcairo.so.2 => /usr/lib/arm-linux-gnueabihf/libcairo.so.2 (0x7156c000)
        libgcrypt.so.20 => /lib/arm-linux-gnueabihf/libgcrypt.so.20 (0x7149b000)
        libgssapi_krb5.so.2 => /usr/lib/arm-linux-gnueabihf/libgssapi_krb5.so.2 (0x71452000)
        libmpg123.so.0 => /usr/lib/arm-linux-gnueabihf/libmpg123.so.0 (0x713f7000)
        libvorbisfile.so.3 => /usr/lib/arm-linux-gnueabihf/libvorbisfile.so.3 (0x713dd000)
        libxml2.so.2 => /usr/lib/arm-linux-gnueabihf/libxml2.so.2 (0x7124d000)
        libp11-kit.so.0 => /usr/lib/arm-linux-gnueabihf/libp11-kit.so.0 (0x711ef000)
        libidn.so.11 => /lib/arm-linux-gnueabihf/libidn.so.11 (0x711ae000)
        libtasn1.so.6 => /usr/lib/arm-linux-gnueabihf/libtasn1.so.6 (0x7118e000)
        libnettle.so.6 => /usr/lib/arm-linux-gnueabihf/libnettle.so.6 (0x71147000)
        libhogweed.so.4 => /usr/lib/arm-linux-gnueabihf/libhogweed.so.4 (0x7110a000)
        libgmp.so.10 => /usr/lib/arm-linux-gnueabihf/libgmp.so.10 (0x71097000)
        libxcb.so.1 => /usr/lib/arm-linux-gnueabihf/libxcb.so.1 (0x71068000)
        libdrm.so.2 => /usr/lib/arm-linux-gnueabihf/libdrm.so.2 (0x7104b000)
        libXfixes.so.3 => /usr/lib/arm-linux-gnueabihf/libXfixes.so.3 (0x71034000)
        libexpat.so.1 => /lib/arm-linux-gnueabihf/libexpat.so.1 (0x71002000)
        libXt.so.6 => /usr/lib/arm-linux-gnueabihf/libXt.so.6 (0x70fa2000)
        libXau.so.6 => /usr/lib/arm-linux-gnueabihf/libXau.so.6 (0x70f97000)
        libuuid.so.1 => /lib/arm-linux-gnueabihf/libuuid.so.1 (0x70f83000)
        libbsd.so.0 => /lib/arm-linux-gnueabihf/libbsd.so.0 (0x70f5a000)
        libgomp.so.1 => /usr/lib/arm-linux-gnueabihf/libgomp.so.1 (0x70f22000)
        libpixman-1.so.0 => /usr/lib/arm-linux-gnueabihf/libpixman-1.so.0 (0x70e80000)
        libxcb-shm.so.0 => /usr/lib/arm-linux-gnueabihf/libxcb-shm.so.0 (0x70e6d000)
        libxcb-render.so.0 => /usr/lib/arm-linux-gnueabihf/libxcb-render.so.0 (0x70e52000)
        libgpg-error.so.0 => /lib/arm-linux-gnueabihf/libgpg-error.so.0 (0x70e30000)
        libkrb5.so.3 => /usr/lib/arm-linux-gnueabihf/libkrb5.so.3 (0x70d79000)
        libk5crypto.so.3 => /usr/lib/arm-linux-gnueabihf/libk5crypto.so.3 (0x70d3a000)
        libcom_err.so.2 => /lib/arm-linux-gnueabihf/libcom_err.so.2 (0x70d27000)
        libkrb5support.so.0 => /usr/lib/arm-linux-gnueabihf/libkrb5support.so.0 (0x70d0e000)
        libkeyutils.so.1 => /lib/arm-linux-gnueabihf/libkeyutils.so.1 (0x70cfb000)
        libresolv.so.2 => /lib/arm-linux-gnueabihf/libresolv.so.2 (0x70cd6000)
        libicui18n.so.57 => /usr/lib/arm-linux-gnueabihf/libicui18n.so.57 (0x70ac6000)
        libicuuc.so.57 => /usr/lib/arm-linux-gnueabihf/libicuuc.so.57 (0x7095c000)
        libicudata.so.57 => /usr/lib/arm-linux-gnueabihf/libicudata.so.57 (0x6f0cf000)
        libXdmcp.so.6 => /usr/lib/arm-linux-gnueabihf/libXdmcp.so.6 (0x6f0b8000)

■動作確認
なんとか動きました

# python3
>>> import cv2
>>> cv2.__version__
'3.4.3'

■参考サイト

Install guide: Raspberry Pi 3 + Raspbian Jessie + OpenCV 3
今更ながらPythonでOpenCVを使うための覚書
RaspberryPi (3 Model B+) へのOpenCV(3.4.2)のインストール
ラズパイにOpenCVをインストールする方法
OpenCV 3.4.4 Python binding #13202
compiling opencv from github
undefined symbol: cblas_sgemm #38
numpy, scipyでOpenBLASを使う
error build openCV
OpenCV 3.0 Makefile生成用スクリプトファイル(Ubuntu15.04)
ラズパイ(Raspbian Jessie)とスワップメモリ容量の変更(環境設定の続き)
UbuntuにOpenCVをパッケージからapt-getを使ってインストールする。

投稿者:

コメントを残す

メールアドレスが公開されることはありません。