android椭圆框 安卓椭圆接口_android任意函数绘制


原文首发于微信公众号:【3D视觉工坊】。

前言

圆特征在测量领域中应用广泛,比如:相机标定、位姿估计、目标跟踪等方面。圆经过透视投影,当成像平面与圆平面不平行时,圆经过透视投影为椭圆,圆心的透视投影点与椭圆的中心点不重合,这个偏差叫做椭圆构像偏差。鉴于此,研究如何绘制一个高精度的椭圆,对于整个测量系统的精度具有重要意义。

一 OpenCV中绘制椭圆的函数

根据OpenCV提供的ellipse()函数,我将其封装成如下的绘制椭圆函数:


//使用opencv中的ellipse函数在平面绘制椭圆,此处的参数为长短轴的半轴长。
Mat DrawPreciseEllipse::DrawEllipse(Mat img, double EllipseCenter_x, double EllipseCenter_y, double EllipseLong_axis, double EllipseShort_axis, double angle)
{
 int thickness = -2;
 int lineType = 8;
    ellipse(img,
        Point(EllipseCenter_x, EllipseCenter_y),
        Size(EllipseLong_axis, EllipseShort_axis),   //ellipse()函数中参数轴长应该是长短轴的一半,此处将对应的参数除以二,则我们输入即可认为是长短轴轴长。
        angle,
 0,
 360,
        Scalar(1),
        thickness,
        lineType);
 return img;
}


利用此函数,我们在平面绘制长半轴长为100pix,短半轴为80pix、偏转角为0度的椭圆,如图1.1所示。利用ImageWatch插件可以观察椭圆边缘轮廓,如图1.2所示。


android椭圆框 安卓椭圆接口_android任意函数绘制_02

图1.1 OpenCV中ellipse函数绘制的椭圆


android椭圆框 安卓椭圆接口_android任意函数绘制_03

图1.2 OpenCV中ellipse函数绘制的椭圆边缘轮廓

由上图可见,使用OpenCV自带的椭圆绘制函数绘制的椭圆边缘轮廓为锯齿形,这对于椭圆中心的检测精度很不利,经过测试,这样的椭圆图案中心检测精度较差。

面积法绘制椭圆

如何实现在给定的图像平面中绘制一个具有任意旋转角、任意长短轴的椭圆,且椭圆中心为任意值,且椭圆边缘较为柔和,这是一个亟待解决的问题。不失一般性,我们以在600pix×600pix图像尺寸中绘制椭圆中心坐标为(300.67,300.35),长短半轴长分别为80,60为例。(单位均为像素)。

2.1 初步绘制二值化椭圆

对于椭圆总有一般方程


android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_04

2.1

此方程可以变形为


android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_05

2.2

令:


android椭圆框 安卓椭圆接口_android椭圆框_06

2.2.1

则有:


android椭圆框 安卓椭圆接口_android椭圆框_07

2.3

椭圆的标准方程


android椭圆框 安卓椭圆接口_android任意函数绘制_08

2.4

对于斜椭圆,其旋转角为-θ(为后续讨论方便,取为负值),则:


android椭圆框 安卓椭圆接口_android椭圆框_09

2.5

2.5


android椭圆框 安卓椭圆接口_android任意函数绘制_10

2.6

带入标准方程,即得到旋转后的方程


android椭圆框 安卓椭圆接口_android任意函数绘制_11

2.7

经化简得到


android椭圆框 安卓椭圆接口_android椭圆框_12

2.8

所以


android椭圆框 安卓椭圆接口_android任意函数绘制_13

2.9

android椭圆框 安卓椭圆接口_android椭圆框_14

2.10

android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_15

2.11

android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_16

2.12

其算法流程图可归纳总结如图 2.1 所示。经过流程图中的步骤,初步绘制好的椭圆二值化图像边缘轮廓部分截图,如图 2.2 所示。


android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_17

图2.1 绘制椭圆二值化图像

android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_18

图2.2 二值化椭圆轮廓边缘示意图

2.2 面积法的含义

接下来,为了使得椭圆边缘轮廓不显得那么锐利,使用面积法使用面积法将其边缘像素重新赋值,使椭圆轮廓边缘更加平滑。面积法指的是将椭圆边界的像素大小划分为 n×n个点,根据公式(2.13)将椭圆边缘重新赋值。公式中的 Ia为椭圆外部的各像素值,Ib椭圆内部的各像素值,I为重新赋值的像素值大小。(对于此处的n取值大小,如有感兴趣者,欢迎在【视觉IMAX】知识星球进行讨论交流)。


android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_19

2.13

使用面积法的算法流程可大致归纳如图 2.3 所示。


android椭圆框 安卓椭圆接口_android任意函数绘制_20

图2.3 面积法对椭圆边缘像素重新赋值

2.3 使用面积法精确绘制椭圆

在 2.2 中我们是默认已经找出了椭圆的边缘轮廓,但在实际操作中,如何找出椭圆的边缘轮廓仍然是我们需要解决的问题。此处我们使用八邻域查找算法,选择的滤波器核大小为 3,如图 2.4 所示。


android椭圆框 安卓椭圆接口_android任意函数绘制_21

图2.4 滤波器核

利用此核与整个二值化椭圆图像做卷积运算,2.1 小节得到的二值化椭圆经过卷积运算后,如果是椭圆外部的点,像素值皆为 0,此时我们将其重新赋值为 50,如果是椭圆内部的点,像素值皆为 8,此时我们将其重新赋值为 200。像素值介于 1~7 的部分,我们便可以认为这是椭圆的边缘轮廓,如图 2.5 所示。图 2.5 中的左图为整幅椭圆图像经过八邻域查找法卷积运算后得到的椭圆,图2.5 中的右图为椭圆部分边缘轮廓放大后的效果图。


android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_22

图 2.5 八邻域查找法寻找椭圆边缘轮廓

android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_23

图 2.6 绘制理想椭圆的流程图


对于椭圆的边缘轮廓,我们便可以使用面积法,对椭圆边缘轮廓重新赋值。这样,使用面积法绘制理想椭圆的算法流程可归纳总结如图 2.6 所示。 经过使用面积法对椭圆边缘轮廓重新赋值之后,绘制好的理想椭圆,如图2.7 所示。图中左边部分为整个椭圆,右边部分为椭圆的轮廓部分截图。


android椭圆框 安卓椭圆接口_已知长短轴求椭圆上任意一点的坐标_24

图 2.7 面积法绘制的理想椭圆效果图

显然,使用面积法绘制的椭圆边缘更加柔和,椭圆中心检测精度更高。

总结

文章主要分析了两种绘制椭圆的方法,对比得出面积法绘制椭圆的精度更高。

犹记得研究椭圆检测的那段时光,每天上下班路上,经常会莫名地观察路边的灯光、早晨的太阳、傍晚的夕阳,脑海中在始终会萦绕着一个问题:它们什么时候的所形成的椭圆图像中心检测精度更高呢?