Introduction to OpenCV

To install OpenCV on Windows the easiest way is to install the library and CMake following the tutorial below.

Installation tutorial for OpenCV

The OpenCV library is composed of different modules, for example

A sample “Hello World” program for OpenCV is the following, in which we read an image called img.png file and open a window called Display window that displays that image.

#include <opencv2/opencv.hpp> // include directive that inserts the opencv
															// header file - handeled by the preprocessor

int main(int argc, char** argv) {
    std::string imagePath = "img.png";

		// Mat is the data structure that stores the pixels and manages memory
    cv::Mat image = cv::imread(imagePath, cv::IMREAD_COLOR); // reads from file
																														 // allocates memory
    cv::imshow("Display window", image); // creates the display window and
																				 // shows the image
    cv::waitKey(0); // this command synchronyzes the drawing, meaning that
                    // with 0 the image stays on until a key is pressed
										// alternatively, the number of milliseconds we want the
										// image to be shown on the screen

    return 0;
}

To compile and run the program we need to build a build directory.

mkdir build

Then we want to specifies the directory where CMake should generate the build system files.

cmake -B .\build\

And then we can actually build the files

cmake --build .\build\

The executable file we can the use is located in the folder

build\Debug\OpenCVExample.exe

OpenCV basic data structures

An image is made up of a set of pixels that are represented in a matrix-like structure.

To represent such structure using OpenCV we use the Mat class. It represents an n-dimensional dense numerical single-channel or multi-channel array. It is used for representing images, matrices, and other multidimensional data in computer vision and image processing applications.

  • Construction: you can create a Mat object using various constructors. For example:
// Create an empty matrix
cv::Mat emptyMatrix;

// Create a matrix with a specified size and type
cv::Mat matrix(3, 3, CV_32F);
  • Accessing Elements: elements in a Mat object can be accessed using the at method or the () operator. For example:
// Access element at row 1, column 2
float value = matrix.at<float>(1, 2);

  • Channels and Depth: Mat can represent single-channel or multi-channel data. The number of channels is specified by the channels attribute.
    The depth attribute specifies the pixel depth (e.g., CV_8U for 8-bit unsigned).
  • Copying and Assignment: Mat supports copying and assignment operations. Be aware of whether you want to create a deep copy or a reference.
cv::Mat copiedMatrix = matrix.clone(); // Creates a deep copy
cv::Mat referenceMatrix = matrix;      // Creates a reference
  • Data Pointer: the actual data is stored in a continuous block of memory, and you can access the raw data using the data pointer.
cv::Mat copiedMatrix = matrix.clone(); // Creates a deep copy
cv::Mat referenceMatrix = matrix;      // Creates a reference
  • Image Processing: Mat is extensively used in image processing tasks. You can load images into Mat objects, apply various filters and transformations, and display the results.
  • Mat Size and Type: you can get information about the matrix size, channels, and depth using the size(), channels(), and depth() methods.

Here’s a simple example that demonstrates some basic usage:

#include <opencv2/opencv.hpp>

int main() {
    // Create a 3x3 matrix of 32-bit floating-point numbers
    cv::Mat matrix(3, 3, CV_32F);

    // Set values in the matrix
    for (int i = 0; i < matrix.rows; ++i) {
        for (int j = 0; j < matrix.cols; ++j) {
            matrix.at<float>(i, j) = i * matrix.cols + j;
        }
    }

    // Display the matrix
    std::cout << "Matrix:\n" << matrix << "\n";

    return 0;
}

This example demonstrates the creation of a 3×3 matrix, setting values, and printing the matrix.

For the context of OpenCV’s Mat class, constructors are methods used to create instances of the Mat class. These constructors allow you to create matrices with specific properties, such as size, type, and initial values. This notation is commonly used when defining the type of elements and channels in a Mat object.

