OpenCV的ellipse函数有两种重载方式,下面首先来试一下第一种重载方式:
OpenCV文档中对于第一种重载方式的调用如下原型:
void cv::ellipse( InputOutputArray img,
Point center,
Size axes,
double angle,
double startAngle,
double endAngle,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
int shift = 0
)
从这个函数原型中我们可以看出,第一种重载方式,可以由椭圆的中心点坐标center,椭圆的长短轴axes,起始的角度angle,弧段的起讫角度startangle和endangle,以及绘制相关的颜色、线宽、线型、坐标偏移参数来进行椭圆的绘制。
在OpenCV的文档中,为了说明具体的角方向定义、轴方向定义等,还给出了如下的示意图:
但笔者认为这个示意图有些不太清楚的地方,于是补充并修正了一些内容,给出如下示意图:
这两张图是第一种重载方式的参数重点,下面来重点讲述一下:
下面就来实践一把,看一看绘制的实际情况:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
// ellipse 第一种重载的绘制
Point ecenter;
Size ax1, ax2;
double angle;
double startangle;
double endangle;
Mat pic1 = Mat::zeros(Size(512, 512), CV_8UC3);
Mat pic2 = Mat::zeros(Size(512, 512), CV_8UC3);
ecenter.x = 256;
ecenter.y = 256;
ax1.width = 200;
ax1.height = 100;
angle = 30;
startangle = 20;
endangle = 150;
ellipse(pic1, ecenter, ax1, angle, 0, 360, Scalar(0, 255, 0), 1, LINE_AA, 0);
ellipse(pic1, ecenter, ax1, angle, startangle, endangle, Scalar(0, 0, 255), 2, LINE_AA, 0);
putText(pic1, "AXES.WIDTH > AXES.HEIGHT", Point(25, 25), FONT_HERSHEY_PLAIN, 1, Scalar(0, 255, 0));
imshow("ellipseExample1", pic1);
ax2.width = 100;
ax2.height = 200;
ellipse(pic2, ecenter, ax2, angle, 0, 360, Scalar(0, 255, 0), 1, LINE_AA, 0);
ellipse(pic2, ecenter, ax2, angle, startangle, endangle, Scalar(0, 0, 255), 2, LINE_AA, 0);
putText(pic2, "AXES.WIDTH < AXES.HEIGHT", Point(25, 25), FONT_HERSHEY_PLAIN, 1, Scalar(0, 255, 0));
imshow("ellipseExample2", pic2);
waitKey(0);
return EXIT_SUCCESS;
}
注意其中的参数:
接下来这种方式,OpenCV给出了一种数据结构 RotatedRect 来存储椭圆的相关信息。
void cv::ellipse( InputOutputArray img,
const RotatedRect & box,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8
)
相较于第一种重载方式,这种方式将椭圆的形状参数全部归并到一个RotatedRect对象即box中。
RotatedRect共有三个属性:
分别是angle center size
这个数据结构的理解很容易:center表示矩形的中心点;angle表示矩形顺时针偏转的角度;size中分别表示矩形的width和height。
注意RotatedRect中,size.width也是作为主轴存在的。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
// ellipse 第一种重载的绘制
Point ecenter;
Size ax1, ax2;
double angle;
double startangle;
double endangle;
ecenter.x = 256;
ecenter.y = 256;
angle = 30;
startangle = 20;
endangle = 150;
// ellipse 第二种重载的绘制
RotatedRect e1;
Mat pic3 = Mat::zeros(Size(512, 512), CV_8UC3);
e1.center = ecenter;
e1.size.width = 400;
e1.size.height = 200;
e1.angle = angle;
ellipse(pic3, e1, Scalar(255, 0, 0), 1, LINE_AA);
imshow("ellipseExample3", pic3);
waitKey(0);
return EXIT_SUCCESS;
}
这里注意,size.width和size.height和第一种重载模式中不同,分别对应椭圆的主轴长和副轴长,而不是半轴长。所以我们从代码中能看到, e1.size.width
设置为400, e1.size.height
设置为200。如此绘制出来的椭圆才和第一种重载模式中的完整椭圆大小一致。
【创作不易,水平有限,如有错漏,轻喷勿骂】