opencv ---minAreaRect()计算偏转角度并纠正

  • 此次试验的目的是计算目标图像偏转的角度,在不改变图像尺寸下纠正
  • 这里主要用到minAreaRect()函数和getRotationMatrix2D()函数
  • 先简单的介绍下minAreaRect()函数,本人在这里踩了一些坑,在这里说明一下,如有不妥的地方,大家尽管指正。

函数为minAreaRect(InputArray points) ,InputArray points是所要求最小外接矩形的点集,这个点集不定个数。

这个矩形是可以有偏转角度的,可以与图像的边界不平行。

调用形式:RotatedRect minAreaRect(InputArray points)

  • 角度计算规则:以左上角为原点,X轴逆时针旋转,所得到的第一个角度即为旋转角度,第一条边为最小外接矩形的宽。角度范围[-90,0],当最小外接矩形平行(或垂直)X轴时角度为-90。(跟目标图像的长宽没关系)

顺时针为正,逆时针为负

  • 函数getRotationMatrix2D(Point2f center, double angle, double scale)

参数详解:

Point2f center:表示旋转的中心点

double angle:表示旋转的角度  //这里的角度顺时针为负,逆时针为正

double scale:图像缩放因子

  • 踩坑的地方主要在角度分不清,我总结了一下:

minAreaRect():以X轴正方向为起点,顺时针为正,逆时针为负

getRotationMatrix2D():以X轴正方向为起点,顺时针为负,逆时针为正

  • 下面是一个例子:
  • #include <iostream>
    #include <string>
    #include <math.h>
    #include <vector>
    #include <io.h>
    #include <fstream>
    #include <opencv2/opencv.hpp>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    
    using namespace cv;
    using namespace std;
    
    int main()
    {  
    	Mat image = imread("a11.jpg");  
    	Mat gaussianimage,grayimage, cannyimage, thresholdimage;
    
    //---------------------旋转-----------------
    	//计算偏转角度
    	GaussianBlur(image, gaussianimage, Size(5, 5), 3, 3);//尽可能多的去除杂质
    	Canny(gaussianimage, cannyimage, 50, 150, 3);
    	cvtColor(cannyimage, grayimage, CV_GRAY2BGR);
    	vector<vector<Point>>vec_point;
    	vector<Vec4i>hireachy;
    	findContours(cannyimage, vec_point, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    
    	double degree = 0;
    	for (size_t i = 0; i < vec_point.size(); i++)
    	{
    		RotatedRect minrect = minAreaRect(vec_point[i]);//minAreaRect():以X轴正方形为起点,顺时针为正,逆时针为负
    		degree = minrect.angle;
    		
            //此处目的是为了让目标图像旋转到水平位置
    		if (degree > -90 && degree <= -45)
    		{
    			degree += 90;
    		}
    		else if (degree >-45 && degree < 0)
    		{
    			degree;
    		}
    		else
    		{
    			degree = 0;
    		}		
    		cout <<"degree:" << degree << endl;
    	}	
    
    	//旋转纠正
    	Point center = Point(image.cols / 2, image.rows / 2);
    	double angle = degree;
    	double scale = 1;
    	Mat rot(2, 3, CV_32FC1);
    	rot = getRotationMatrix2D(center, angle, scale);//getRotationMatrix2D():以X轴正方形为起点,顺时针为负,逆时针为正
    	Mat rotimage;
    	warpAffine(image, rotimage, rot, image.size());
    	namedWindow("rotation", 0);
    	resizeWindow("rotation", 800, 600);
    	imshow("rotation", rotimage);
    }
    效果图:

猜你喜欢

转载自blog.csdn.net/m0_45376718/article/details/106615495