opencv图像旋转

功能:对一幅二值图像进行旋转,旋转后图像是倾斜的,然后再把倾斜图像最小的外接矩形(边界是水平垂直)区域取出来。基于这样的需求,图像旋转的时候是取原图像左上、左下和右上三个点,然后根据旋转的角度计算这三个点在目标图像上对应的点。

#include<stdio.h>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace cv;

int main(int argc,char** argv)
{
	Mat src = imread("t2.png",0);
	double angle = -90;
	int height = src.rows;
	int width = src.cols;
	Point2f srcTri[3],dstTri[3];
	//取原图像上的三个点,左上、左下和右上,根据旋转角度计算出在目标图像上对应的点
	srcTri[0] = Point2f(0,0);
	srcTri[1] = Point2f(width-1,0);
	srcTri[2] = Point2f(0,height-1);
	//把角度化成弧度
	double ang = fabs(angle)*CV_PI/180;
	double sina = sin(ang);
	double cosa = cos(ang);
	int newH,newW;
	//顺时针旋转的
	if(angle < 0)
	{
		dstTri[0] = Point2f(height*sina,0);
		dstTri[1] = Point2f(dstTri[0].x + width * cosa,width * sina);
		dstTri[2] = Point2f(0,height * cosa);
		newW = dstTri[1].x;
		newH = dstTri[2].y + width*sina;
	}
	else
	//逆时针旋转
	{
		dstTri[0] = Point2f(0,width * sina);
		dstTri[1] = Point2f(width*cosa,0);
		dstTri[2] = Point2f(height*sina,dstTri[0].y + height*cosa);
		newH = dstTri[2].y;
		newW = dstTri[1].x + height*sina;
	}
	printf("dstTri[0]:(%f,%f) dstTri[1]:(%f,%f) dstTri[2]:(%f,%f)\n",dstTri[0].x,dstTri[0].y,dstTri[1].x,dstTri[1].y,dstTri[2].x,dstTri[2].y);
	//计算仿射变换矩阵
	Mat warpMat = getAffineTransform(srcTri,dstTri);

	//dst这里高和宽随意设了一个很大的值
	Mat dst(500,500,CV_8U);

	warpAffine(src,dst,warpMat,dst.size(),INTER_LINEAR,BORDER_CONSTANT,Scalar(255));
	
	dst = dst(Rect(0,0,newW,newH));
	//二值图像旋转后在黑白交界的地方由于插值会变成黑色,为了使旋转后的图像仍是二值图像,就把灰色像素置0
	uchar *data = dst.data;
	int num = dst.cols*dst.rows;
	int i;
	Mat test(dst.rows,dst.cols,CV_8U,Scalar(255));
	uchar *data1 = test.data;
	for(i=0;i<num;i++)
	{
		if(*(data+i) != 0 && *(data+i) != 255)
		{
			*(data1+i) = 0;
		}
	}
	imshow("src",src);
	imshow("dst",dst);
	imshow("test",test);
	waitKey(0);
	return 0;
}

效果图:


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值