How to rotate an image using opencv

Image rotation refers to the process of rotating an image at a certain angle according to a certain position, and the image still maintains its original size during rotation. After the image is rotated, the horizontal axis of symmetry, the vertical axis of symmetry, and the origin of the central coordinates of the image may all be transformed, so the coordinates in the image rotation need to be transformed accordingly

Image coordinate composition

 

 

Explain the steps above

Since the image coordinates are based on the upper left corner as the origin, the right direction is the positive X direction, and the downward direction is the positive Y direction. When rotating, the common Cartesian coordinate system is generally used, and the right direction is the positive X direction, and the upward direction is the positive Y direction. So the first step in the rotation transformation is the coordinate system transformation. The first step is to explain the process of coordinate system conversion.

 

 The second step explains the process of rotation

 

During the process of image rotation, the image takes the rotation center as the origin of coordinates, and the final rotation needs to move the origin of coordinates to the upper left corner of the image. The size of the rotated image can be determined by the extreme points of the image. Let the abscissa of the leftmost point of the rotated image be lxmin, the rightmost abscissa be lxmax, the ordinate of the highest point be lymin, and the ordinate of the lowest point be lymax .

 

Finally, it is necessary to transform the origin of the coordinates to the coordinates of the upper left corner of the rotated image. According to the coordinate conversion before and after rotation, the coordinates of the upper left corner can be obtained. The matrix is ​​expressed as:

 

 

#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;

Mat angleRotate(Mat& src, int angle)
{
	//角度转换
	float alpha = angle * CV_PI / 180;
	//构造旋转矩阵
	float rotateMat[3][3] = {
		{cos(alpha),-sin(alpha),0},
		{sin(alpha),cos(alpha),0},
		{0,0,1} };
	int nSrcRows = src.rows;
	int nSrcCols = src.cols;

	//计算旋转后图像矩阵的各个顶点位置
	float a1 = nSrcCols * rotateMat[0][0];
	float b1 = nSrcCols * rotateMat[1][0];
	float a2 = nSrcCols * rotateMat[0][0] + nSrcRows * rotateMat[0][1];
	float b2 = nSrcCols * rotateMat[1][0] + nSrcRows * rotateMat[1][1];
	float a3 = nSrcRows * rotateMat[0][1];
	float b3 = nSrcRows * rotateMat[1][1];
	//计算出极值点
	float kxMin = min(min(min(0.0f, a1), a2), a3);
	float kxMax = max(max(max(0.0f, a1), a2), a3);
	float kyMin = min(min(min(0.0f, b1), b2), b3);
	float kyMax = max(max(max(0.0f, b1), b2), b3);
	//计算输出矩阵的尺寸
	int nRows = abs(kyMax - kyMin);
	int nCols = abs(kxMax - kxMin);
	Mat dst(nRows, nCols, src.type(), Scalar::all(0));
	for (int i = 0; i < nRows; ++i)
	{
		for (int j = 0; j < nCols; ++j)
		{
			//旋转坐标变换
			int x = (j + kxMin) * rotateMat[0][0] - (i + kyMin) * rotateMat[0][1];
			int y = -(j + kxMin) * rotateMat[1][0] +(i + kyMin) * rotateMat[1][1];
			//区域旋转
			if (x >= 0 && x < nSrcCols && y >= 0 && y < nSrcRows)
			{
				dst.at<Vec3b>(i, j) = src.at<Vec3b>(y, x);
			}
		}
	}
	return dst;
}
int main()
{
	Mat src = imread("C:\\Users\\32498\\Pictures\\16.png");
	if (!src.data)
	{
		return -1;
	}
	imshow("src", src);
	int angle = 30;
	Mat result = angleRotate(src, angle);
	imshow("result",result);
	waitKey();
	return 0;

}

The result of running the program is as follows: 

Guess you like

Origin blog.csdn.net/yangSHU21/article/details/131150241