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を使ってインストールする。