OpenCV - Q-engineering
Go to content
OpenCV on Raspberry Pi 5

Install OpenCV on Raspberry Pi 5.

Last updated: October 23, 2023


Installing OpenCV on your new Raspberry Pi 5 is not much different from installing it on a Pi 4.
The Raspberry Pi 5 and 4 have an ARM Cortex-A CPU with the same registers, like NEON and FPU. Of course, the Raspberry Pi 5 is a lot faster.

It would be nice if we could install the new OpenCV version 5. However, the OpenCV foundation is still crowd-funding the project. Without a doubt, it will be available in the near future. For now, let's use the version 4.8.

Another essential point is the new Bookworm OS in the Raspberry Pi. It has a much more significant impact than the CPU upgrade.

Firstly, Bookworm supports the Wayland video engine instead of the 'old' X11. Just being released, not every supplier has adapted its software. Most noteworthy is the RealVNC interface. Undoubtedly, they come up with a good solution shortly. For now, there is a workaround for the 64-bit OS version.

Another point is the Python 3.11 version found in Bookworm. Not all packages have installation wheels for a 3.11, aarch64 machine.
For instance, installing TensorFlow with Bazel is a nightmare. There is an avalanche of unmet dependencies.
That's why we start this tutorial with a brief Bookworm overview.


For now, there are two points to consider using Bookworm.
If you want to work with RealVNC, use this workaround. It bypasses the safety encryption used by the connection.
As a result, file transfers are not possible anymore.

Very important, do not mix the methods. They will interfere and cause crashes. If you want to switch, please uninstall the previous installation before continuing.

Now let's take a closer look and, more importantly, their differences.

First, we have the Python package manager pip. If you are only programming in Python, you can use this method.
It will install OpenCV only for Python, not C++.

Method 1: Pip.

Basically, there are three ways to install OpenCV on a machine.

Very important, do not mix the methods. They will interfere and cause crashes. If you want to switch, please uninstall the previous installation before continuing.

Now let's take a closer look and, more importantly, their differences.

First, we have the Python package manager pip. If you are only programming in Python, you can use this method.
It will install OpenCV only for Python, not C++.
# only Python
$ pip3 install opencv-contrib-python
Sometimes you see $ pip3 install opencv-python. The above-given command will install this package also.
The maintainers of the pip repository are pretty up-to-date. Mostly you get the latest version of OpenCV.

Method 2: sudo apt-get install.

You can use the apt-get installation if you want the C++ version of OpenCV.
In addition, if you want to use Python bindings, you need the second command also.
# only C++
$ sudo apt-get install libopencv-dev
# need Python also?
$ sudo apt-get install python3-opencv
This time the repository is not up to date. At the time of writing, version 4.8.0 has just been released, while version 4.5.1, dated December 2020 (!), has been installed. You are missing many improvements and bug fixes.

