With the advancement in silicon technologies, Artificial Intelligence and Image Processing have been used extensively for the last few years. Many of the applications that we use today are already using such complex technologies without us, the users, noticing any difference. For example, if you post an image of yourself and your colleagues on social networking site it automatically detects the faces and annotated them with an appropriate name. Or when you click an image from your smartphone it automatically blurs the background making a person or object much more prominent. All these types of applications use image processing algorithms and well-trained machine learning models to work correctly. OpenCV is one of the most prominent image processing libraries used in the market. In this article, we will see how to use the OpenCV library using C++ programming languages.
What is OpenCV?
OpenCV (Open Source Computer Vision Library) is an open-source computer vision and machine learning software library. OpenCV was built to provide a common infrastructure for computer vision applications and to accelerate the use of machine perception in commercial products. As OpenCV is based on BSD license, it allows individual researchers or organizations to use OpenCV libraries either in parts or in whole without forcing code to be open. OpenCV has C++, Python, Java, and MATLAB interfaces and supports Windows, Linux, Android, and Mac OS.
Getting started with OpenCV with C++
Installation
OpenCV can be directly downloaded from https://opencv.org/releases/ either as a library or in actual source code format, which later can be compiled locally to generate relevant libraries. In this example, I'll be using the Windows version of OpenCV which I've directly downloaded and unzipped into the C:\opencv4.5.3 folder.
Project Settings Configuration:
In order to write the C++ application, I've used Microsoft Visual Studio 2019 Community Edition. Before going into actual application creation, first, we need to add the path to OpenCV dependencies into project settings. We need to add the path to OpenCV header files into the include directory section. In my case, OpenCV library headers were under C:\opencv4.5.3\opencv\build\include directory. Similarly, we need to add the path to the OpenCV library in Library include the directory list which is used at the link stage. In my case OpenCV lib file was located in C:\opencv4.5.3\opencv\build\x64\vc14\lib directory. Below is the screenshot of the MSVS project setting wizard.
Similarly, I've added OpenCV .lib file in the linker section so that project builds successfully.
Once done with the above changes, we can continue with our actual C++ program. Please note if you are not using IDE then please add the above-mentioned path as per your machine's location into your make/build script.
OpenCV with C++ examples
In order to use OpenCV libraries, one has to include required modules as per their need. Below is a small example of a key OpenCV header file.
#include "opencv2/core.hpp"
New C++ data structures and arithmetic routines
#include "opencv2/miniflann.hpp"
Approximate nearest neighbor matching functions
#include "opencv2/imgproc.hpp"
New C++ image processing functions
#include "opencv2/photo.hpp"
Algorithms specific to handling and restoring photographs
#include "opencv2/video.hpp"
Video tracking and background segmentation routines
#include "opencv2/features2d.hpp"
Two-dimensional feature tracking support
#include "opencv2/objdetect.hpp"
Cascade face detector; latent SVM; HoG; planar patch detector
#include "opencv2/calib3d.hpp"
Calibration and stereo
#include "opencv2/ml.hpp"
Machine learning: clustering, pattern recognition
#include "opencv2/highgui.hpp"
New C++ image display, sliders, buttons, mouse, I/O
#include "opencv2/contrib.hpp"
User-contributed code: flesh detection, fuzzy mean-shift tracking, spin images, self-similar features
If you do not remember the exact header file name then simply use opencv.hpp which includes all the supported OpenCV functions.
#include <opencv2/opencv.hpp>
Include file for every supported OpenCV function
Loading and displaying image
The below simple program reads an image file from disk and then displays it. All OpenCV functions are inside cv namespace, user can either user cv::<function name> or use using directive. To simplify the example, we will use the namespace directive.
// read_image.cpp
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
string path = "Resources/land.jpg";
Mat img = imread(path, IMREAD_COLOR);
imshow("Display window", img);
waitKey(0);
return 0;
}
After compilation, if we run the resulting executable, below 'Display Window' appears with an image that we are trying to display from the disc.
Let's try to understand how the above program works. To read an image from the disk we need to use the cv::imread() function which returns Mat structure containing individual pixels and other details. Since Mat is C++object, it has some inbuild methods to get other details. Note that cv::imread() can read a wide variety of image formats, including BMP, DIB, JPEG, JPE, PNG, PBM, PGM, PPM, SR, RAS, and TIFF. Once the image is read into Mat object using cv::imshow() we can display the image.
The cv::waitKey() function asks the program to stop and wait for a keystroke. If a
positive argument is given, the program will wait for that number of milliseconds and
then continue even if nothing is pressed. If the argument is set to 0 or to a negative
number, the program will wait indefinitely for a key-press.
Since the image consists of RGB channel and if you need to extract one of the channels then one can use one of the below approaches to extract individual channels. For more details on color space please refer to this blog.
Mat img=imread("my.png"); // read image
Mat planes[3];
split(src,planes)
Mat img=imread("my.png");
cv::Mat out_img;
cv::extractChannel(img, out_img, 0) // 0: Blue, 1: Green, 2: Red channel
Note, if we want to store the image on a disc after some operation we need to use cv::imwrite() function.
imwrite("output.png",img);
Loading video and displaying individual frame
The Below program reads the mp4 video file and displays each frame into a window after a 10-millisecond delay between the two frames.
// read_video.cpp
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
int main()
{
string video_path = "Resources/test_video.mp4";
VideoCapture v_cap(video_path);
Mat img;
while (true) //generate exception once v_cap frame read is over
{
v_cap.read(img); // load each frame into img
imshow("Display window", img); // display img
waitKey(10); // delay of 10 ms
}
return 0;
}
Once we execute read_video.exe file 'Display window' will show each frame of test_video.mp4 at a 10-millisecond interval.
In the above example, we've used video capture object cv::VideoCapture and instantiated it with an mp4 file. Alternatively, we can simply declare cv::VideoCapture object and use the open method to read the input video file. For example, it would look something like this
string video_path = "Resources/test_video.mp4";
VideoCapture v_cap;
v_cap.open(video_path);
Once we have a valid video capture object we can read the individual frames from the input video file using one of the below approaches (inside the loop).
v_cap.read(img);
v_cap>>img; // overloaded extraction operator
The rest of the display part remains the same as we have seen with reading individual images. Since the computer runs on very high frequency, we've added WaitKey(10) which will wait for 10milliseconds before displaying the next frame.
Working with web camera
Working with a web camera is similar to the above example of reading input video files. The only change in the above program would be instantiating the cv::VideoCapture object with camera id. For the inbuilt webcam, it's 0 and for external, it's 1. Below is the program to read from the inbuilt webcam and display is named video.
// read_webcam.cpp
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
int main()
{
VideoCapture v_cap(0); // use 1 as id if using external webcam
Mat img;
while (true) //generate exception once v_cap frame read is over
{
v_cap.read(img); // load each frame into img
imshow("Display window", img); // display img
waitKey(10); // delay of 10 ms
}
return 0;
}
Conclusion
As we can see from the above examples, the OpenCV library contains a variety of functions that are very simple to use. Using the above simple example one can familiarize with the OpenCV library and then continue to build more complex image processing applications.
Hello! I also want to learn how to program in C++ and would like to see a couple of training videos. Could you create them? Click to read more about it here. I would like to see a series of training videos.