Using OpenCV 

In the OpenCV library, an image is treated as a multidimensional matrix of values. There is a special cv::Mat type for this purpose. There are two base functions: the cv::imread() function loads the image, and the cv::imwrite() function writes the image to a file, as illustrated in the following code snippet:

#include <opencv2/opencv.hpp>
..
cv::Mat img = cv::imread(file_name);
cv::imwrite(new_file_name, img);

Also, there are functions to manage images located in a memory buffer. The cv::imdecode() function loads an image from the memory buffer, and the cv::imencode() function writes an image to the memory buffer.

Scaling operations in the OpenCV library can be done with the cv::resize() function. This function takes an input image, an output image, the output image size or scale factors, and an interpolation type as arguments. The interpolation type governs how the output image will look after the scaling. General recommendations are as follows:

  • Use cv::INTER_AREA for shrinking.
  • Use cv::INTER_CUBIC (slow) or cv::INTER_LINEAR for zooming.
  • Use cv::INTER_LINEAR for all resizing purposes because it is fast.

The following code sample shows how to scale an image:

  cv::resize(img, img, {img.cols / 2, img.rows / 2}, 0, 0, cv::INTER_AREA);
cv::resize(img, img, {}, 1.5, 1.5, cv::INTER_CUBIC);

There is no special function for image cropping in the OpenCV library, but the cv::Mat type overrides the operator() method, which takes a cropping rectangle as an argument and returns a new cv::Mat object with part of the image surrounded by the specified rectangle. Also, note that this object will share the same memory with the original image, so its modification will change the original image too. To make a deep copy of the cv::Mat object, we need to use the clone() method, as follows:

  img = img(cv::Rect(0, 0, img.cols / 2, img.rows / 2));

Sometimes, we need to move or rotate an image. The OpenCV library supports translation and rotation operations for images through affine transformations. We have to manually—or with helper functions—create a matrix of 2D affine transformations and then apply it to our image. For the move (the translation), we can create such a matrix manually, and then apply it to an image with the cv::wrapAffine() function, as follows:

  cv::Mat trm = (cv::Mat_<double>(2, 3) << 1, 0, -50, 0, 1, -50);
cv::wrapAffine(img, img, trm, {img.cols, img.rows});

We can create a rotation matrix with the cv::getRotationMatrix2D() function. This takes a point of origin and the rotation angle in degrees, as illustrated in the following code snippet:

  auto rotm = cv::getRotationMatrix2D({img.cols / 2, img.rows / 2}, 45, 1);
cv::wrapAffine(img, img, rotm, {img.cols, img.rows});

Another useful operation is extending an image size without scaling but with added borders. There is the cv::copyMakeBorder() function in the OpenCV library for this purpose. This function has different options on how to create borders. It takes an input image, an output image, border sizes for the top, the bottom, the left and the right sides, type of the border, and border color. Border types can be one of the following:

  • BORDER_CONSTANT—Make function fill borders with a single color.
  • BORDER_REPLICATE—Make function fill borders with copies of last pixel values on each side (for example, aaaaaa|abcdefgh|hhhhhhh).
  •  BORDER_REFLECT—Make function fill borders with copies of opposite pixel values on each side (for example, fedcba|abcdefgh|hgfedcb).
  •  BORDER_WRAP—Make function fill borders by simulating the image duplication (for example, cdefgh|abcdefgh|abcdefg).

The following example shows how to use this function:

  int top = 50;     // px
int bottom = 20; // px
int left = 150; // px
int right = 5; // px
cv::copyMakeBorder(img, img, top, bottom, left, right,
cv::BORDER_CONSTANT | cv::BORDER_ISOLATED,
cv::Scalar(255, 0, 0));

When we are using this function, we should take care of the origin of the source image. The OpenCV documentation says: If the source image is a part of a bigger image, the function will try to use the pixels outside of the ROI (short for region of interest) to form a border. To disable this feature and always do extrapolation, as if the source image was not a part of another image, use border type BORDER_ISOLATED.

The function described previously is very helpful when we need to adapt training images of different sizes to the one standard image size used in some machine learning algorithms because, with this function, we do not distort target image content.

There is the cv::cvtColor() function to convert different color spaces in the OpenCV library. The function takes an input image, an output image, and a conversion scheme type. For example, in the following code sample, we convert the red, green, and blue (RGB) color space to a grayscaled one:

  cv::cvtColor(img, img,
cv::COLOR_RGB2GRAY); // now pixels values are in range 0-1
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.114.19