版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yang332233/article/details/70216117
注:一下部分内容来源于网络
RotatedRect该类表示平面上的旋转矩形,有三个属性:
1. 矩形中心点(质心)
2. 边长(长和宽)
3. 旋转角度
class CV_EXPORTS RotatedRect
{ public: //构造函数
RotatedRect();
RotatedRect(const Point2f& center, const Size2f& size, float angle);
RotatedRect(const CvBox2D& box);
void points(Point2f pts[]) const; //!返回矩形的4个顶点
Rect boundingRect() const; //返回包含旋转矩形的最小矩形
operator CvBox2D() const; //!转换到旧式的cvbox2d结构
Point2f center; //矩形的质心
Size2f size; //矩形的边长
float angle; //旋转角度,当角度为0、90、180、270等时,矩形就成了一个直立的矩形
};
现在的问题是要校正下面的矩形:
代码如下:
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void main()
{
Mat img=imread("C:/Users/Administrator/Desktop/testP/rect1.png");
Mat img_gray;
cvtColor(img,img_gray,CV_BGR2GRAY);
Mat thresh_img(img.size(),CV_8UC1);
threshold(img_gray,thresh_img,230,255,THRESH_BINARY_INV);
imshow("thresh",thresh_img);
//waitKey();
vector<vector<Point>> contours;
findContours(thresh_img,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
RotatedRect mr=minAreaRect(Mat(contours[0]));
Mat DrawImg(img.size(),img.type(),Scalar(255,255,255));
Point2f vectpoint[4];
mr.points(vectpoint);
for(int i=0;i<4;i++)
{
line(DrawImg,vectpoint[i],vectpoint[(i+1)%4],Scalar(255,0,0),2);
}
imshow("drawimg",DrawImg);
//waitKey();
float angle=0.0;
Size si=mr.size;
if(mr.size.width<=mr.size.height)
{
angle=mr.angle+90;
swap(si.width,si.height);
}
else
{
angle=mr.angle;
}
Mat rotmat=getRotationMatrix2D(mr.center,angle,1);
Mat deal_img;
warpAffine(img,deal_img,rotmat,img.size(),CV_INTER_CUBIC);
imshow("deal_img",deal_img);
waitKey();
Mat rRect;
getRectSubPix(deal_img,si,mr.center,rRect);
imshow("截取的矩形区域",rRect);
waitKey();
}
这里主要分析一下RotatedRect旋转校正:
图1:左倾斜图
图2:RotatedRect信息
图3:右倾斜图
图4:RotatedRect信息
总结:要注意的4点是:
1、角度angle的取值是由RotatedRect的width和X轴的夹角组成的。
2、RotatedRect的width和height的选取跟矩形的尺寸无关,并非长的就是height,短的就是width。
3、OpenCV默认把 水平轴(x轴)逆时针旋转,碰到的第一个边 这个边的边长作为width。
4、angle的取值范围必然是负的,实际angle的取值范围为(-90,0]。
但是,很奇怪的是如果直接通过构造函数赋值RotatedRect 可以使其角度为正 例如代码如下:
#include"iostream"
#include"opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat image(200, 200, CV_8UC3, Scalar(0));
RotatedRect rRect(Point2f(100, 100), Size2f(100, 50), 30);
Point2f vertices[4]; //定义矩形的4个顶点
rRect.points(vertices); //计算矩形的4个顶点
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0));
Rect brect = rRect.boundingRect(); //返回包含旋转矩形的最小矩形
rectangle(image, brect, Scalar(255, 0, 0));
imshow("rectangles", image);
waitKey(0);
}
当把改成-30°时候:RotatedRect rRect(Point2f(100, 100), Size2f(100, 50), -30);
至于为什么直接通过构造函数赋值 角度可以是正的问题 还不清楚。。。
好久木有写博客了,主要原因在于其实好像荒废了大半年啊,16年年底一直在海南搞那项目,年后又在学校忙毕设,头大。。其实,我感觉最主要的原因在于自己一直木有啥突破,懒散,木有深入研究,罪过。。。。还有这段时间需要找工作,迷茫。。。