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 :
- OpenCV4 machine learning ( One ):OpenCV4+VS2017 Environment construction and configuration
- OpenCV4 machine learning ( Two ): Image reading 、 Display and storage
- OpenCV4 machine learning ( 3、 ... and ): Color space (RGB、HSI、HSV、Lab、Gray) Conversion between
List of 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)] (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] ⎣⎡100010001⎦⎤ | x = v , y = w 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] ⎣⎡cx000cy0001⎦⎤ | x = c x v , y = c y w x =c_{x}v, y=c_{y}w x=cxv,y=cyw |
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] ⎣⎡cosθ−sinθ0sinθcosθ0001⎦⎤ | 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 x=vcosθ−wsinθ,y=vsinθ+wcosθ |
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] ⎣⎡10tx01ty001⎦⎤ | x = v + t x , y = w + t y x=v+t_{x}, y=w+t_{y} x=v+tx,y=w+ty |
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] ⎣⎡1sh0010001⎦⎤ | x = v + w s h , y = w x=v+ws_{h}, y=w x=v+wsh,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] ⎣⎡100sv10001⎦⎤ | x = v , y = w + v s v x=v, y=w+vs_v x=v,y=w+vsv |
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 x=cxv,y=cyw 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()
{
Mat img = imread("D:\\CSDN\\dog.jpg", 1);
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} x=v+tx,y=w+ty 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()
{
Mat img = imread("D:\\CSDN\\lena.jpeg", 1);
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 x=vcosθ−wsinθ,y=vsinθ+wcosθ 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 = imread("D:\\CSDN\\lena.jpeg", 1);
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 x=v+wsh,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 = imread("D:\\CSDN\\lena.jpeg", 1);
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 !