Cross compiling OpenCV 4 for Raspberry Pi and BeagleBone Black

Updated 7 August 2019

If you want to cross compile OpenCV for Raspberry Pi Zero please check this article.

In this article, I will show you how to cross compile the latest version of OpenCV for Raspberry Pi and BeagleBone Black. At the time of this writing, OpenCV is at version 4.1.0 while the version available with the default Debian based OS on Raspberry Pi and BeagleBone Black is 3.2.0. Building OpenCV 4 directly on a Raspberry Pi or BeagleBone Black is doable, but it could take a few hours. Cross compiling OpenCV for armhf is a 20 - 30 minutes process, depending on the speed of your computer it could be even shorter.

I recommend that you do the build in a Debian Buster virtual machine or a Docker container in order to not mess your system. If you decide to install Buster in a virtual machine, make sure to use the minimal netinst system. It is really important that you start with a bare bone system, because we need to install armhf executables and libraries. By using a minimal system we avoid potential conflicts with the native x86-64 versions.

For the remaining of this article, I will mention only Raspbian and Raspberry Pi, if you are using a BeagleBone Black everything should work the same.

I’ll assume that you have a clean Raspbian install. I’ve used the latest available desktop image. In principle you should be able to follow the article using Raspbian Lite, but I did all my tests using the full desktop version of Rasbian.

First, make sure your x86-64 Debian Stretch virtual machine or container is updated:

1 sudo apt update 2 sudo apt upgrade

Next, let’s enable the armhf architecture on the x86-64 machine:

1 sudo dpkg --add-architecture armhf 2 sudo apt update 3 sudo apt install qemu-user-static

At this point, you should be able to install armhf libraries and applications on your system and run them.

We are going to build OpenCV with support for Python and C++. Let’s install NumPy and Python 2, 3 for the host system:

1 sudo apt-get install python3-dev 2 sudo apt-get install python3-numpy 3 sudo apt-get install python-dev 4 sudo apt-get install python-numpy

We’ll also need libpython for the armhf architecture:

1 sudo apt-get install libpython2-dev:armhf 2 sudo apt-get install libpython3-dev:armhf

Next, we are going to install libgtk-3 in order to be able to write simple GUI programs. If you plan to use OpenCV exclusively on a headless system you can safely ignore the next two libraries:

1 sudo apt install libgtk-3-dev:armhf libcanberra-gtk3-dev:armhf

We also need to install a bunch of other libraries required by OpenCV (various image and video formats support):

1 sudo apt install libtiff-dev:armhf zlib1g-dev:armhf 2 sudo apt install libjpeg-dev:armhf libpng-dev:armhf 3 sudo apt install libavcodec-dev:armhf libavformat-dev:armhf libswscale-dev:armhf libv4l-dev:armhf 4 sudo apt-get install libxvidcore-dev:armhf libx264-dev:armhf

Next, we are going to install the default cross compilers from Debian which can be used to create armhf binaries for Raspberry Pi:

1 sudo apt install crossbuild-essential-armhf 2 sudo apt install gfortran-arm-linux-gnueabihf

At the time of this writing, the above toolchain is based on GCC 8.3, which is the same version of GCC available on Raspbian.

Finally, we’ll install Cmake, git, pkg-config and wget:

1 sudo apt install cmake git pkg-config wget

Next, we can download the current release of OpenCV. I will show you how to install the full OpenCV (default and contrib libraries):

1 cd ~ 2 mkdir opencv_all && cd opencv_all 3 wget -O opencv.tar.gz https://github.com/opencv/opencv/archive/4.1.0.tar.gz 4 tar xf opencv.tar.gz 5 wget -O opencv_contrib.tar.gz https://github.com/opencv/opencv_contrib/archive/4.1.0.tar.gz 6 tar xf opencv_contrib.tar.gz 7 rm *.tar.gz

We need to temporarily modify two system variables required to successfully build GTK+ support:

1 export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig 2 export PKG_CONFIG_LIBDIR=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig

At this point, we can use Cmake to generate the OpenCV build scripts:

1 cd opencv-4.1.0 2 mkdir build && cd build 3 cmake -D CMAKE_BUILD_TYPE=RELEASE \ 4 -D CMAKE_INSTALL_PREFIX=/opt/opencv-4.1.0 \ 5 -D CMAKE_TOOLCHAIN_FILE=../platforms/linux/arm-gnueabi.toolchain.cmake \ 6 -D OPENCV_EXTRA_MODULES_PATH=~/opencv_all/opencv_contrib-4.1.0/modules \ 7 -D OPENCV_ENABLE_NONFREE=ON \ 8 -D ENABLE_NEON=ON \ 9 -D ENABLE_VFPV3=ON \ 10 -D BUILD_TESTS=OFF \ 11 -D BUILD_DOCS=OFF \ 12 -D PYTHON2_INCLUDE_PATH=/usr/include/python2.7 \ 13 -D PYTHON2_LIBRARIES=/usr/lib/arm-linux-gnueabihf/libpython2.7.so \ 14 -D PYTHON2_NUMPY_INCLUDE_DIRS=/usr/lib/python2/dist-packages/numpy/core/include \ 15 -D PYTHON3_INCLUDE_PATH=/usr/include/python3.7m \ 16 -D PYTHON3_LIBRARIES=/usr/lib/arm-linux-gnueabihf/libpython3.7m.so \ 17 -D PYTHON3_NUMPY_INCLUDE_DIRS=/usr/lib/python3/dist-packages/numpy/core/include \ 18 -D BUILD_OPENCV_PYTHON2=ON \ 19 -D BUILD_OPENCV_PYTHON3=ON \ 20 -D BUILD_EXAMPLES=OFF ..