Using the apt-get install method, OpenCV may be upgraded when you use $ sudo apt-get upgrade. It sounds fine, but it can have unforeseen consequences. Software, like Pytorch, or TensorFlow, depends on the OpenCV version found during their installation on your Raspberry Pi. Upgrading to a newer version can cause a package to complain (you're lucky) or to stop functioning (too bad).
One of the solutions here is using a virtual environment. You will find detailed information about the virtual environment at the end of this manual. Install your environment first. Then you can install OpenCV inside it.

Note that the installation puts all headers files in the /usr/include/opencv4 directory, whereas we use the /usr/local/include/opencv4 folder throughout our GitHub repos.

Method 3: compiling the source.

In fact, the best method to install OpenCV on your Raspberry Pi is to compile the source code. You always have the latest version while controlling all the features you want to add. The method generates the C++ libraries and the Python bindings. You have them all in one. It sounds complicated, but if you follow the instructions, it's not that hard.

Before we can start the actual build, the memory swap space needs to be enlarged. For daily use a swap memory of 100 Mbyte is sufficient. However, with the massive build ahead of use, extra memory space is crucial. Enlarge the swap space with the following command. OpenCV requires at least a total of 5.8 GB of memory.

This command opens Nano, a very lightweight text editor, with the system file /sbin/phys-swapfile. With the arrow keys, you can move the cursor to the CONF_MAXSWAP line where the new value 4096 can be entered. Next, close the session with the <Ctrl+X> key combination. With <Y> and <Enter> changes are being saved. With the same procedure, you can alter the CONF_SWAPSIZE in the /etc/dphys-swapfile.
The slide show clarifies the procedure.
# enlarge the boundary (CONF_MAXSWAP)
$ sudo nano /sbin/dphys-swapfile
# give the required memory size (CONF_SWAPSIZE)
$ sudo nano /etc/dphys-swapfile
# reboot afterwards
$ sudo reboot

If your Raspberry Pi has only 1 GByte of RAM, obviously, you have to increase the swap space not with 4096, but with 5120. The same applies to the 4 GByte version; a 2048 GB swap space is now sufficient. In that case, you don't have to alter the CONF_MAXSWAP in /sbin/dphys-swapfile.
We restore the swap space to its original size after the installation; there is no need to wear your SD card unnecessarily.

Installation script.

Installing OpenCV on your Raspberry Pi is not that complicated. With its 60 command lines, it's more of an administrative task. That's why we've created an installation script that executes all the commands in this guide in one go. Use it if you want. It shouldn't cause any problems. The entire installation will take an hour and a half. Make sure you have enough swap space (5.8 GB) before running the script.
If you want to beautify your OpenCV with the Qt5 GUI, follow the instructions on the GitHub page, or in the section below.
# check your memory first
$ free -m
# you need at least a total of 5.8 GB!
# if not, enlarge your swap space as explained in the guide
$ wget
$ sudo chmod 755 ./
$ ./
Cleaning and lowering dphys-swap should now be done manually according to these instructions.


Not using the script? Here's the full guide.
The OpenCV software uses other third party software libraries. These must be installed first. Some come with the Raspberry 64-bit operating system, others may already be installed. Better to be safe than sorry so here's the full list. Only the latest packages are installed according to the procedure.
# check for updates
$ sudo apt-get update
$ sudo apt-get upgrade
# dependencies
$ sudo apt-get install build-essential cmake git unzip pkg-config
$ sudo apt-get install libjpeg-dev libpng-dev
$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
$ sudo apt-get install libgtk2.0-dev libcanberra-gtk* libgtk-3-dev
$ sudo apt-get install libgstreamer1.0-dev gstreamer1.0-gtk3
$ sudo apt-get install libgstreamer-plugins-base1.0-dev gstreamer1.0-gl
$ sudo apt-get install libxvidcore-dev libx264-dev
$ sudo apt-get install python3-dev python3-numpy python3-pip
$ sudo apt-get install libtbbmalloc2 libtbb-dev
$ sudo apt-get install libv4l-dev v4l-utils
$ sudo apt-get install libopenblas-dev libatlas-base-dev libblas-dev
$ sudo apt-get install liblapack-dev gfortran libhdf5-dev
$ sudo apt-get install libprotobuf-dev libgoogle-glog-dev libgflags-dev
$ sudo apt-get install protobuf-compiler


Qt is an open-source toolkit for the development of cross-platform graphical user interfaces. It also works on the Raspberry Pi. The software can be used to beautify OpenCV windows and other user interfaces, such as sliders and checkboxes. It is absolutely not mandatory for the working of OpenCV, only to embellish the look. Must be said, that using Qt5 will slow down your OpenCV by a few percent. If you go for the fastest possible apps, don't use it.
No Qt5
With Qt5
If you want the Qt5 support enabled in OpenCV, you have to download the library as shown in the command below. The next step is to set the -D WITH_QT flag during the build.
# only install if you want Qt5
# to beautify your OpenCV GUI
$ sudo apt-get install qt5-default

Download OpenCV.

When all third-party software is installed, OpenCV itself can be downloaded. There are two packages needed; the basic version and the additional contributions. After downloading, you can unzip the files. Please be aware of line wrapping in the text boxes. The two commands are starting with wget and ending with zip.
# check your memory first
$ free -m
# you need at least a total of 5.8 GB!
# if not, enlarge your swap space as explained earlier
# download the latest version
$ cd ~
$ git clone --depth=1
$ git clone --depth=1

Virtual environment.

Now it is time to decide whether or not to use a virtual environment for your OpenCV installation. We don't use the virtual environment. Instead, we simply swap the SD-card if needed. However, feel free to install a virtual environment. All instructions are given in the virtual environment section at the end of this guide.
Importing both TensorFlow and OpenCV into Python can throw the error: cannot allocate memory in static TLS block.
This behaviour only occurs on an aarch64 system and is caused by the OpenMP memory requirements not being met. For more information, see GitHub ticket #14884.


There are a few solutions. The easiest is to import OpenCV at the beginning, as shown above.
The other is disabling OpenMP by setting the -DBUILD_OPENMP and -DWITH_OPENMP flags OFF. Where possible, OpenCV will now use the default pthread or the TBB engine for parallelization.
We don't recommend it. Not all OpenCV algorithms automatically switch to pthread. Our advice is to import OpenCV into Python first before anything else.

Build Make.

Before we begin with the actual build of the library, there is one small step to go. You have to make a directory where all the build files can be located.
$ cd ~/opencv
$ mkdir build
$ cd build
Now it is time for an important step. Here you tell CMake what, where and how to make OpenCV on your Raspberry. There are many flags involved. The most you will recognize. You will probably notice the -D WITH_QT=OFF line. Here Qt5 support is disabled. Set -D WITH_QT=ON if you choose to use the Qt5 software for the GUI. We save space by excluding any (Python) examples or tests.
There are only bare spaces before the -D flags, not tabs. By the way, the two last dots are no typo. It tells CMake where it can find its CMakeLists.txt (the large recipe file); one directory up.
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
-D PYTHON3_PACKAGES_PATH=/usr/lib/python3/dist-packages \
Hopefully, everything went well and CMake comes with a report that looks something like the screenshot below.

CMake succes 64


With all compilation directives in place, you can start the build with the following command. This will take a while (minimal 1:30).
$ make -j4
Hopefully, your build was as successful as the one below.


Now to complete, install all the generated packages to the database of your system with the next commands.
$ sudo make install
$ sudo ldconfig
# cleaning (frees 300 KB)
$ make clean
$ sudo apt-get update


Time to check your installation in Python. You can use the commands as shown is the screen dump below. It all speaks for itself. Obvious, if you have installed OpenCV in a virtual environment, you need to activate this environment first with the command workon.


OpenCV will be installed to the /usr/local directory, all files will be copied to following locations:
  • /usr/local/bin - executable files
  • /usr/local/lib - libraries (.so)
  • /usr/local/cmake/opencv4 - cmake package
  • /usr/local/include/opencv4 - headers
  • /usr/local/share/opencv4 - other files (e.g. trained cascades in XML format)


The first thing to do is resetting the swap space back. Flash memory can only write a limited number of cycles. In the end, it will wear your SD card out. It is therefore wise to keep memory swapping to a minimum. Besides, it also slows down your application. That's why we prefer to use zram, as explained in the Raspberry Pi 4 64-bit OS guide.
The original swap size is 100 MByte. It is not sufficient if you program C++ on a Raspberry Pi with 1 GByte RAM. In that case, you need at least 1 GByte of swap space. Two GByte is the very minimum of RAM when programming. If your RPi has more RAM, restore the swap size to 100 MByte (or whatever size you want).
Don't forget the restore sbin/dphys-swapfile if you had that changed too.
$ sudo nano /sbin/dphys-swapfile
# set CONF_MAXSWAP=2048 with the Nano text editor
$ sudo nano /etc/dphys-swapfile
# set CONF_SWAPSIZE=100 with the Nano text editor
$ sudo reboot
If you are in shortage of disk space, you may consider deleting the ~/opencv and ~/opencv_contrib folders. By the command, sudo make install, you have copied all the headers and libraries to their appropriate locations on your disk. The original files in the ~/opencv/build/ folder are no longer needed. Of course, if you have, for instance, enabled the building of examples, you can not delete the folders as this will also remove these examples. Let's say it's just a tip saving about 1.5 GByte of space.
# just a tip to save some space
$ sudo rm -rf ~/opencv
$ sudo rm -rf ~/opencv_contrib

Build information.

If you want to know in the future which software modules are included in your OpenCV build, you can always find the answer with the following Python command.
$ python
>>> import cv2
>>> print( cv2.getBuildInformation() )
Or use the following C++ code example.

						#include <opencv2/opencv.hpp>
						int main(void)
						    std::cout << "OpenCV version : " << cv::CV_VERSION << endl;
						    std::cout << "Major version : " << cv::CV_MAJOR_VERSION << endl;
						    std::cout << "Minor version : " << cv::CV_MINOR_VERSION << endl;
						    std::cout << "Subminor version : " << cv::CV_SUBMINOR_VERSION << endl;
						    std::cout << cv::getBuildInformation() << std::endl;
And you get the next outcome.
When you compare the three methods, you get the following scheme.
If you look closely, all have roughly the same modules. It doesn't differ much.


Virtual environment.

The section below guides you through the installation of a virtual environment on your Raspberry Pi.

A virtual environment is a Python tool for dependency management and project isolation. It allows Python site packages (third party libraries) to be installed locally in an isolated directory for a particular project, as opposed to being installed globally (i.e. as part of a system-wide Python).

An example. You install Tensorflow with a pip command. During installation, Tensorflow will install Numpy. Sometime later, you want to install PyTorch on your Pi as well. In turn, Pytorch may install a newer version of Numpy, causing Tensorflow to have serious compatibility errors.
Using separate virtual environments would leave the Tensorflow Numpy untouched. It would install another instance in the PyTorch virtual environment.

Here you have the strengths and weaknesses in one sentence. To maintain secure environments, copies of software packages are on your SD card. Each environment can have its own Numpy, OpenCV and MatPlot. If you have a large SSD card, that's no problem. A small SD card can quickly fill up with (almost) identical software. That is why we never use the virtual environment on a Raspberry Pi. Instead, we swap SD cards.

If you program in C++, there is no need for a virtual environment. In this language, you must explicitly tell the compiler where the different folders with the headers and libraries are located.

It is up to you. If you want to install the virtual environment software, follow the next steps.
Install a virtual environment.
Step one is some administration. We only use Python 3 because the support of Python 2.7 has stopped at the beginning of 2020. You have first to determine your Python 3 version and location. This location must be placed in the (hidden) ~/.bashrc file. The easiest way is a direct injection at the end of the file. You don't have to use an editor like nano or leafpad now.
# get version
$ python3 --version
# get location
$ which python 3.9
# merge VIRTUALENVWRAPPER_PYTHON=location/version
$ echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python" >> ~/.bashrc
# reload profile
$ source ~/.bashrc
The Python location in the above commands was /usr/bin/python. This location is passed as an argument in the echo command.


The next step is installing the virtual environment software. This can be done with the following commands.
$ sudo pip3 install virtualenv
$ sudo pip3 install virtualenvwrapper
The last step is again some administration in the ~/.bashrc file, followed by a re-activation.
With the command mkvirtualenv, a virtual environment is set up for the OpenCV installation.
$ echo "export WORKON_HOME=$HOME/.virtualenvs" >> ~/.bashrc
$ echo "source /usr/local/bin/" >> ~/.bashrc
$ source ~/.bashrc
$ mkvirtualenv cv480
# to quit working in cv480
(cv480) $ deactivate
# to activate cv430 the next time
$ workon cv480

Your screen will be something like this.


There is only one dependency for Python with OpenCV in a virtual environment and that is Numpy. Although you have previously installed this package, you must also install it within the environment, otherwise, CMake cannot compile.
# without sudo!!!!
$ pip3 install numpy
Deep learning examples for Raspberry Pi
Back to content