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的文档中,为了说明具体的角方向定义、轴方向定义等,还给出了如下的示意图:
在这里插入图片描述

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

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

  • 对于第一种情况,椭圆的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 <opencv2/opencv.hpp>
#include <iostream>

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

注意其中的参数:

  • 椭圆中心点坐标为(256,256);
  • 椭圆的长轴半径为200,短轴半径为100;
  • 第一种设置下长轴为主轴,第二种设置下短轴为主轴;
  • 当startangle和endangle分别设置为0和360时,可以把整个椭圆完整绘制出来,即为结果图中的绿色椭圆;
  • 红色弧段为绘制出来的椭圆弧段:
    在这里插入图片描述
    在这里插入图片描述

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 <opencv2/opencv.hpp>
#include <iostream>

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。如此绘制出来的椭圆才和第一种重载模式中的完整椭圆大小一致。
【创作不易,水平有限,如有错漏,轻喷勿骂】
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值