Assuming that you had no errors, you should have a Makefile in the build folder. We can start the actual build:

1 make -j16

Once the build phase is done, we can install the library:

1 sudo make install/strip

Next, we need to change the name of a library that the installer mistakenly labeled as a x86_64 library when in fact it is an armhf one:

1 cd /opt/opencv-4.1.0/lib/python3.7/dist-packages/cv2/python-3.7/ 2 sudo cp cv2.cpython-37m-x86_64-linux-gnu.so cv2.so

Let’s compress the installation folder and save the archive to the home folder:

1 cd /opt 2 tar -cjvf ~/opencv-4.1.0-armhf.tar.bz2 opencv-4.1.0 3 cd ~

To make our life easier, I’ve also prepared a simple pkg-config settings file, named opencv.pc. Get it with:

1 git clone https://gist.github.com/sol-prog/ed383474872958081985de733eaf352d opencv_cpp_compile_settings 2 cd opencv_cpp_compile_settings 3 cp opencv.pc ~ 4 cd ~

Copy opencv-4.1.0-armhf.tar.bz2 and opencv.pc from your home folder to your Raspberry Pi.

For the next part of the article, I’ll assume that you are on a RPi.

Make sure your RPi has all the development libraries we’ve used. Like before, if you don’t plan to use GTK+, ignore the first line from the next commands. Most of these libraries should be already installed if you are using the full version of Raspbian:

1 sudo apt install libgtk-3-dev libcanberra-gtk3-dev 2 sudo apt install libtiff-dev zlib1g-dev 3 sudo apt install libjpeg-dev libpng-dev 4 sudo apt install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev 5 sudo apt-get install libxvidcore-dev libx264-dev

Uncompress and move the library to the /opt folder of your RPi:

1 tar xfv opencv-4.1.0-armhf.tar.bz2 2 sudo mv opencv-4.1.0 /opt

Optionally, you can erase the archive:

1 rm opencv-4.1.0-armhf.tar.bz2

Next, let’s also move opencv.pc where pkg-config can find it:

1 sudo mv opencv.pc /usr/lib/arm-linux-gnueabihf/pkgconfig

In order for the OS to find the OpenCV libraries we need to add them to the library path:

1 echo 'export LD_LIBRARY_PATH=/opt/opencv-4.1.0/lib:$LD_LIBRARY_PATH' >> .bashrc 2 source .bashrc

Log out and log in or restart the Terminal.

Next, let’s create some symbolic links that will allow Python to load the newly created libraries:

1 sudo ln -s /opt/opencv-4.1.0/lib/python2.7/dist-packages/cv2 /usr/lib/python2.7/dist-packages/cv2 2 sudo ln -s /opt/opencv-4.1.0/lib/python3.7/dist-packages/cv2 /usr/lib/python3/dist-packages/cv2

At this point, you should be able to use the OpenCV library from C++ or Python.

On the repository for this article you can find a few C++ and Python test programs. You can download the code on your Pi with:

1 git clone https://github.com/sol-prog/raspberry-pi-opencv.git 2 cd raspberry-pi-opencv/tests

There are two headless tests that you can use even if you don’t have a display connected to your RPi: cli_cpp_test.cpp and cli_python_test.py. I’ve also included two graphical tests that require a display: gui_cpp_test.cpp and gui_python_test.py.

You can build and run the C++ tests like this:

1 g++ cli_cpp_test.cpp -o cli_cpp_test `pkg-config --cflags --libs opencv` 2 ./cli_cpp_test

or, if you have a display connected to your RPi:

1 g++ gui_cpp_test.cpp -o gui_cpp_test `pkg-config --cflags --libs opencv` 2 ./gui_cpp_test

Here is a screenshoot of the C++ GUI test running on my Pi:

For the Python tests, use:

1 python3 cli_python_test.py

or

1 python3 gui_python_test.py

As a side note, it is also possible to cross compile C++ programs that use OpenCV on your x86-64 Debian Stretch system and run the binary on your RPi.

If you want to learn more about programming on the Raspberry Pi, a very good book is Exploring Raspberry Pi by Derek Molloy: