/ pi

Installing OpenCV 4.0 on Raspberry Pi 3 B+

If you don't want to compile on a Raspberry Pi, you should look into cross compiling using a more powerful machine. That's not what this guide is about though. Also, if you need OpenCV 3.4.3, see one of my earlier blog posts.

I will be using a Raspberry Pi 3 B+, which costs around $40 on Amazon.

Warning: compiling OpenCV is a CPU-intensive task - all 4 cores will be maxed out for a couple of hours. To avoid overheating, make sure your Raspberry Pi has radiators and a fan (or place a powerful external fan next to it). As I mentioned before - no, the box won't die from overheating, but its CPU performance will be throttled, increasing build time from 2 hours to possibly 6 hours, and you probably don't want that.

IMG_9969

Let's get started:

Step 1: make sure your OS is current. (< 5min)

I am using latest version of Raspbian Stretch (specifically, RASPBIAN STRETCH WITH DESKTOP Kernel 4.14, released on November 13 2018). You can either do a clean install from SD (detailed instructions can be found here), or upgrade your existing version.

To upgrade, open (as sudo) the files /etc/apt/sources.list and /etc/apt/sources.list.d/raspi.list in your favorite editor, and change all occurences of your current distro name (e.g. "jessie") to "stretch". Then, open a terminal and run the update:

sudo apt-get update
sudo apt-get -y dist-upgrade

If you're already running Stretch, simply update all packages before proceeding:

sudo apt-get update
sudo apt-get upgrade

Step 2: configure SSH and utilities (< 2min)

Make sure SSH is enabled. Change the default password, too!

Some of my favorite utilities on Linux are screen (to keep processes running if your terminal session is dropped) and htop (performance monitoring) - htop may already be pre-installed:

sudo apt-get install screen
sudo apt-get install htop

Step 3: configure swap and GPU memory allocation (< 2min)

First, we're going to change swapfile settings:

sudo nano /etc/dphys-swapfile

... I uncommented CONF_SWAPFACTOR (and set it to 2 times RAM size), and commented out the others:

# 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

# set size to computed value, this times RAM size, dynamically adapts,
#   guarantees that there is enough swap without wasting disk space on excess
CONF_SWAPFACTOR=2

# restrict size (computed and absolute!) to maximally this limit
#   can be set to empty for no limit, but beware of filled partitions!
#   this is/was a (outdated?) 32bit kernel limit (in MBytes), do not overrun it
#   but is also sensible on 64bit to prevent filling /var or even / partition
#CONF_MAXSWAP=2048

For these changes to take effect, you will need to stop and start the service that manages the swapfile:

sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start

... verify new swapfile settings:

free -m

Screen-Shot-2018-11-21-at-1.16.59-PM

Warning: memory swapping will wear out your SD card. Do not put your swap file on a SD card unless absolutely necessary. For example, you might want to revert your swapfile settings back to their default values after you're done installing OpenCV. This topic will probably need its own blog post.

Then, adjust GPU memory:

sudo nano /boot/config.txt

If there's a "gpu_mem" setting there, change it to 128, otherwise add this line at the end:

gpu_mem=128

GPU memory in megabytes. This sets the memory split between the CPU and GPU; the CPU gets the remaining memory. Minimum value is 16; maximum value is 192, 448, or 944, depending on whether you are using a 256M, 512MB, or 1024MB Pi. The default value is 64.

Setting gpu_mem to low values may automatically disable certain firmware features, as there are some things the GPU cannot do if it has access to too little memory. So if a feature you are trying to use isn't working, try setting a larger GPU memory split.

You can read more about GPU memory considerations here.

Step 4: install dependencies (< 10min)

sudo apt-get install build-essential cmake pkg-config
sudo apt-get install libjpeg-dev libtiff-dev libjasper-dev libpng12-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libgtk2.0-dev libgtk-3-dev
sudo apt-get install libatlas-base-dev gfortran

Step 5: install Python 3 bindings (< 2min)

We need this in order to enable Python bindings in Open CV:

In OpenCV, all algorithms are implemented in C++. But these algorithms can be used from different languages like Python, Java etc. This is made possible by the bindings generators. These generators create a bridge between C++ and Python which enables users to call C++ functions from Python. To get a complete picture of what is happening in background, a good knowledge of Python/C API is required. A simple example on extending C++ functions to Python can be found in official Python documentation[1]. So extending all functions in OpenCV to Python by writing their wrapper functions manually is a time-consuming task. So OpenCV does it in a more intelligent way. OpenCV generates these wrapper functions automatically from the C++ headers using some Python scripts which are located in modules/python/src2

sudo apt-get install python3-dev

Step 6 (OPTIONAL): install pip3 (< 2min)

You probably already have pip3 on your system. You can check using this command: pip3 -h

... if you don't, install it:

sudo apt-get install python3-pip

Step 7: get the latest (4.0) OpenCV source code (< 5min)

I am using version 4.0 of OpenCV. You can check the Releases section of the official site (or Github) to see what the current build is. If your desired version is different, update the commands and paths below accordingly.

Download and unzip OpenCV 4.0 and its experimental modules (those are stored in the opencv_contrib repository):

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 opencv.zip

unzip opencv_contrib.zip

Step 8: install Numpy and Scipy (< 3min)

sudo pip3 install numpy scipy

Step 9: compile OpenCV (< 10min)

Again, I am using version 4.0.0 of OpenCV. If you aren't - update your paths accordingly:

cd ~/opencv-4.0.0/
mkdir build
cd build

cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D INSTALL_PYTHON_EXAMPLES=ON \
    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-4.0.0/modules \
    -D ENABLE_NEON=ON \
    -D ENABLE_VFPV3=ON \
    -D WITH_FFMPEG=ON \
    -D WITH_GSTREAMER=ON \
    -D BUILD_EXAMPLES=ON ..

Examine the output to make sure cmake finished without errors.

Step 10: build OpenCV (100-120min)

Warning: this step will take a long time. Took almost 2 hours on my device. Also, your Raspberry Pi will overheat without proper cooling.

This will work faster if you use all four CPU cores:

make -j4

You may see a bunch of warnings about upcoming syntax changes in GCC 7.1.

During this process, my CPU temperature (/opt/vc/bin/vcgencmd measure_temp) is hovering just above 59 degrees Celsius (thanks to the cooling fan + radiators). Towards the end, it dropped to 49 C.

Once OpenCV builds successfully, continue the installation:

sudo make install
sudo ldconfig
sudo apt-get update

... then reboot the system - and you should be good to go!

sudo reboot

Step 11 (OPTIONAL): revert swapfile settings (2 min)

As mentioned above, using your SD card constantly for memory swapping can wear it out (even if it's a high-endurance card), so you may want to consider returning swap settings to their default values.

Step 12 (OPTIONAL): if you get "No module named cv2" in Python (2 min)

Copy the cv2 library (or create a symlink) to /usr/local/lib/python3.5/dist-packages:

cd ~/opencv-4.0.0/build/lib/python3
sudo cp cv2.cpython-35m-arm-linux-gnueabihf.so /usr/local/lib/python3.5/dist-packages/cv2.so

Good luck - and let me know what you would like to see next!