opencv图像的旋转角度计算,opencv 旋转任意角度

opencv图像的旋转角度计算,opencv 旋转任意角度,opencv图片的任意角度旋转实现示例

本博客将介绍如何使用OpenCV对图像进行任意角度的旋转,实现所有角度的旋转,具有一定的参考价值。有需要的朋友就跟着下面的边肖学习吧。

目录

-旋转角度坐标的计算-旋转任意角度的步骤3的实现

一 旋转角度坐标的计算

1.若以O点为圆心,P点绕O点旋转一个弧度后,P点坐标转换为Q点的计算公式为:

q . x=p . x * cos(redian)-p . y * sin(redian)

q . y=p . x * sin(redian)p . y * cos(redian)

Redian代表弧度。

弧度和角度之间的转换公式为:

redian=pi * 180/角度

2.如果O点不是圆心,P点绕O点旋转一个半径弧度后,P点到Q点的坐标变换计算公式如下:

q . x=(p . x-o . x)* cos(redian)-(p . y-o . y)* sin(redian)o . x

q . y=(p . x-o . x)* sin(redian)(p . y-o . y)* cos(redian)o . y

二 旋转任意角度的步骤

1.首先,图像默认旋转45度时,展开的图像最大,即长度或宽度的最大值为根号的两倍,图像填充到可能的最大值。

使用getRotationMatrix2D函数获取旋转矩阵,使用warpAffine函数旋转矩阵。

3找到包含旋转后图像的最大矩形。

4删除多余的黑色边框。

三 实现

#包括iostream

# includeopenv2/opencv . HPP

使用名称空间cv;

void rotate _ arbitrary _ angle(Mat src,Mat dst,float angle)

{

浮动弧度=(float)(角度/180.0 * CV _ PI);

//填充图像

int max border=(int)(max(src . cols,src . rows)* 1.414);//是sqrt(2)*max。

int dx=(max border-src . cols)/2;

int dy=(max border-src . rows)/2;

copyMakeBorder(src,dst,dy,dy,dx,dx,BORDER _ CONSTANT);

//旋转

point 2f center((float)(dst . cols/2),(float)(dst . rows/2));

mat affine _ matrix=getrotationmatrix 2d(中心,角度,1.0);//找到旋转矩阵

warpAffine(dst,dst,affine_matrix,dst . size());

//计算图像旋转后包含图像的最大矩形

float sinVal=abs(sin(弧度));

float cosVal=abs(cos(弧度));

size targetSize((int)(src . cols * cos val src . rows * sinVal),

(int)(src . cols * sin val src . rows * cos val));

//剪掉多余的边框

int x=(dst . cols-targetsize . width)/2;

int y=(dst . rows-targetsize . height)/2;

Rect rect(x,y,targetSize.width,targetsize . height);

dst=Mat(dst,rect);

}

int main() {

cv:Mat src=cv:imread(./3 . png’);

cv:Mat dst;

rotate _ arbitrary _ angle(src,dst,30);

cv:imshow(src ,src);

cv:imshow(dst ,dst);

cv:wait key(0);

返回0;

}

原图

围绕中心点旋转30度的结果

需要注意的是,这种方法只适用于将水平图像旋转成角度图像。至于可以随意旋转角度的方法,现在不知道怎么做,以后还会再做。

上述方法的最大缺点是旋转后像素大小发生变化。如果要在像素上操作,会有很多问题。下一个代码会固定像素,但也是针对旋转到一定角度再回到水平位置的代码。它有很大的局限性,所以我们会在研究了解后更新其他情况。

cv:Mat rotate _ arbitrary _ angle 1(cv:Mat matSrc,float angle,bool direction,int height,int width) {

float theta=角度* CV _ PI/180.0;

int nRowsSrc=mat src . rows;

int nColsSrc=mat src . cols;//如果顺时针旋转

如果(!方向)theta=2 * CV _ PI-theta;//都是逆时针旋转计算的

//逆时针旋转矩阵

浮动矩阵[3][3]{ {

STD:cos(),-STD:sin(),0},

{ STD:sin(),STD:cos(),0 },

{0, 0, 1} };

浮动点[3][2]{

{ 0,nRowsSrc },

{nColsSrc,nRowsSrc},

{nColsSrc,0 } };

for(int I=0;i3;i ) {

float x=pt[I][0]* matRotate[0][0]pt[I][1]* matRotate[1][0];

float y=pt[I][0]* matRotate[0][1]pt[I][1]* matRotate[1][1];

pt[I][0]=x;pt[I][1]=y;

}

//计算旋转后图像的极值点和大小。

float fMin _ x=STD:min(STD:min(STD:min(pt[0][0],pt[1][0]),pt[2][0]),(float)0.0);

float fMin _ y=STD:min(STD:min(STD:min(pt[0][1],pt[1][1]),pt[2][1]),(float)0.0);

float fMax _ x=STD:max(STD:max(STD:max(pt[0][0],pt[1][0]),pt[2][0]),(float)0.0);

float fMax _ y=STD:max(STD:max(STD:max(pt[0][1],pt[1][1]),pt[2][1]),(float)0.0);

int nRows=cv round(fMax _ y-fMin _ y 0.5)1;

int nCols=cv round(fMax _ x-fMin _ x 0.5)1;

int nMin _ x=cv round(fMin _ x 0.5);

int nMin _ y=cv round(fMin _ y 0.5);

//复制输出图像

cv:Mat matRet(nRows,nCols,matSrc.type(),cv:Scalar(0));

for(int j=0;j nRowsj ) {

for(int I=0;i nColsi ) {

//计算输出图像对应点在原始图像中的坐标,然后复制坐标的灰度值。

//因为是逆时针转换,所以在这里映射到原图的时候可以视为输出图。

//对原图进行顺时针旋转,顺时针旋转矩阵只是逆时针旋转矩阵的转置。

//也可以考虑将旋转后的图像左上角移动到坐标原点。

int x=(I nMin _ x)* matRotate[0][0](j nMin _ y)* matRotate[0][1];

int y=(I nMin _ x)* matRotate[1][0](j nMin _ y)* matRotate[1][1];

if (x=0 x nColsSrc y=0 y nRowsSrc) {

matRet.atuchar(j,i)=matSrc.atuchar(y,x);

}

}

}

If(direction==false){//当需要顺时针旋转回到水平位置时

int x=(matret . cols-width)/2;

int y=(matret . rows-height)/2;

//width和height是图像在水平条件下的宽度和高度。

cv:Rect rect(x,y,width,height);

matRet=cv:Mat(matRet,rect);

}

返回matRet

}

关于opencv图像任意角度旋转的实现示例,本文到此结束。有关opencv图像任意角度旋转的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!

opencv图像的旋转角度计算,opencv 旋转任意角度