よし呟こう

思ったことを呟きます。

Raspberry Pi 4, デフォルトPython 3.7.3 + OpenCVは構成できた。しかし pyenv + OpenCV はできなかった。

こんにちはAxifofです。Raspberry Pi 4 にて Python3 OpenCV をインストールしたときに詰まった話をします。もともと pyenv を導入したのですが opencv の導入がうまく行きませんでした。当たり前かもしれませんが、管理者権限で実行したものと、管理者権限なしで実行したものの結果は異なることが多いです;pyenv global X.X.Xで設定した pythonsudo pythonの実行結果は、デフォルトでは異なります。ですから、sudo pip3 install pip3 install は全く別の結果を返します。インストールできない!と騒いでいましたが、ただ私の理解不足が原因でした。


[目次]


環境等

pi@raspberrypi:~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
Codename:       buster

pi@raspberrypi:~ $ uname -a
Linuc raspberrypi 4.19.118-v71+ ~(略)

pi@raspberrypi:~ $ cat /proc/cpuinfo
~ (略)
Model: Raspberry Pi 4 model B Rev 1.4

何もインストールしていません。クリーンインストール直後の Raspbian buster です。


pyenv の導入と python 3.8.4 のインストール

$ sudo apt update
$ sudo apt upgrade
$ sudo apt-get install -y git openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ source ~/.bashrc

で pyenv をセットアップ後

$ pyenv install 3.8.4
$ pyenv global 3.8.4
$ python --version
3.8.4

によって、pyenv の導入も、python 3.8.4 の global 設定もうまく行きました。


sudo pip3 install で OpenCV の導入に成功

$ sudo apt install -y 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
$ sudo apt-get install -y libatlas-base-dev libhdf5-dev libhdf5-serial-dev libatlas-base-dev libjasper-dev  libqtgui4  libqt4-test
$ sudo pip3 install opencv-python==4.1.0.25

によって、OpenCV 4.1.0.25 も無事インストールできました(書いてはいませんが、一から全部ビルドして3時間ほど費やしたのに失敗したため、クリーンインストールまでしてやり直しています涙)。

ちなみにネットによれば、opencv-python==4.1.1.26は読み込み時にエラーが出る欠陥がライブラリ自体にあり、修正できないので、一つ前のopencv-python==4.1.0.25を使います。


問題発生:インストールしたはずなのに、pyenv の python では cv2 が読み込めない

何が問題だったのかというと、この global でした。私は

$ python
python 3.8.4 ...(略)...
...(略)...
>>> 

のようになるので、pip もすべて python 3.8.4 の仮想空間に切り替わっていると思っていました。しかし実際には

$ sudo python
python 2.7.16 ...(略)...
...(略)...
$ sudo python3
python 3.7.3 ...(略)...
...(略)...

でした。ですから

$ python
Python 3.8.4 ...(略)...
...(略)...
>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named "cv2"
$ sudo python3
Python 3.7.3 ...(略)...
...(略)...
>>> import cv2
>>> cv2.__version__
4.1.0

となったのです。


確かに、

$ sudo pip3 install opencv-python==4.1.0.25

を実行したときに、チラチラと .../Python3.7/...が見えていたので気になっていました。しかしまさかsudo pythonpythonで実行結果が違うとは思っていなかったので、完全な盲点でした。

3日ほどなぜかパスが通らない問題を抱えて苦しんでいましたが、ようやく理解できた気がします。


確かにそうすれば

$ pyenv global 3.8.4

のもとで、このコードがいうことを聞かないのも肯けます;

$ pip3 install opencv-python


python 3.7.3 の環境で事足りるならそれで十分な可能性あり

仕方がないので

rm -rf $(pyenv root)

で pyenv を除去しました。git を使ってインストールしているので、上記コマンドでアンインストールできます。 reboot して以下のコードを試したところ......

$ cd /home/pi/Documents
$ mkdir python3
$ cd python3
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip3 install opencv-python
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting opencv-python
  Cache entry deserialization failed, entry ignored
  Cache entry deserialization failed, entry ignored
  Downloading https://www.piwheels.org/simple/opencv-python/opencv_python-4.1.1.26-cp37-cp37m-linux_armv7l.whl (10.0MB)
    100% |████████████████████████████████| 10.0MB 43kB/s 
Collecting numpy>=1.16.2 (from opencv-python)
  Downloading https://www.piwheels.org/simple/numpy/numpy-1.19.0-cp37-cp37m-linux_armv7l.whl (10.5MB)
    100% |████████████████████████████████| 10.5MB 44kB/s 
Installing collected packages: numpy, opencv-python
Successfully installed numpy-1.19.0 opencv-python-4.1.1.26

なんと成功しました。ちょっと cache error が出ているのが気になりますが、デフォルトインストールされている python 3.7.3 の元では普通に動くようです。


ただ

(venv) $ python
Python 3.7.3 (default, Dec 20 2019, 18:57:59) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/Documents/python3/venv/lib/python3.7/site-packages/cv2/__init__.py", line 3, in <module>
    from .cv2 import *
ImportError: /home/pi/Documents/python3/venv/lib/python3.7/site-packages/cv2/cv2.cpython-37m-arm-linux-gnueabihf.so: undefined symbol: __atomic_fetch_add_8
>>> 

となるので、やはりopencv-python==4.1.1.26 は導入できません。代わりに

$ pip3 install opencv-python==4.1.0.25

を導入しましょう。


したがって python 3.7.3 の環境で事足りるならば、venv を使って一つづつライブラリを入れていくのが良さそうです。


というよりも、これが一番驚きだったのですが、Raspberry Pi 4 はデフォルトで Python 3.7.3 が導入されているようです。本当に驚きました。正直馬鹿にしていてすみません。


現在、pyenv + OpenCV の方法を探しています。