图像的旋转操作

图像的旋转的额基本原理:

















图像的每个像素需要经过如下3步完成旋转。

①由输入图像的坐标系转换为数学坐标系。
②通过数学旋转坐标系计算指定像素旋转后的坐标。
③由旋转坐标系转换为输出图像的坐标系。





话不多说放上源代码:

#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<cmath>
#include<iostream>
using namespace cv;
using namespace std;
//旋转图像
Mat RotIamge(Mat &srcImage, float Angle) //旋转角度然后返回一张旋转后的图像
{
	//以图像的中心为原点求出原图中的四个角的坐标
	float SrcX1, SrcY1, SrcX2, SrcY2, SrcX3, SrcY3, SrcX4, SrcY4;
	//新图中四个角的坐标
	float DstX1, DstY1, DstX2, DstY2, DstX3, DstY3, DstX4, DstY4;
	//将角度转换位弧度
	float alpha = Angle*CV_PI / 180;
	//原图的宽高
	int Wold = srcImage.cols;
	int Hold = srcImage.rows;

//假设原图的原点在原图的中心主要是为了求出新图的宽高
	//原图的四个角的坐标
	SrcX1 = (float)((-0.5)*Wold);
	SrcY1 = (float)((0.5)*Hold);
	SrcX2 = (float)((0.5)*Wold);
	SrcY2 = (float)((0.5)*Hold);
	SrcX3 = (float)((-0.5)*Wold);
	SrcY3 = (float)((-0.5)*Hold);
	SrcX4 = (float)((0.5)*Wold);
	SrcY4 = (float)((-0.5)*Hold);
	//求出cosa 和sina
	float cosa = cos(alpha);
	float sina = sin(alpha);

	//求出新图的四个角的坐标
	DstX1 = cosa*SrcX1 + sina*SrcY1;
	DstY1 = -sina*SrcX1 + cosa*SrcY1;
	DstX2 = cosa*SrcX2 + sina*SrcY2;
	DstY2 = -sina*SrcX2 + cosa*SrcY2;
	DstX3 = cosa*SrcX3 + sina*SrcY3;
	DstY3 = -sina*SrcX3 + cosa*SrcY3;
	DstX4 = cosa*SrcX4 + sina*SrcY4;
	DstY4 = -sina*SrcX4 + cosa*SrcY4;

	//计算新图的宽和高
	int Wnew = cvRound(max(abs(DstX4 - DstX1), abs(DstX3 - DstX2)));
	int Hnew = cvRound(max(abs(DstY4 - DstY1), abs(DstY3 - DstY2)));

	//计算矩阵中的两个常数
	float num1 = (float)(-0.5*Wnew*cosa - 0.5*Hnew*sina + 0.5*Wold);
	float num2 = (float)(0.5*Wnew*sina - 0.5*Hnew*cosa + 0.5*Hold);
	//创建一张新的大小的图
	Mat resultImage(Hnew, Wnew, srcImage.type());
	for (int i = 0; i < Hnew; i++) //rows
	{
		for (int j = 0; j < Wnew; j++)//cols
		{
			//求出新图中的像素在原图的位置
			int x = cvRound(i*cosa + j*sina + num1);
			int y = cvRound(-sina*i + j*cosa + num2);
			if ((x >= 0) && (x < Wold) && (y >= 0) && (y < Hold))//在原图中的范围
			{
				resultImage.at<Vec3b>(i, j) = srcImage.at<Vec3b>(x, y);
			}
		}
	}
	return resultImage;
}
int main()
{
	Mat srcImage = imread("lakeWater.jpg");
	if (!srcImage.data)
	{
		printf("image could not load...\n");
		return -1;
	}
	imshow("srcImage", srcImage);
	Mat resultImage = RotIamge(srcImage,30);
	imshow("resultImage", resultImage);
	waitKey(0);
	return 0;

}

原图:



旋转之后的效果图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值