OpenCV之RotatedRect基本用法和角度探究

文章目录
一、属性
1.成员变量
-
float angle
-
Point2f center
-
Size2f size
2.构造函数
-
默认构造:
RotatedRect ()
default constructor More… -
角度构造:
RotatedRect (const Point2f ¢er, const Size2f &size, float angle)
center:矩形的中心点
angle:顺时针的角度,0-360°size
可以是负的:x正沿x正方向(向右),y正沿y正方向(向下) -
三个点构造:
RotatedRect (const Point2f &point1, const Point2f &point2, const Point2f &point3)
矩形的任意三个点。注意必须遵从逆时针或顺时针的顺序
3.成员函数
-
Rect boundingRect () const
returns the minimal up-right integer rectangle containing the rotated rectangle -
Rect_< float > boundingRect2f () const
returns the minimal (exact) floating point rectangle containing the rotated rectangle, not intended for use with images -
void points (Point2f pts[]) const
returns 4 vertices of the rectangle。返回矩形四个顶点的Point2f类位置信息给pts数组
4.例子
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat test_image(200, 200, CV_8UC3, Scalar(0));
RotatedRect rRect = RotatedRect(Point2f(100, 100), Size2f(100, 50), 30);
/*获得角度*/
cout << rRect.angle << endl;
//角度30度
/*获得中心点*/
cout << rRect.center << endl;
//中心点[100, 100]
/*获得宽×高*/
cout << rRect.size << endl;
//宽×高[100 x 50]
/*获得宽*/
cout << rRect.size.width << endl;
// 100
/*获得高*/
cout << rRect.size.height << endl;
// 50
/*获得面积*/
cout << rRect.size.area() << endl;
//5000
//绘制旋转矩形
Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(test_image, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0), 2);
//圈中这个旋转矩形的外矩形
Rect brect = rRect.boundingRect();
rectangle(test_image, brect, Scalar(255, 0, 0), 2);
imshow("rectangles", test_image);
waitKey(0);
return 0;
}
二、类成员变量探究
1.用角度构造和用三个点构造
(1)用角度构造
- angle范围任意值(就是指定的angle)
- width和height就是指定的值(不会随角度变化)
- 机制:初始图像(宽就是给的width值,高就是给的height值,以向上为轴,现在为0°),然后以角度angle旋转图形(正顺时针,负逆时针),现在表示的是33°
(2)用三个点构造
- angle范围[-45°,45°]
- width就是角度接触的那一边,height就是另一边(会变化)
- 判定机制:找到最下面的顶点,设定水平轴,左边(正)和右边(负)分别得到一个角度,以绝对值小的那个角度为angle,接触的边为width。比如下图,就是左边的角为angle,正值,其边为width。
(3)验证
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat src(400,400,CV_8UC1,Scalar::all(0));
for(float angle=0;angle<=720;angle++)
{
RotatedRect angle_rotatedRect(Point2f(200,200),Size2f(50,100),angle);
Point2f vertices[4];
angle_rotatedRect.points(vertices);
for (int i = 0; i < 4; i++)
{
line(src, vertices[i], vertices[(i+1)%4], Scalar::all(255), 2);
}
RotatedRect points_RotatedRect(vertices[3],vertices[2],vertices[1]);
// 角度,用角度构造的旋转矩形的角度,用点构造的旋转矩形的角度
cout<<"angle:"<<angle<<" , "<<"angle_rotatedRect's angle:"<<angle_rotatedRect.angle
<<" , "<<"points_RotatedRect's angle:"<<points_RotatedRect.angle<<endl;
// 用角度构造的旋转矩形的宽,用点构造的旋转矩形的宽
cout<<"angle_rotatedRect's width:"<<angle_rotatedRect.size.width<<" , "
<<"points_RotatedRect's width:"<<points_RotatedRect.size.width<<endl;
// 用角度构造的旋转矩形的高,用点构造的旋转矩形的高
cout<<"angle_rotatedRect's height:"<<angle_rotatedRect.size.height<<" , "
<<"points_RotatedRect's height:"<<points_RotatedRect.size.height<<endl;
cout<<endl;
imshow("src",src);
if(waitKey()=='q') return 0;
src=Scalar::all(0);
}
return 0;
}
2.minAreaRect()圈出的旋转矩形
- angle范围:[-90°,0°]
- width就是角度挨着的那一边,height就是另一边(会变化)
- 判定机制:还是最低顶点建轴,只不过这会只选择右边(负)为angle,其边为width。当为0°时,以左下角为顶点。当为-90°时,以右下角为顶点
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define W_CONVEX "RESULT"
int main()
{
Mat image=Mat::zeros(600,600,CV_8UC3);
RNG& rng=theRNG();
while(1)
{
char key;
int count=(unsigned)rng%100+3;
vector<Point> points;
for(int i=0;i<count;i++)
{
Point point;
point.x=rng.uniform(image.cols/4,image.cols*3/4);
point.y=rng.uniform(image.rows/4,image.rows*3/4);
circle(image,point,2,Scalar::all(255),2);
points.push_back(point);
}
RotatedRect rotatedRect=minAreaRect(points);
Point2f hull[4];
rotatedRect.points(hull);
for(int i=0;i<4;i++)
{
line(image,hull[i],hull[(i+1)%4],Scalar::all(255),2);
}
cout<<"RotatedRect's angle:"<<rotatedRect.angle<<endl;
cout<<"RotatedRect's width:"<<rotatedRect.size.width<<endl;
cout<<"RotatedRect's height:"<<rotatedRect.size.height<<endl;
cout<<endl;
namedWindow(W_CONVEX,WINDOW_NORMAL);
imshow(W_CONVEX,image);
image=Scalar::all(0);
if(waitKey()=='q') return 0;
}
return 0;
}
/*获得-90°的情况*/
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define W_CONVEX "RESULT"
int main()
{
Mat image=Mat::zeros(600,600,CV_8UC3);
vector<Point> points{Point(100,100),Point(200,100),Point(100,300),Point(200,300)};
RotatedRect rotatedRect=minAreaRect(points);
Point2f hull[4];
rotatedRect.points(hull);
for(int i=0;i<4;i++)
{
line(image,hull[i],hull[(i+1)%4],Scalar::all(255),2);
}
cout<<"RotatedRect's angle:"<<rotatedRect.angle<<endl;
cout<<"RotatedRect's width:"<<rotatedRect.size.width<<endl;
cout<<"RotatedRect's height:"<<rotatedRect.size.height<<endl;
cout<<endl;
namedWindow(W_CONVEX,WINDOW_NORMAL);
imshow(W_CONVEX,image);
waitKey();
return 0;
}
3.minAreaRect()后改变类属性
比如改变angle,那么width和height是否会变化。是采用角度规则还是三个点的规则还是minAreaRect()规则。
结论:采用角度规则
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat image = Mat::zeros(600, 600, CV_8UC3);
vector<Point> points{Point(100, 100), Point(300, 100), Point(100, 200), Point(300, 200)};
// 圈出来旋转矩形
RotatedRect rotatedRect = minAreaRect(points);
cout << "RotatedRect's angle:" << rotatedRect.angle << endl;
cout << "RotatedRect's width:" << rotatedRect.size.width << endl;
cout << "RotatedRect's height:" << rotatedRect.size.height << endl;
cout << endl;
Point2f hull1[4];
rotatedRect.points(hull1);
for (int i = 0; i < 4; i++)
{
line(image, hull1[i], hull1[(i + 1) % 4], Scalar::all(255), 2);
}
for (;;)
{
rotatedRect.angle += 10;
cout << "RotatedRect's angle:" << rotatedRect.angle << endl;
cout << "RotatedRect's width:" << rotatedRect.size.width << endl;
cout << "RotatedRect's height:" << rotatedRect.size.height << endl;
cout << endl;
Point2f hull2[4];
rotatedRect.points(hull2);
for (int i = 0; i < 4; i++)
{
line(image, hull2[i], hull2[(i + 1) % 4], Scalar::all(120), 2);
}
imshow("image", image);
if (waitKey() == 'q')
return 0;
image = Scalar::all(0);
}
return 0;
}
旋转过程:
初始宽为100,高为200,angle是70°,旋转70°




更多推荐









所有评论(0)