图像旋转是指图像按照某个位置转动一定角度的过程,旋转中图像仍保持着原始尺寸。图像旋转后图像的水平对称轴、垂直对称轴以及中心坐标原点可能都会发生变换,因此需要对图像旋转中的坐标进行相应的转换
图像坐标构成
文章来源:https://www.toymoban.com/news/detail-707768.html
解释一下上面的各个步骤
由于图像坐标是以左上角为原点,向右为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;
}
运行程序结果如下: 文章来源地址https://www.toymoban.com/news/detail-707768.html
到了这里,关于利用opencv怎样旋转一幅图像的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!