OpenCV学习笔记(5)_ ellipse绘制函数浅析

OpenCV学习笔记(5)_ ellipse绘制函数浅析

文章目录

1. ellipse第一种重载——绘制椭圆弧

1.1 函数原型

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,以及绘制相关的颜色、线宽、线型、坐标偏移参数来进行椭圆的绘制。

1.2 参数解析

在OpenCV的文档中,为了说明具体的角方向定义、轴方向定义等,还给出了如下的示意图:

OpenCV学习笔记(5)_ ellipse绘制函数浅析

但笔者认为这个示意图有些不太清楚的地方,于是补充并修正了一些内容,给出如下示意图:

OpenCV学习笔记(5)_ ellipse绘制函数浅析

这两张图是第一种重载方式的参数重点,下面来重点讲述一下:

  • 对于第一种情况,椭圆的axes.width > axes.height;
  • 注意对照示意图,axes.width表示的是椭圆的主轴,即FIRST AXIS,axes.height表示的是椭圆的副轴,即SECOND AXIS,主轴的方向沿图像坐标轴X轴顺时针偏移的方向即为angle;
  • 以主轴axes.width为半径虚拟一个圆,以主轴为基准,顺时针方向偏移start angle角度,得到起始弧段点,由这个点向椭圆主轴做投影,在椭圆弧上的投影点作为椭圆弧段的真正起始点;
  • 椭圆弧段的真正结束点也是采取相同的方式获得;
  • 沿顺时针方向,将椭圆弧段的起始点和结束点之间的椭圆弧段绘制出来,即为图中的深蓝色弧,为该模式下绘制出的椭圆弧段;
  • 注意在这种绘制模式下,axes.width和awes.height均表示的是椭圆的半轴长度,这和下一种模式会有区别;
  • 对于第二种情况,即椭圆的axes.width < axes.height时,仍将axes.width所在的轴作为主轴,和第一种情况类似,也仍是以axes.width作为半径虚拟一个圆,各种偏移角、起始角、结束角均与第一种情况类似。

; 1.3 绘制示例

下面就来实践一把,看一看绘制的实际情况:

#define _CRT_SECURE_NO_WARNINGS

#include
#include

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{

    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;
}

注意其中的参数:

  • 椭圆中心点坐标为(256,256);
  • 椭圆的长轴半径为200,短轴半径为100;
  • 第一种设置下长轴为主轴,第二种设置下短轴为主轴;
  • 当startangle和endangle分别设置为0和360时,可以把整个椭圆完整绘制出来,即为结果图中的绿色椭圆;
  • 红色弧段为绘制出来的椭圆弧段:
    OpenCV学习笔记(5)_ ellipse绘制函数浅析
    OpenCV学习笔记(5)_ ellipse绘制函数浅析

2. ellipse第二种重载——RotatedRect方式绘制椭圆

接下来这种方式,OpenCV给出了一种数据结构 RotatedRect 来存储椭圆的相关信息。

2.1 ellipse函数原型


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也是作为主轴存在的。

2.2 ellipse绘制示例

#define _CRT_SECURE_NO_WARNINGS

#include
#include

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{

    Point ecenter;
    Size ax1, ax2;
    double angle;
    double startangle;
    double endangle;

    ecenter.x = 256;
    ecenter.y = 256;
    angle = 30;
    startangle = 20;
    endangle = 150;

    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;
}

OpenCV学习笔记(5)_ ellipse绘制函数浅析

这里注意,size.width和size.height和第一种重载模式中不同,分别对应椭圆的主轴长和副轴长,而不是半轴长。所以我们从代码中能看到, e1.size.width设置为400, e1.size.height设置为200。如此绘制出来的椭圆才和第一种重载模式中的完整椭圆大小一致。
【创作不易,水平有限,如有错漏,轻喷勿骂】

OpenCV学习笔记(5)_ ellipse绘制函数浅析

Original: https://blog.csdn.net/horsee/article/details/124568157
Author: CarnivoreRabbit
Title: OpenCV学习笔记(5)_ ellipse绘制函数浅析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/637861/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球