利用opencv函数对图像旋转后,按旋转偏移新计算新的图像外接四边形绘制

利用模板匹配后,基于模板旋转1度角度逼近匹配目标图像,计算出第一个符合的目标模组图像的旋转角度,记录目标模组

旋转角度为⊙,模板选定的正方形区域,利用 matchTemplate函数,匹配方法选取平方差匹配,method=CV_TM_SQDIFF,

计算出最小旋转角度,但是需要绘制出旋转外接四边形, minMaxLoc函数,寻找到最小值的左上角顶点坐标,记录为x1,y1;

如图所示,偏转后的左上角的顶点为x11,y11,

     

x11,y11是目标模组的偏移后的坐标点的位置,x1,y1的坐标位置与模组中心位置的夹角为正方形的夹角

为45度,偏转角度上面算出为⊙,可以计算出x1,y1到中心之间的距离L的长度为,三角形的斜边。旋转后的图像

x11,y11到旋转中心的长度L未变。根据以上几个参数可以算出旋转后的新的坐标点的位置。

void new(Mat &display,Mat &tempImg,int &x,int &y,double &theta, Point2f *subP3)
{
    int ox = 2;
    int oy = 2;

    int nx = x;
    int ny = y;
    nx+=ox;ny+=oy;
    
    float cols = (float)tempImg.cols;
float rows = (float)tempImg.rows;
cols-=2*ox;rows-=2*oy;
//cout<<"cols="<<cols<<"rows"<<rows<<endl;
double theta1 = 45*3.14/180;//原始图像最小顶点与旋转中心的夹角
double theta2 = -theta*3.14/180;//模板匹配后的图像偏转角度
//cout<<"sintheta"<<sin(theta1)<<endl;
int l = sqrtf(cols*cols+rows*rows)/2;//斜边的长度L,固定不变,勾股定理算出
//cout<<"l="<<l<<endl;
/*对于opencv整个图像坐标的起点的偏移计算,nx+cols/2为x1做偏移处理后的nx加上图像一半

像素长度的坐标,再减去旋转后的点的x的长度(-L*cos(theta1+theta2)),即为新的坐标点的x坐标,

y同理*/

int x1 = -l*cos(theta1+theta2)+nx+cols/2;
int y1 = -l*sin(theta1+theta2)+ny+rows/2;
//cout<<"x1="<<nx<<"y1="<<ny<<endl;
//cout<<"x1'="<<x1<<"y1'="<<y1<<endl;
/*x2y2*/
int x2 = -l*cos(theta1-theta2)+nx+cols/2;
int y2 = l*sin(theta1-theta2)+ny+rows/2;
//cout<<"x1="<<nx<<"y1="<<ny+rows<<endl;
//cout<<"x1'="<<x2<<"y1'="<<y2<<endl;
/*x3y3*/

/*这边的每个偏移后的x,y的坐标都需要做一次根据L与旋转角度的正弦余弦变化,计算出新的x,y长度,所以

前面的参数有+有-,角度的有加有减*/
int x3 = l*cos(theta1-theta2)+nx+cols/2;
int y3 = -l*sin(theta1-theta2)+ny+rows/2;
//cout<<"x3="<<nx+cols<<"y3="<<ny<<endl;
//cout<<"x3'="<<x3<<"y3'="<<y3<<endl;
/*x4y4*/
int x4 = l*cos(theta1+theta2)+nx+cols/2;
int y4 = l*sin(theta1+theta2)+ny+rows/2;
//cout<<"x="<<nx+cols<<"y="<<ny+rows<<endl;
//cout<<"x'="<<x4<<"y'="<<y4<<endl;
/*new rect*/
//将新的坐标点存入Point2f的坐标点组。

    subP3[0].x = x1;
    subP3[0].y = y1;
    subP3[1].x = x3;
    subP3[1].y = y3;
    subP3[2].x = x4;
    subP3[2].y = y4;
    subP3[3].x = x2;
    subP3[3].y = y2;

//最后根据line函数画出图像外接四边形
    for(int jj = 0; jj <=3; jj++)
      {
line(display,subP3[jj],subP3[(jj+1)%4],Scalar(255,255,0),1);
      }
imshow("srcImg", display);   


}

效果图像:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值