Opencv4 machine learning (4): geometric transformation and affine transformation of images
AI bacteria 2021-08-03 09:44:23

Preface ：

This column mainly combines OpenCV4（C++ edition ）, To realize some basic image processing operations 、 Classical machine learning algorithms （ such as K-Means、KNN、SVM、 Decision tree 、 Bayesian classifier, etc ）, And common deep learning algorithms .

Series articles ：

## One 、 The basic principle

Translation of image 、 The zoom 、 Mirroring and rotation are geometric transformations . In digital image processing , Geometric transformation consists of two basic operations ： Coordinate transformation and gray interpolation . The coordinate transformation formula can be expressed as ： ( x , y ) = T [ ( v , w ) ] (x, y) = T[(v, w)] .

among ,（v, w） Is the pixel coordinates in the source image ;（x, y） Is the pixel coordinates in the transformed image .

One of the most common spatial transformations is Affine transformation , Its general form is as follows ：

According to the matrix T The values of elements in are different , Affine transformation can be divided into ： Identity transformation 、 Scale transformation 、 Rotation transformation 、 Translation transformation 、 Vertical transform or horizontal shear transform . The details are shown in the table below ：

Change the name Affine matrix T Coordinate formula
Identity transformation [ 1 0 0 0 1 0 0 0 1 ] \left[ \begin{matrix}1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{matrix} \right] x = v , y = w x=v, y=w
Scale transformation [ c x 0 0 0 c y 0 0 0 1 ] \left[ \begin{matrix}c_{x} & 0 & 0 \\ 0 & c_{y} & 0 \\ 0 & 0 & 1 \end{matrix} \right] x = c x v , y = c y w x =c_{x}v, y=c_{y}w
Rotation transformation [ c o s θ s i n θ 0 − s i n θ c o s θ 0 0 0 1 ] \left[ \begin{matrix}cos\theta & sin\theta & 0 \\ -sin\theta &cos\theta & 0 \\ 0 & 0 & 1 \end{matrix} \right] x = v c o s θ − w s i n θ , y = v s i n θ + w c o s θ x=vcos\theta-wsin\theta, y=vsin\theta+wcos\theta
Translation transformation [ 1 0 0 0 1 0 t x t y 1 ] \left[ \begin{matrix}1 & 0 & 0 \\ 0 & 1 & 0 \\ t_{x} & t_{y} & 1 \end{matrix} \right] x = v + t x , y = w + t y x=v+t_{x}, y=w+t_{y}
Vertical transformation [ 1 0 0 s h 1 0 0 0 1 ] \left[ \begin{matrix}1 & 0 & 0 \\ s_{h} & 1 & 0 \\ 0 & 0 & 1 \end{matrix} \right] x = v + w s h , y = w x=v+ws_{h}, y=w
Horizontal shear transform [ 1 s v 0 0 1 0 0 0 1 ] \left[ \begin{matrix}1 & s_{v} & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{matrix} \right] x = v , y = w + v s v x=v, y=w+vs_v

## Two 、 Affine transformation warpAfine

stay OpenCV in , The function to realize affine transformation is ：cv::warpAffine function . Its definition is as follows ：

void cv::warpAffine(InputArray src,
OutputArray dst,
InputArray M,
Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar= & boaderValue = Scalar())

Introduction to each parameter ：

• src： The input image
• dst： Output image
• M： Transformation matrix
• dsize： Output image size ; If dsize=(0,0), Then it is calculated by the following formula ：dsize=Size(round(fx * src.cols), round(fy * src.rows))
• flags： Combined flag bit
• borderMode： Pixel extrapolation method
• borderValue： The value used when the boundary bit is constant , The default is 0

By changing warpAffine Function Transformation matrix M , Can be easily implemented ： Identity transformation 、 Scale transformation 、 Rotation transformation 、 Translation transformation 、 Vertical transform or horizontal shear transform .

## 3、 ... and 、 Scale transformation

### （1）resize Function implementation

Scale transformation is also called image scaling , stay OpenCV in , You can use resize Function to realize scale transformation .resize function The definition is as follows ：

void cv::resize(InputArray src,
OutputArray dst,
Size dsize,
Double fx=0,
Double fy=0,
Int interpolation = INTER_LINEAR)

Introduction to each parameter ：

• src： The input image
• dst： Output image
• dsize： Output image size ; If dsize=(0,0), Then it is calculated by the following formula ：dsize=Size(round(fx * src.cols), round(fy * src.rows))
• fx： Horizontal axis scaling factor ;fx、fy Not all for 0.
• fy： Vertical axis scaling factor
• interpolation： Interpolation algorithm

By calling resize function , You can scale the original image to half the original size ：

resize(img, img_resize, cv::Size(0, 0), 0.5, 0.5, 1);

### （2）warpAffine Function implementation

The so-called scale transformation , The original coordinates of the pixels in the image （v, w） according to x = c x v , y = c y w x =c_{x}v, y=c_{y}w The rules of , The switch to （x, y）. Its simplified form can be expressed by the following formula ：

therefore , adopt warpAffine function , Transform the matrix M Set to ：

Scale transformation can also be easily realized , The specific implementation method is as follows ：

warpAffine(img, img_warpAffine, M, size, INTER_LINEAR, 1); // Affine transformation

### （3） Summary of actual combat

Use... Respectively resize Functions and warpAfine function , To achieve scale transformation ：

