利用opencv怎样旋转一幅图像

图像旋转是指图像按照某个位置转动一定角度的过程,旋转中图像仍保持着原始尺寸。图像旋转后图像的水平对称轴、垂直对称轴以及中心坐标原点可能都会发生变换,因此需要对图像旋转中的坐标进行相应的转换

图像坐标构成

 

解释一下上面的各个步骤

由于图像坐标是以左上角为原点,向右为X正方向,向下为Y正方向。而旋转时一般使用的是常见的笛卡尔坐标系,向右为X正方向,向上为Y正方向。所以进行旋转变换的第一步就是坐标系转换。第一步先解释坐标系转换的过程。

 

 第二步解释旋转的过程

 

在进行图像旋转的过程中,图像以旋转中心为坐标原点,最终完成旋转还需要将坐标原点移动到图像的左上角。旋转后图像的尺寸可以由图像极值点确定,设旋转后图像的最左边点的横坐标为lxmin,最右边的横坐标为lxmax,最高点的纵坐标为lymin,最低点的纵坐标为lymax.

 

最后需要将坐标原点变换到旋转后图像的左上角坐标,根据旋转前后的坐标转换可得左上角坐标为,矩阵表示为:

 

#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;

}

运行程序结果如下: 

猜你喜欢

转载自blog.csdn.net/yangSHU21/article/details/131150241