前言
Opencv中是没有直接图像旋转的函数的,只能通过仿射变换实现,但在实现过程中会出现部门内容被裁剪的情况,在解决这个问题上,耗费了一点时间,走了一些弯路,故记录之。
Opencv各版本可在:https://www.ixxin.cn/software.html下载到,需要注意的是Opencv版本越高,支持的VS版本也越高。
主要问题
主要问题就是,旋转后,图像会变大,如图:

解决方法:

第二个问题就是,把图像比例放大后,旋转中心不会变,导致图像还是被裁切状态,如图:

解决方法就是把旋转中心移到新生成图像的中点。
代码
Opencv1代码:
 
IplImage* rotateImage1(IplImage* img,int degree){  
    double angle = degree  * CV_PI / 180.;   
    double a = sin(angle), b = cos(angle);   
    int width = img->width;    
    int height = img->height;    
    int width_rotate= int(height * fabs(a) + width * fabs(b));    
    int height_rotate=int(width * fabs(a) + height * fabs(b));    
    // [ m0  m1  m2 ] ===>  [ A11  A12   b1 ]  
    // [ m3  m4  m5 ] ===>  [ A21  A22   b2 ]  
    float map[6];  
    CvMat map_matrix = cvMat(2, 3, CV_32F, map);    
    CvPoint2D32f center = cvPoint2D32f(width / 2, height / 2);    
    cv2DRotationMatrix(center, degree, 1.0, &map_matrix);    
    map[2] += (width_rotate - width) / 2;    
    map[5] += (height_rotate - height) / 2;    
    IplImage* img_rotate = cvCreateImage(cvSize(width_rotate, height_rotate), 8, 3);   
    cvWarpAffine( img,img_rotate, &map_matrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(0));    
    return img_rotate;  
}  
Opencv2代码:(注:注释中有Opencv1的调试代码,可以忽略不看,本程序还实现了Opencv1跟Opencv2联合使用,转换的代码)
/*
作者:山科_xxin
时间:2017-03-19 23:04:38
功能:图像旋转
类别:Opencv学习
Opencv版本2.4.11
IDE:VS2010
*/
#include<iostream>
#include<stdlib.h>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
//#include<cv.h>
//#include<highgui.h>
using namespace std;
using namespace cv;
int fsbh(Mat srcimg)
{
	Mat dstimg;
	Mat rotimg;
	int row,col;
	Point2f srcTri[3];
	Point2f dstTri[3];
	Mat warpMat(2,3,CV_32FC1);//2*3矩阵,float类型;
	srcimg = imread("G:/opencv/1.jpg");
	if(!srcimg.data)
	{
		cout<<"读取错误"<<endl;
		return false;
	}
	row = srcimg.rows;
	col = srcimg.cols;
	cout<<"行:"<<row<<"列:"<<col<<endl;
	//三种方法创建
	//dstimg = Mat::zeros(srcimg.rows,srcimg.cols,srcimg.type());
	//dstimg = Mat::zeros(srcimg.size(),srcimg.type());
	//dstimg.create(srcimg.size(),srcimg.type());
	srcTri[0] = Point2f(0,0);
	srcTri[1] = Point2f(col-1,0);
	srcTri[2] = Point2f(0,row-1);
	dstTri[0] = Point2f( col*0.0, row*0.33 );
    dstTri[1] = Point2f( col*0.85, row*0.25 );
    dstTri[2] = Point2f( col*0.15, row*0.7 );
	warpMat = getAffineTransform(srcTri,dstTri);
	warpAffine(srcimg,dstimg,warpMat,dstimg.size());
	Point2f center(col/2,row/2);
	int degree = -30;  
	double angle = degree*CV_PI/180; //转换为弧度 
	double scale = 1;
	double a = sin(angle);
	double b = cos(angle);
	int width = col;
	int height = row;
	int rewidth = int(height*fabs(a)+width*fabs(b));
	int reheight = int(width*fabs(a)+height*fabs(b));
	cout<<rewidth<<endl<<reheight<<endl;
	Mat rot = getRotationMatrix2D(center,degree,scale);
	double* p = (double*)rot.data; 
	p[2] += (rewidth-width)/2;
	p[5] += (reheight-height)/2;
	//rotimg = Mat::zeros(rewidth,reheight,srcimg.type());
	//warpAffine(srcimg,rotimg,rot,srcimg.size(),0,0,0);
	warpAffine(srcimg,rotimg,rot,cv::Size(rewidth,reheight),0,0,0);
	/*
	//IplImage->Mat
	IplImage *ipimg;
	ipimg = &IplImage(srcimg);
	float map[6];
	CvMat map_matrix = cvMat(2,3,CV_32F,map);
	CvPoint2D32f center1 = cvPoint2D32f(width/2,height/2);
	cv2DRotationMatrix(center1, degree, 1.0, &map_matrix);
	map[2] += (rewidth - width)/2;    
    map[5] += (reheight - height)/2;
	IplImage* img_rotate = cvCreateImage(cvSize(rewidth, reheight), 8, 3);
	cvWarpAffine(ipimg,img_rotate, &map_matrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(0));
	Mat test = img_rotate;
	*/
	imshow("原图",srcimg);
	//imshow("变换后",dstimg);
	//namedWindow("30°旋转",1);
	imshow("30°旋转",rotimg);
	return 0;
}
int main()
{
	Mat srcimg;
	string filepath;
	filepath = "G:\\opencv\\1.jpg";
	srcimg = imread(filepath,1);
	fsbh(srcimg);
	waitKey(0);
	system("pause");
	return 0;
}
结果:

后语(更新预告)
接下来会更新两个Python的模块,很有用的模块,还会更新学习Opencv(C++),GDAL(C++,Python),ENVI二次开发。










 
