To install OpenCV on Windows the easiest way is to install the library and CMake following the tutorial below.
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 theat
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 thechannels
attribute.
Thedepth
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 intoMat
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()
, anddepth()
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;
}
- 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).
- 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.
- 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 theval
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.