Em português.
OpenCV is a beast of a library. It's huge. But it's also super flexible. You typically choose what your binary will contain by providing optional dependencies but sometimes you have to nudge it to the direction you need.
In this guide I'll show you how I compile it with the longest cmake line you'll ever see (hopefully) and I'll also add comments so you know what you need to compile it successfully.
Let's get started.
Downloading
You need two projects in order to build OpenCV: the OpenCV source code and OpenCV contrib.
You can either download the latest versions as as zip/tar ball or you can clone them and checkout the version (aka tag) you need.
Whatever way you choose, for the purpose of this tutorial all you need is both projects to be sitting next to each other on the same folder:
Dependencies
If you install all the depencies I explain bellow you'll have:
-- OpenCV modules:
-- To be built: aruco bgsegm bioinspired calib3d ccalib core cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev cvv datasets dnn dnn_objdetect dnn_superres dpm face features2d flann freetype fuzzy gapi hfs highgui img_hash imgcodecs imgproc intensity_transform line_descriptor mcc ml objdetect optflow phase_unwrapping photo plot python3 quality rapid reg rgbd saliency shape stereo stitching structured_light superres surface_matching text tracking video videoio videostab xfeatures2d ximgproc xobjdetect xphoto
-- Disabled: world
-- Disabled by dependency: -
-- Unavailable: alphamat cnn_3dobj hdf java julia matlab ovis python2 sfm ts viz
This is what you'll need:
-
python3 + numpy
- I generally install it globally, outside of any venv/virtualenv sandboxes. Having OpenCV installed globally I can reference it on the venv sandboxes when needed. You'll see a similar cmake output: -
python3-pyqt5.qtopengl
- it's enough to bring in the dependencies in order to detect Qt + OpenGL. Why is OpenGL so important, you may ask? Hardware accelerated frame rates. You'll see a similar cmake output: -
ffmpeg + gstreamer
- if you want to load different video encodings: -
libfreetype-dev + libharfbuzz-dev
- if you want support for truetype fonts -
CUDA + CuDNN
- this one deserves a more detailed explanation bellow.
CUDA + CuDNN
CUDA (and CuDNN) are usually installed under the same directory. And this directory is typically /usr/local/cuda-<version>
. But this is not a rule. I use PopOS and it gets installed in /usr/lib/cuda-<version>
. It can also have as many versions as you want installed in parallel:
As you can see above, even though CUDA-11.2 was installed automatically (it's the current version as of today), CuDNN is only available up until 11.1 so I was forced to install CUDA-11.1 as well in order to have both CUDA and CuDNN installed on the same tree structure.
In order for cmake to find CUDA and CuDNN all you need is add <your CUDA root>/bin
to your path.
You can check like this:
Super easy right? 🤣
Let's build it then!
Check for dependencies
In order to compile you need to create a build
folder inside your opencv library root folder (cd opencv; mkdir build; cd build
).
Now take a deep breath and enjoy the largest command line I've ever written for a single command:
cmake -D CMAKE_CXX_COMPILER=/usr/bin/g++ \
-D CUDA_HOST_COMPILER:FILEPATH=/usr/bin/gcc-9 \
-D CUDA_NVCC_FLAGS=--expt-relaxed-constexpr \
-D WITH_CUDA=ON \
-D WITH_CUDNN=ON \
-D CUDNN_INCLUDE_DIR=/usr/lib/cuda-11.1/include \
-D OPENCV_DNN_CUDA=ON \
-D ENABLE_FAST_MATH=1 \
-D CUDA_FAST_MATH=1 \
-D CUDA_ARCH_BIN=8.6 \
-D WITH_CUBLAS=1 \
-D WITH_TBB=ON \
-D WITH_OPENMP=ON \
-D WITH_IPP=ON \
-D CMAKE_BUILD_TYPE=RELEASE \
-D WITH_CSTRIPES=ON \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
-D CMAKE_INSTALL_PREFIX=/usr/local/ \
-D WITH_QT=ON \
-D WITH_OPENGL=ON \
-D BUILD_EXAMPLES=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_opencv_python3=ON \
-D PYTHON3_EXECUTABLE=$(which python3) \
-D PYTHON_INCLUDE_DIR=$(python2 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \
-D PYTHON3_INCLUDE_DIR=$(python3 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \
-D PYTHON3_LIBRARY=$(python3 -c "from distutils.sysconfig import get_config_var;from os.path import dirname,join ; print(join(dirname(get_config_var('LIBPC')),get_config_var('LDLIBRARY')))") \
-D PYTHON3_NUMPY_INCLUDE_DIRS=$(python3 -c "import numpy; print(numpy.get_include())") \
-D PYTHON3_PACKAGES_PATH=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") \
..
Don't miss the double dots at the end!
Some configurations worth explaining:
-
CMAKE_CXX_COMPILER
- to compile c++ files -
CUDA_HOST_COMPILER:FILEPATH
- to compile cuda files - Duringsystem76-cudnn
package installation I noticed it installed gcc-9. Very deterministic (not), I know. -
CUDA_NVCC_FLAGS
- needed some day, may remove eventually -
CUDNN_INCLUDE_DIR
- check your cuda home folder -
CUDA_ARCH_BIN
- the architecture of your GPU. Check it here https://developer.nvidia.com/cuda-gpus -
OPENCV_EXTRA_MODULES_PATH
- relative or absolute path to opencv_contrib folder
In order to validate if all your dependencies are ok, read the line Unavailable: ...
in the beginning of the previous section and check for differences with yours.
If you need to rerun cmake, leave the build
folder, destroy it, recreate it, change back to it, only then rerun cmake... It's a tedious process but there's no shortcut here unfortunately.
Compiling
This step is the easiest. Given all the dependencies are met all you have to do is run the make command:
make -j<number of processes>
I highly recommend using the -j flag in order to cut compilation time. If you want to keep using your machine while the compilation is running, I recommend using $(nproc)-2
.
For your reference, using -j60
+ nvme, the compilation process takes 5m30s here.
If anything goes wrong don't be afraid to scroll up (or search for error:
) and check what happened.
Installing
If everything went fine and dandy:
💯% baby!
All you need to do is:
sudo make install
That's the only time you need to invoke root's super powers in order to write files on /usr/local
.
Validating
To test your achievement:
$ python3
>>> import cv2
>>> print(cv2.getBuildInformation())
You should see the same output as cmake's.
Using
In order to use OpenCV with a venv (you can read more about venv here) use the flags:
python -mvenv --system-site-packages venv
This will create a sub-folder named venv
with a sandbox that comes with "system wide packages", such as ... you know it.
Closing
If you read until here, congrats, you are a very determined person 🤣
If you need any help just leave a comment!
Good luck.
Top comments (0)