opencv中,拟合椭圆后,常常需要得到该椭圆方向的系数,而网上大多数方法并未给出全部系数,因此有了这篇博客。
fitEllipse函数拟合椭圆后,返回一个RotatedRect类型的值,RotatedRect参数如下所示,其中,angle、Center、size需要用到求解椭圆方程系数。
class CV_EXPORTS RotatedRect
{ public: //构造函数
RotatedRect();
RotatedRect(const Point2f& center, const Size2f& size, float angle);
RotatedRect(const CvBox2D& box);
void points(Point2f pts[]) const; //!返回矩形的4个顶点
Rect boundingRect() const; //返回包含旋转矩形的最小矩形
operator CvBox2D() const; //!转换到旧式的cvbox2d结构
Point2f center; //矩形的质心
Size2f size; //矩形的边长
float angle; //旋转角度,当角度为0、90、180、270等时,矩形就成了一个直立的矩形
};
下面给出通过一个RotatedRect来获取椭圆参数,不涉及复杂的推导,方便大家直接拿来使用。
椭圆的一般方程为:
void Ellipse_parameters(vector<Point2f> contours)
{
//coutours代表的传入的椭圆轮廓的边缘点
RotatedRect box=fitEllipse(contours);
double cx=box.center.x,cy=box.center.y,a=box.size.width/2,b=box.size.height/2,rot_ang=box.angle*PI/180.0;
double A,B,C,D,E,F;
A=(a*sin(rot_ang))*(a*sin(rot_ang))+(b*cos(rot_ang))*((b*cos(rot_ang)));
B=2*(a*a-b*b)*sin(rot_ang)*cos(rot_ang);
C=(a*cos(rot_ang))*(a*cos(rot_ang))+(b*sin(rot_ang))*(b*sin(rot_ang));
D=-(2*A*cx+B*cy);
E=-(2*C*cy+B*cx);
F=A*cx*cx+B*cx*cy+C*cy*cy-(a*b)*(a*b);
//输出椭圆方程系数
cout<<A<<" "<<B<<" "<<C<<" "<<D<<" "<<E<<" "<<F<<endl;
}
如有问题,敬请指出。