绘制椭圆函数DrawEllipseDouble()以及Ellipse()

来源:互联网 发布:linux我的世界启动器 编辑:程序博客网 时间:2024/05/19 17:56

一、关于DrawEllipseDouble()
1)函数定义:
Mat DrawEllipseDouble(Mat &img, double center_x, double center_y, double semiLongAxis, double semiShortAxis, double angle);
参数说明:
img————————————Mat图像
center_x—————————–椭圆中心x轴坐标值
center_y—————————–椭圆中心y轴坐标值
semiLongAxis———————–椭圆长半轴
semiShortAxis———————-椭圆短半轴
angle———————————-椭圆旋转角,注:顺时针方向为正
3)函数功能:
可以实现在给定的图像平面上绘制一个具有任意旋转角、图像大小范围内的任意长短轴长的椭圆,并且椭圆中心可以是double类型的数值,这是该函数与opencv函数中ellipse()函数绘制椭圆的最大不同点,也是该函数对于解决椭圆中心检测问题的核心优势。
4)算法文档:
对于椭圆总有一般方程
Ax^2+Bxy+Cy^2+Dx+Ey+F=0 (2.1)
此方程可以变形为
A〖(x-x_0)〗^2+B(x-x_0)(y-y_0)+C〖(y-y_0)〗^2+f=0 (2.2)
令 x^’=x-x_0 y^’=y-y_0
则 A〖x^’〗^2+Bx^’ y^’+C〖y^’〗^2+f=0 (2.3)
椭圆的标准方程
( x^2)/a^2 +y^2/b^2 =1 (2.4)
对于斜椭圆,其旋转角为-θ(为后续讨论方便,取为负值),则
x=x^’ cosθ-y^’ sinθ
y=x^’ sinθ+y^’ cosθ
带入标准方程,即得到旋转后的方程
〖〖 (x〗^’ cosθ-y^’ sinθ)〗^2/a^2 +〖〖(x〗^’ sinθ+y^’ cosθ)〗^2/b^2 =1
经化简得到
(a^2 sin^2 〖θ+b^2 cos^2 θ)∙x^’〗^2+(a^2 cos^2 〖θ+b^2 sin^2 θ)∙y^’〗^2+2(a^2-b^2)sinθcosθ∙x^’ y^’-a^2 b^2=0 (2.5)
所以
A=a^2 sin^2 θ+b^2 cos^2 θ (2.6)
B=2(a^2-b^2)sinθcosθ (2.7) C=a^2 cos^2 θ+b^2 sin^2 θ (2.8) f=-a^2 b^2 (2.9)

5)函数代码:

Mat DrawEllipseDouble(Mat &img, double center_x, double center_y, double semiLongAxis, double semiShortAxis, double angle){    double pivalue = acos(-1);    angle = -angle / 180 * pivalue;    double A = pow(semiLongAxis, 2)*pow(sin(angle), 2) + pow(semiShortAxis, 2)*pow(cos(angle), 2);    double B = 2 * (semiLongAxis*semiLongAxis - semiShortAxis*semiShortAxis)*sin(angle)*cos(angle);    double C = pow(semiLongAxis, 2)*pow(cos(angle), 2) + pow(semiShortAxis, 2)*pow(sin(angle), 2);    double f = -pow(semiLongAxis, 2)*pow(semiShortAxis, 2);    for (int j = 0; j < img.rows; j++)    {        for (int i = 0; i < img.cols; i++)        {            if ((A*pow((i - center_x), 2) + B*(i - center_x)*(j - center_y) + C*pow((j - center_y), 2) + f) <= 0)                img.at<uchar>(j, i) = 1;            else            {                continue;            }        }    }    /*namedWindow("ellipse", CV_WINDOW_AUTOSIZE);    imshow("ellipse", img);    waitKey();*/    return img;}

二、使用opencv中的函数ellipse()进行绘制椭圆
函数代码:

Mat EllipseDetectionCoreAlgorithm::DrawEllipse(Mat img, double EllipseCenter_x, double EllipseCenter_y, double EllipseLong_axis, double EllipseShort_axis, double angle, int ksizeWidth){    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);    //Mat out;    //blur(img, out, Size(ksizeWidth, ksizeWidth));    return img;}

三、二者的区别
DrawEllipseDouble()可以实现在给定的图像平面上绘制一个具有任意旋转角、图像大小范围内的任意长短轴长的椭圆,并且椭圆中心可以是double类型的数值,这是该函数与opencv函数中ellipse()函数绘制椭圆的最大不同点(Ellipse()所绘制的椭圆都是以int类型的中心点进行绘制),也是该函数对于解决椭圆中心检测问题的核心优势。

0 0