Getting Started with CMake and OpenCV

Intro

In this post I want to give a primer on how to set up a project using CMake and OpenCV in Linux. While this is basic stuff firsts are always hard and this might still help some folks out there to get started.

Step One – Project Structure and Dependencies

First we’ll set up a clean structure separating the source files from the build output. The project will contain of only two files neccessary for a minimal application:

template/           # project folder
 - CMakeLists.txt   # the main CMake file defining the project
 - src/             # the folder containing the source files
 - build/           # the folder containig the build output

As for the dependencies necessary to build the project we will need at least the following:

  • GCC and the associated build tools
  • CMake
  • OpenCV

To install these in Ubuntu use:

sudo apt install build-essential cmake libopencv-dev

Now your system is ready to build applications using OpenCV and CMake.

Step Two – The Project

The CMakeLists.txt file defines how the project is built. CMake will translate this into a Makefile during the build process. For this example your CMake file should look like this:

cmake_minimum_required(VERSION 3.2)

project(template)

find_package(OpenCV REQUIRED)

add_executable(template
    src/main.cpp
)

target_include_directories(template PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ${OpenCV_INCLUDE_DIRS})
target_link_libraries(template PUBLIC ${OpenCV_LIBRARIES})

Note that all additional .cpp files you will be using during developement have to be added to add_executable.
The main.cpp containing the application itself should look like this:

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>

int main(int argc, char**argv)
{
    std::cout << "Hello OpenCV!" << std::endl;
    cv::Mat mat(cv::Size(640, 640), CV_8UC3);
    cv::randu(mat, 0, 255);
    cv::imwrite("test.png", mat);
    return 0;
}

It consists of a few self explanatory lines of code, which create a cv::Mat and save it as an image.

Step Three – Building the Project

In order to build the project few steps are needed. Open a terminal inside the template main directory. If you don’t have one yet, create the and to to the build directory.

[georg@archlinux template]$ mkdir build 
[georg@archlinux template]$ cd build/

From this location call CMake with the folder that contains the CMakeLists file as parameter. CMake will parse the file, check that the dependencies are met and will create a Makefile inside the build directory amongst some other files.

[georg@archlinux build]$ cmake ..
-- The C compiler identification is GNU 10.2.0
-- The CXX compiler identification is GNU 10.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenCV: /usr (found version "4.5.1") 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/georg/gles/template/build

Now you’re ready to make and run the project:

[georg@archlinux build]$ make
[ 50%] Building CXX object CMakeFiles/template.dir/src/main.cpp.o
[100%] Linking CXX executable template
[100%] Built target template
[georg@archlinux build]$ ./template 
Hello OpenCV!

And this is all, that’s needed to include OpenCV in a CMake project in Linux.