How to install OpenCV4 on a Raspberry Pi with Python 3.7
If you're version-locked and have nowhere to turn to
Why?
I’m currently working on a project that needs Python 3.7 to function. To the chagrin of most developers, the Raspberry Pi only natively supports Python 2.7 and 3.5. But, many projects, including my game Discordia, need Python 3.7. I want to host a Discordia server on my Pi, but how am I going to even try if there’s no Python 3.7?
Lets’ start there; by installing Python 3.7.
Requirements
- Raspberry Pi 3B or 3B+
- Raspbian Stretch installed
- Expanded Filesystem (via raspi-config)
Getting Python 3.7 (and pyenv)
We’re going to use pyenv as a tool to manage our Python installations, as Python 2.7 and 3.5 are dependencies of Raspbian Stretch.
Start by installing the following packages:
sudo apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python3-openssl git unzip default-jre
Then download pyenv:
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
You may see a warning about pyenv not being in the load path. Follow the given instructions to fix it, then close and reopen your shell.
Since there’s no distribution of Python 3.6+ for Raspberry Pi, we’re going to need to compile Python 3.7 from source.
CONFIGURE_OPTS="--enable-shared --enable-optimizations" pyenv install 3.7.2 -v
--enable-shared
is critical, as it gives us access to to libpython3.so files later on.
This command took about 45 minutes on my Raspberry Pi 3B+. If you’re pressed for time, remove the CONFIGURE_OPTS=--enable-optimizations
from the command. However, this change will make Python ~10% slower.
Finally run the following to set Python 3.7 as your default interpreter:
pyenv global 3.7.2
Ensure this works by running python –version; you should get “Python 3.7.2” as output.
Getting OpenCV
This is where the fun begins. Start by updating your system packages:
sudo apt-get update && sudo apt-get upgrade
Then install dev tools and CMake:
sudo apt-get install build-essential cmake unzip pkg-config
The following image and video libraries make the backbone of OpenCV’s processing:
sudo apt-get install libjpeg-dev libpng-dev libtiff-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
Optionally you can install the GTK Graphical-User-Interface (GUI) backend:
sudo apt-get install libgtk-3-dev
sudo apt-get install libcanberra-gtk*
Grab some numerical optimizations libraries:
sudo apt-get install libatlas-base-dev gfortran
And finally install the Python headers.
sudo apt-get install python3-dev
With all the pregame out of the way, we’re finally ready to install OpenCV itself. We’ll be downloading both opencv
and opencv_contrib
into our home directory.
cd ~
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.0.0.zip
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.0.0.zip
Unzip the files, and remove the version numbers for easier scripting.
unzip opencv.zip
unzip opencv_contrib.zip
mv opencv-4.0.0 opencv
mv opencv_contrib-4.0.0 opencv_contrib
Before we go installing this giant package into our one-and-only Python 3.7 installation, we should make a virtual environment for it first. This will keep our main installation clean and allow us to enable/disable OpenCV at will. We’ll be using a virtualenvironment mangager called virtualenvwrapper
.
sudo pip install virtualenv virtualenvwrapper
We then need to edit our ~/.profile
to add the venv to our PATH. Using a text-editor, change the lines at the bottom of ~./profile
:
export WORKON_HOME=$HOME/.virtualenvs
export VIRTUALENVWRAPPER_PYTHON=$HOME/.pyenv/shims/python3
source /usr/local/bin/virtualenvwrapper.sh
It’s vital that VIRTUALENVWRAPPER_PYTHON
is set to the interpreter in ~/.pyenv
, as this is our Python 3.7 install.
In order to put these changes into effect, source the profile:
source ~/.profile
With virtualenvwrapper
in your environment, it’s finally time to make the environment.
mkvirtualenv cv -p python3
This creates a Python 3.7 environment called cv
. Verify cv
works with:
workon cv
If this worked correctly, the shell prompt should be prefixed with a (cv)
.
There’s only 1 Python requirement for OpenCV, numpy
:
pip install numpy
We now have everything we need to build OpenCV from source.
Building OpenCV
Now for the tense part. We’re going to build opencv
from source.
Change directory to opencv
and make a build
directory:
cd ~/opencv`
mkdir build
cd build
Because we’re using virtualenvwrapper
, none of the correct Python files or libraries are in the PATH. Therefore, we’re going to have to hold cmake
’s hand for each and every Python resource. We also need to specify that we want Python 3 with the parameter BUILD_opencv_python3=yes
.
If you gain nothing from this tutorial, at least see this
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D
OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules -D ENABLE_NEON=ON -D ENABLE_VFPV3=ON -D
BUILD_TESTS=OFF -D OPENCV_ENABLE_NONFREE=ON -D INSTALL_PYTHON_EXAMPLES=OFF -D BUILD_EXAMPLES=OFF
-DPYTHON3_EXECUTABLE=/home/pi/.virtualenvs/cv/bin/python
-DPYTHON3_INCLUDE_DIR=/home/pi/.virtualenvs/cv/include/python3.7m
-DPYTHON3_LIBRARY=/home/pi/.pyenv/versions/3.7.2/lib/libpython3.so -D BUILD_opencv_python3=yes ..
This will take a few minutes to complete. Once finished, inspect the output. Ensure that cv
Python3 interpreter and numpy
package were both discovered, with the correct paths. The next step is very time-consuming, and it would be a waste if you were to compile for the wrong version.
Before we build, we must increase the SWAP size of the Raspberry Pi. This can be accomplished via editing some text files:
sudo nano /etc/dphys-swapfile
# set size to absolute value, leaving empty (default) then uses computed value
# you most likely don't want this, unless you have an special disk situation
# CONF_SWAPSIZE=100
CONF_SWAPSIZE=2048
Swapsize was set from 100MB to 2048MB
This is a requirement; if this is not completed your Pi will most likely freeze during compilation. Note that having an increased SWAP size burns out your SD card faster (as there are more I/O operations). Remember to change the CONF_SWAPSIZE
back down to 100
(MB).
To put the swap changes into effect, restart the dphys-swap
service:
sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start
Finally, after all the teasing, we’re here: building OpenCV4. The commmand is simple,
make -j4
Where -j4
says to use all 4 cores of the Pi. However, this can lead to race conditions, and I’ve personally had bad luck with it, so you can just enter make
if you like.
Either way, this going to take a couple of hours. Check in every so often to make sure the device isn’t hanging. Once the process hits 100% and sends you back to the shell, you’ve officially copiled OpenCV4 for a Raspberry Pi’s ARM processor. Pat yourself on the back!
Installing OpenCV
To install the binaries, simply enter the following:
sudo make install
sudo ldconfig
(Note: Remember to reset your SWAPSIZE to 100MB and restart the SWAP service)
Link OpenCV to Python
OpenCV has been installed, but our Python installation doesn’t know about it. We need to link the library into its namespace in site-packages
.
cd ~/.virtualenvs/cv/lib/python3.7/site-packages/
ln -s /usr/local/python/cv2/python-3.7/cv2.cpython-37m-arm-linux-gnueabihf.so cv2.so
cd ~
Test your installation
To ensure you’ve done everything right, give a trial by fire: activate the cv
environment and attempt to import cv2
workon cv
python
>>> import cv2
>>> cv2.__version__
'4.0.0'
>>> exit()
You’re now running the latest version of Python with the most powerful Computer Vision library publicly available. Go blur some images!
This tutorial borrows heavily from Adrian Rosebrock’s Amazing OpenCV + Raspberry Pi Tutorial. He’s brilliant and one of the best resources for all Python + OpenCV content.
I also used a pyenv tutorial for a Discord Bot as a way to install Python 3.7 on the RPi.