OpencV使用fitEllipse擬合橢圓後,獲取橢圓引數
阿新 • • 發佈:2019-02-07
使用OpenCV的fitEllipse函式擬合橢圓後,會得到一個RotatedRect型別的返還值,首先介紹一下RotatedRect結構,這個參考的無左無右的部落格:點選開啟連結,嫌左右跳麻煩,所以直接貼過來
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等時,矩形就成了一個直立的矩形 };
需要注意的是angle對應角度是角度,如果使用三角函式sin,cos,tan之類的需要先轉換成弧度,boundingRect對應水平方向外接矩形而不是橢圓的外接矩形,如果需要獲取橢圓的兩個半軸長度可以通過size.width和size.height得到,其餘的引數看一下上面程式碼對應註釋.
下面就是怎麼通過一個RotatedRect來獲取橢圓引數,具體原理可以參考百度文庫的一個文件:點選開啟連結,直接截圖看一下:
因為這裡預設的是順時針旋轉為正,而影象裡面預設是逆時針旋轉為正,只需要把B乘以一個負號就行,感興趣的同學自己推導一下.
好了,到了上程式碼的時間了,程式碼如下:
#include <opencv2//opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
struct EllipsePara
{
Point2f c;
float A;
float B;
float C;
float F;
};
void getEllipsePara(RotatedRect & ellipsemege, EllipsePara& EP_t) { float theta = ellipsemege.angle * CV_PI / 180.0 ; float a = ellipsemege.size.width / 2.0; float b = ellipsemege.size.height / 2.0; EP_t.c.x = ellipsemege.center.x; EP_t.c.y = ellipsemege.center.y; EP_t.A = a * a * sin(theta) * sin(theta) + b * b * cos(theta) * cos(theta); EP_t.B = (-2.0) * (a * a - b * b) * sin(theta) * cos(theta); EP_t.C = a * a * cos(theta) * cos(theta) + b * b * sin(theta) * sin(theta); EP_t.F = (-1.0) * a * a * b * b; //cout << "theta: " << theta << " x: " << EP.c.x << " y: " << EP.c.y << " C: " << EP.C << " F: " << EP.F << endl; } void main() { //RotatedRect(const Point2f& center, const Size2f& size, float angle); RotatedRect Rec_t = RotatedRect(Point2f(0,0), Size2f(4,1), 90); cout << Rec_t.size.width << " " << Rec_t.size.height << endl; cout << Rec_t.boundingRect().width << " " << Rec_t.boundingRect().height << endl; EllipsePara EP_t; getEllipsePara(Rec_t, EP_t); cout << EP_t.A << " " << EP_t.B << " " << EP_t.C << " " << EP_t.F << endl; }
得到的橢圓方程為:
打完收工!!!