#include <iostream>
#include <opencv.hpp>
using namespace std;
using namespace cv;
int main()
{

imshow("original", img);
/*************** Scale transformation ***************/
// Method 1：resize
Mat img_resize;
resize(img, img_resize, cv::Size(0, 0), 0.5, 0.5, 1);
imshow("resize", img_resize);
// Method 2： Affine transformation
Mat img_warpAffine;
Mat M = Mat::zeros(2, 3, CV_32F); // Declare scale transformation M matrix (2x3)
float cx = 0.5, cy = 0.5;
M.at<float>(0, 0) = cx;
M.at<float>(1, 1) = cy;
cv::Size size = img.size();
size.width *= cx;
size.height *= cy;
warpAffine(img, img_warpAffine, M, size, INTER_LINEAR, 1); // Affine transformation
imshow("warpAffine", img_warpAffine);
waitKey(0);
return 0;
}

Display as shown below ：

## Four 、 Translation transformation

For translation transformation , The original coordinates of the pixels in the image （v, w） according to x = v + t x , y = w + t y x=v+t_{x}, y=w+t_{y} The rules of , The switch to （x, y）. Its simplified form can be expressed by the following formula ：

therefore , adopt warpAffine function , Transform the matrix M Set to ：

Translation transformation can be easily realized , The specific implementation method is as follows ：

#include <iostream>
#include <opencv.hpp>
using namespace std;
using namespace cv;
int main()
{

imshow("original", img);
Mat img_trans;
Mat M1 = cv::Mat::eye(2, 3, CV_32F); // Declare the translation transformation matrix M1（2x3）, And initialize the diagonal element to 1
float tx = 40, ty = 20; // Set the translation transformation parameters
M1.at<float>(0, 2) = tx;
M1.at<float>(1, 2) = ty;
// In order to display the translated image completely , Expand the edge here , Put the original picture on 、 Next 、 Left 、 Expand the corresponding elements in the four right directions , The extended region is filled with constant gray value 200
int top = 0, bottom = ty, left = 0, right = tx;
cv::copyMakeBorder(img, img_trans, top, bottom, left, right, BORDER_CONSTANT, cv::Scalar(200)); // Expanding edge
cv::warpAffine(img_trans, img_trans, M1, img_trans.size(), INTER_LINEAR, BORDER_TRANSPARENT);
imshow("translation", img_trans);
waitKey(0);
return 0;
}

The effect after the original image and translation transformation is shown in the following figure ：

## 5、 ... and 、 Rotation transformation

For rotation transformation , The original coordinates of the pixels in the image （v, w） according to x = v c o s θ − w s i n θ , y = v s i n θ + w c o s θ x=vcos\theta-wsin\theta, y=vsin\theta+wcos\theta The rules of , The switch to （x, y）. Its simplified form can be expressed by the following formula ：

therefore , adopt warpAffine function , Transform the matrix M Set to ：

Rotation transformation can be easily realized , The specific implementation method is as follows ：

#include <iostream>
#include <opencv.hpp>
using namespace std;
using namespace cv;
int main()
{

Mat img_rotate;
double angle = 45; // Set the rotation angle
int border = 0.207 * img.cols;
cv::copyMakeBorder(img, img_rotate, border, border, border, border, BORDER_CONSTANT, cv::Scalar(0)); // Expanding edge
cv::Point2f center(img_rotate.cols / 2., img_rotate.rows / 2.); // Specify the center of rotation
cv::Mat M2 = cv::getRotationMatrix2D(center, angle, 1.0); // Get the rotation transformation matrix M2
cv::warpAffine(img_rotate, img_rotate, M2, img_rotate.size(), INTER_LINEAR, BORDER_REPLICATE);
cv::imshow("rotate", img_rotate);
waitKey(0);
return 0;
}

Pass around the center 45 degree , The effect image after rotation transformation is shown below ：

## 6、 ... and 、 Shear transform

The shear transformation includes vertical shear and horizontal shear , Let's take vertical cutting as an example , The original coordinates of the pixels in the image （v, w） according to x = v + w s h , y = w x=v+ws_{h}, y=w The rules of , The switch to （x, y）. Its simplified form can be expressed by the following formula ：

therefore , adopt warpAffine function , Transform the matrix M Set to ：

Vertical rotation transformation can be easily realized , The specific implementation method is as follows ：

#include <iostream>
#include <opencv.hpp>
using namespace std;
using namespace cv;
int main()
{

Mat img_shear_vertical;
int border = 40;
cv::copyMakeBorder(img, img_shear_vertical, 10, 10, 10, 10+4* border, BORDER_CONSTANT, cv::Scalar(0)); // Expanding edge
Mat M3 = cv::Mat::eye(2, 3, CV_32F); // Declare the vertical shear transform M3 matrix （2x3）, Initialize the diagonal to 1
float sv = 0.3; // Vertical shear coefficient
M3.at<float>(0, 1) = sv;
cv::warpAffine(img_shear_vertical, img_shear_vertical, M3, img_shear_vertical.size(), INTER_LINEAR, BORDER_REPLICATE);
cv::imshow("shear_vertical", img_shear_vertical);
waitKey(0);
return 0;
}

The effect of vertical rotation transformation of the original image is shown in the following figure ：

All the complete code for this column will be in my GitHub Update on warehouse , Welcome to learn ：

Get into GitHub Warehouse , Click on star ( Red arrow ), Get dry goods at the first time ：

The best relationship is Each achievement , Everyone 「 Three even 」 Namely 【AI bacteria 】 The greatest power of creation , See you next time ！