【OpenCV】OpenCV通过仿射变换实现图像旋转(自适应图像尺寸大小)

先看结果

【OpenCV】OpenCV通过仿射变换实现图像旋转(自适应图像尺寸大小)_第1张图片       【OpenCV】OpenCV通过仿射变换实现图像旋转(自适应图像尺寸大小)_第2张图片

 

【OpenCV】OpenCV通过仿射变换实现图像旋转(自适应图像尺寸大小)_第3张图片

仿射变换原理

一般通过一个2*3的矩阵对图像中每个位置(x,y)进行矩阵运算来得到一个新的位置(x',y'),具体公式如下:

                                           【OpenCV】OpenCV通过仿射变换实现图像旋转(自适应图像尺寸大小)_第4张图片

每个对应点有两个对应的方程,因此只要找到三个位置对应的点就可以知道变换矩阵,在OpenCV中通过getAffineTransform函数可得。也可以直接给出中心点与角度,得到一个旋转变换矩阵,对应OpenCV中getRotationMatrix2D接口可得。一般进行旋转变换后有一个偏移,需要通过计算点的位置变换得到一个平移矩阵来对图像进行校正,在旋转矩阵的最后一列增加平移最后进行仿射变换。

需要了解旋转变换后窗口的尺寸变换:

                                        【OpenCV】OpenCV通过仿射变换实现图像旋转(自适应图像尺寸大小)_第5张图片

代码

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include 


using namespace std;
using namespace cv;

int main()
{
	Mat src = imread("image0.jpg", IMREAD_COLOR);
	cvtColor(src, src, COLOR_BGR2GRAY);
											
	if (src.empty() /*|| src == NULL*/)
	{
		cout << "读入的图像为空error" << endl;
		return -1;
	}
	imshow("原图灰度化", src);
//按角度旋转矩阵
	Mat res4(src.size(), src.depth(), Scalar(0));
	Point2f center;
	center.x = float(src.cols / 2.0 - 0.5);
	center.y = float(src.rows / 2.0 - 0.5);

	//计算二维旋转的仿射变换矩阵(也可以通过三点法计算仿射变换矩阵)
	//Mat getRotationMatrix2D( Point2f center, double angle, double scale );
	double degree = 45.;//角度为+表示逆时针
	//CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst,
                    //InputArray M, Size dsize,
					//int flags = INTER_LINEAR,
					//int borderMode = BORDER_CONSTANT,const Scalar& borderValue = Scalar());

	Mat M = getRotationMatrix2D(center, degree, 1);
	cout << M.size() << endl;
	//变换图像,并用黑色填充其余值  
	warpAffine(src, res4, M, src.size());
	imshow("直接旋转图像", res4);
														
	
	Point2f center2;
	center2.x = float(src.cols / 2.0 - 0.5);
	center2.y = float(src.rows / 2.0 - 0.5);
	double degree2 = 45.;

	double angle = degree2  * CV_PI / 180.; // 弧度    
	double a = sin(angle), b = cos(angle);
	int width = src.cols;
	int height = src.rows;
	int width_rotate = int(height * fabs(a) + width * fabs(b));
	int height_rotate = int(width * fabs(a) + height * fabs(b));

	Mat M1 = getRotationMatrix2D(center2, degree, 1.0);

	Point2f srcPoints1[3];
	Point2f dstPoints1[3];

	srcPoints1[0] = Point2i(0, 0);
	srcPoints1[1] = Point2i(0, src.rows);
	srcPoints1[2] = Point2i(src.cols, 0);

	dstPoints1[0] = Point2i((width_rotate - width)/2 , (height_rotate - height)/2);
	dstPoints1[1] = Point2i((width_rotate - width)/2 , src.rows + (height_rotate - height)/2);
	dstPoints1[2] = Point2i(src.cols + (width_rotate - width)/2, (height_rotate - height)/2);

	Mat M2 = getAffineTransform(srcPoints1, dstPoints1);
	
	M1.at(0, 2) = M1.at(0, 2) + M2.at(0, 2);
	M1.at(1, 2) = M1.at(1, 2) + M2.at(1, 2);

	//Mat src2(Size(width_rotate, height_rotate), CV_8UC1, Scalar(0));
	Mat res5(width_rotate, height_rotate, CV_8UC1, Scalar(0));
	
	//warpAffine(src, src2, M2, src.size());
	//imshow("平移", src2);
	warpAffine(src, res5, M1, Size(width_rotate, height_rotate));
	

	imshow("自适应旋转图像", res5);
	waitKey(0);
	return 0;
}

 

你可能感兴趣的:(OpenCV,OpenCV,仿射变换)