Here’s a breakdown of the notation:

  • CV_: This prefix is used in OpenCV type constants.
  • <depth>: Specifies the pixel depth or data type. It represents the precision and range of values that each element in the matrix can hold. Common values include:
    • CV_8U: 8-bit unsigned integers (0 to 255).
    • CV_8S: 8-bit signed integers (-128 to 127).
    • CV_16U: 16-bit unsigned integers (0 to 65535).
    • CV_16S: 16-bit signed integers (-32768 to 32767).
    • CV_32S: 32-bit signed integers.
    • CV_32F: 32-bit floating-point numbers.
    • CV_64F: 64-bit floating-point numbers.
  • [C<# channels>]: Represents the number of channels in the matrix. It is optional and is used for multi-channel matrices. For example, if you have an RGB image, the number of channels would be 3.

There are also the so called “inspectors” or “accessors”, that provide information about the properties of a Mat object without modifying its content. For example, the following code accesses the number of channels, the pixel depth and the matrix type of the image.

#include <opencv2/opencv.hpp>

int main() {
    cv::Mat image = cv::imread("example.jpg", cv::IMREAD_COLOR);

    if (!image.empty()) {
        int numChannels = image.channels();
        int pixelDepth = image.depth();
        int matrixType = image.type();

        std::cout << "Number of Channels: " << numChannels << "\n";
        std::cout << "Pixel Depth: " << pixelDepth << "\n";
        std::cout << "Matrix Type: " << matrixType << "\n";
    } else {
        std::cerr << "Failed to read the image.\n";
    }

    return 0;
}
  1. Number of Channels: represents the color components in an image, indicating whether it is grayscale (1 channel) or color (3 channels for RGB, 4 channels for RGBA).
  2. Pixel Depth: refers to the precision and range of values each element in the matrix can hold, determining whether it is an 8-bit integer, 16-bit integer, 32-bit integer, or a floating-point value.
  3. Matrix Type: provides a comprehensive description, combining both the data type (pixel depth) and the number of channels, specifying how the pixel values are stored in the matrix.

The OpenCV Vec class

In OpenCV, the Vec class is a template class that represents fixed-size vectors, which are essentially arrays of elements with a fixed size known at compile time. These vectors are commonly used to represent points, colors, or other small sets of related values. The Vec class is part of the core module of OpenCV and is widely used in computer vision and image processing applications.

  • Template Class: the Vec class is templated, meaning you can create vectors of different types and sizes. The template parameters specify the type of elements in the vector and the number of elements.
  • Syntax: the syntax for creating a Vec object is as follows:
cv::Vec<T, N> vector;

where T is the type of elements (e.g., float, int) and N is the number of elements in the vector.

  • Accessing Elements: elements in a Vec object are accessed using the [] operator or the val member variables.
cv::Vec3f color(0.5f, 0.2f, 0.8f);
float blueComponent = color[0];  // Access using []
float greenComponent = color.val[1];  // Access using val
  • Common Operations: Vec supports common vector operations such as addition, subtraction, scalar multiplication, and dot product.
cv::Vec3f v1(1.0f, 2.0f, 3.0f);
cv::Vec3f v2(0.5f, 1.0f, 1.5f);
cv::Vec3f result = v1 + v2;
  • Fixed Size: the size of the vector is fixed at compile time, and it cannot be changed dynamically.
  • Convenience in Representing Points and Colors: Vec is often used to represent points in 2D or 3D space and colors in images, providing a convenient and efficient way to handle small sets of related values.

Here’s a simple example demonstrating the use of Vec to represent a 3D color:

#include <opencv2/opencv.hpp>int main() {
    // Create a Vec3f object representing a color (RGB)
    cv::Vec3f color(0.5f, 0.2f, 0.8f);

    // Access and print individual components
    std::cout << "Red: " << color[0] << ", Green: " << color[1] << ", Blue: " << color[2] << "\n";

    return 0;
}

In this example, a Vec3f object is created to represent an RGB color, and individual components are accessed and printed.

Did you find this article interesting?
YesNo
Scroll to Top