基于代數距離的橢圓擬合

問題

給定離散點集Xi=(xi,yi),i=1,2,...NX_i=(x_i,y_i) ,i=1,2,...NXi?=(xi?,yi?),i=1,2,...N,我們希望找到誤差最小的橢圓去擬合這些離散點。

方法

由于橢圓的形式可以給定, 自然我們將使用最小二乘法來求解橢圓。主要依據論文《Direct least squares fitting of ellipsees, Fitzgibbon, Pilu and Fischer in Fitzgibbon, A.W., Pilu, M., and Fischer R.B.,Proc. of the 13th Internation Conference on Pattern Recognition, pp 253–257, Vienna, 1996》。

橢圓擬合的難點

通常我們使用最小二乘法求解如下的最優化問題:

Min∑i=1Nf(xi,E)Min \sum_{i=1}^N f(x_i,E)Mini=1N?f(xi?,E)
這里f(xi,E)f(x_i,E)f(xi?,E)表示點xix_ixi?到E(指待擬合的橢圓)的最小距離。一般稱為幾何距離。但是我們很難直接給定幾何距離的解析表達,因此很難求出。因此我們退而求其次,我們采用:為橢圓寫下隱式方程,然后將點的坐標帶入此隱式方程就得到了點到橢圓的距離。這種方法對于直線擬合、圓擬合,返回的就是到其的真實距離。而對于橢圓擬合,它返回的值是與距離有類似的屬性,但不是一個真正的距離值。因此這個距離被稱為代數距離
橢圓可以用下面的隱式方程表達:

a1x2+a2xy+a3y2+a4x+a5y+a6=0a_1x^2+a_2xy+a_3y^2+a_4x+a_5y+a_6=0a1?x2+a2?xy+a3?y2+a4?x+a5?y+a6?=0

與直線類似(直線表達為:a1x+a2y+a3=0a_1x+a_2y+a_3=0a1?x+a2?y+a3?=0),上式的一組參數也是齊次量,即只能定義到一個比例因子。而且表達式也能表達雙曲線和拋物線。而橢圓
通常要求:a22?4a1a4&lt;0a_2^2-4a_1a_4&lt;0a22??4a1?a4?<0。最好通過令a22?4a1a4=?1a_2^2-4a_1a_4=-1a22??4a1?a4?=?1,即可同時解決這兩個問題。

請參考維基百科橢圓定義和wolfram MathWorld 橢圓定義

一般的求解過程

對上面的橢圓方程改寫為:

f(a,(x,y))=D?a=0f(a,(x,y))=D\cdot a=0f(a,(x,y))=D?a=0

這里D=(x2,xy,y2,x,y,1)D=(x^2, xy, y^2, x, y, 1)D=(x2,xy,y2,x,y,1),a=(a1,a2,a3,a4,a5,a6)a=(a_1, a_2, a_3, a_4, a_5, a_6)a=(a1?,a2?,a3?,a4?,a5?,a6?).
于是給定N個離散點Xi=(xi,yi),i=1...NX_i=(x_i,y_i),i=1...NXi?=(xi?,yi?),i=1...N,通過最小化代數距離:

MinΔ(a,X)=∑i=1N(f(a,Xi))2Min \Delta(a,X)=\sum_{i=1}^{N}(f(a,X_i))^2MinΔ(a,X)=i=1N?(f(a,Xi?))2

重寫上式,即有:

MinΔ(a,X)=∑i=1NaTDiTDia=aTSaMin \Delta(a,X)=\sum_{i=1}^{N}a^TD_i^TD_ia=a^TSaMinΔ(a,X)=i=1N?aTDiT?Di?a=aTSa

這里S=∑DiTDiS=\sum D_i^T D_iS=DiT?Di?為6x6矩陣。
另外,我們可以把各個DiD_iDi?合并起來,則有
D^=(D1D2?DN)\hat{D}=\begin{pmatrix} D_1\\ D_2\\ \vdots \\ D_N \end{pmatrix}D^=??????D1?D2??DN????????
因此:
S=D^TD^S=\hat{D}^T\hat{D}S=D^TD^

此外,我們還有約束條件:
a22?4a1a4&lt;0a_2^2-4a_1a_4&lt;0a22??4a1?a4?<0,可以改寫為:

aTCa=?1a^TCa=-1aTCa=?1

其中C∈R6×6C\in R^{6\times 6}CR6×6,且大部分為0,只有C1,3=C3,1=?2,C2,2=1C_{1,3}=C_{3,1}=-2,C_{2,2}=1C1,3?=C3,1?=?2,C2,2?=1
因此綜合上來即為,求解如下的最優化問題:

MinaTSaMin~~~ a^TSa Min???aTSa
s.t.aTCa=?1s.t. ~~~a^TCa=-1s.t.???aTCa=?1

公式和拉格朗日乘子法

通過使用拉格朗日乘子法 ,我們可以得到

L(a)=aTSa?λ(aTCa+1)L(a)=a^TSa-\lambda (a^TCa+1)L(a)=aTSa?λ(aTCa+1)

然后求解?aL(a)=0\partial_aL(a)=0?a?L(a)=0可以求解得到:
Sa=λCaSa=\lambda CaSa=λCa

上式是經典的廣義特征值問題。我們可以直接求解,其中λ\lambdaλ為廣義特征值,而a為廣義特征向量
論文 中指出有且僅有一個負的特征值,且其對應的特征向量即為我們需要的橢圓方程的系數,即這里的a.

一般的圓錐方程到標準橢圓方程的轉化。

當我們求解得到了圓錐曲線的系數,即a,我們一般需要獲得橢圓的標準方程,也就是獲得橢圓的如下參數:
中心(cx,cy)(c_x,c_y)(cx?,cy?)、長短半軸r1,r2r_1,r_2r1?,r2?,旋轉角度θ\thetaθ.

這里我們可以給出結果,也可以自己結合橢圓的標準形式與圓錐曲線的方程去推導.

參考文獻:http://mathworld.wolfram.com/Ellipse.html.
##編程實現
下面描述matlab與c++實現。

matlab

% fitellip gives the 6 parameter vector of the algebraic circle fit
% to a(1)x^2 + a(2)xy + a(3)y^2 + a(4)x + a(5)y + a(6) = 0
% X & Y are lists of point coordinates and must be column vectors.(或者行向量)
function a = fitellip(X,Y)% normalize datamx = mean(X);my = mean(Y);sx = (max(X)-min(X))/2;sy = (max(Y)-min(Y))/2;x = (X-mx)/sx;y = (Y-my)/sy;% Force to column vectorsx = x(:);y = y(:);% Build design matrixD = [ x.*x  x.*y  y.*y  x  y  ones(size(x)) ];% Build scatter matrixS = D'*D;% Build 6x6 constraint matrixC(6,6) = 0; C(1,3) = -2; C(2,2) = 1; C(3,1) = -2;% Solve eigensystem[gevec, geval] = eig(S,C);% Find the negative eigenvalue[NegR, NegC] = find(geval < 0 & ~isinf(geval));% Extract eigenvector corresponding to positive eigenvalueA = gevec(:,NegC);% unnormalizea = [A(1)*sy*sy,   ...A(2)*sx*sy,   ...A(3)*sx*sx,   ...-2*A(1)*sy*sy*mx - A(2)*sx*sy*my + A(4)*sx*sy*sy,   ...-A(2)*sx*sy*mx - 2*A(3)*sx*sx*my + A(5)*sx*sx*sy,   ...A(1)*sy*sy*mx*mx + A(2)*sx*sy*mx*my + A(3)*sx*sx*my*my   ...- A(4)*sx*sy*sy*mx - A(5)*sx*sx*sy*my   ...+ A(6)*sx*sx*sy*sy   ...]';

c++

我們參考了網上的版本,并修復了他的問題,最終也做出了和matlab一樣的效果。其中最關鍵的是廣義特征值的求解。我們使用了Eigenclapack庫。其中Eigen易于表達矩陣,和matlab用法類似,是個強大的C++線性代數庫。而CLAPACK是線性代數包Lapack面向C/c++的接口。里面包含了很豐富的線性代數算法,包括廣義特征值求解接口,而且速度很快。我們希望將二者結合起來使用。

Eigen的安裝

Eigen直接以源代碼的方式提供給用戶,因此我們從官網上下載下后,直接在工程中包含其頭文件路徑即可。具體可參考:http://blog.csdn.net/abcjennifer/article/details/7781936

clapack的安裝

請查看官網,里面包含了詳細的使用與安裝步驟。

也可以使用我們已經編譯了的vc2010和vc2013的庫,可以點擊下載。

盡管clapack面向c語言,因此需要我們在包含頭文件的時候,記得加上extern “C”.但是最新的版本(比如CLAPACK 3.2.1)已經為我們在頭文件中加上了這些限制符,因此最新的版本可以兼容c和c++,所以直接在項目包含頭文件即可。

比如像下面一樣:

//Eigen
#include <Eigen/Dense>
#include <Eigen/Core>
#include <iostream>//clapack,必須放在Eigen后面#include <f2c.h>
#include <clapack.h>

而且應該注意Eigen與CLAPACK混合使用的時候,CLAPACK的頭文件要加在Eigen的后面。否則會出錯

代碼

請查看Github主頁:https://github.com/xiamenwcy/EllipseFitting

實驗結果

在這里插入圖片描述

參考文獻

Eigen、LAPACK

  1. Interfacing Eigen with LAPACK
  2. Using BLAS/LAPACK from Eigen
  3. CLAPACK for Windows
  4. 如何在VC中調用CLAPACK
  5. 使用Lapack庫的一些重要規則
  6. 在VS中用CLAPACK解決廣義特征值問題
  7. LAPACK 3.7.0
  8. C++編程:C++中同時使用Eigen和CLAPACK
  9. CLAPACK在vc++6.0中成功調用
  10. CLAPACK動態調用
  11. Leading dimension
  12. leading dimension 2

橢圓擬合

  • Fitting an Ellipse to a Set of Data Points(python實現)
  • 二次曲線Quadratic Curve
  • fitellipse.cpp(opencv)
  • Creating Bounding rotated boxes and ellipses for contours
  • OpenCV’s fitEllipse() sometimes returns completely wrong ellipses
  • Fitting an Ellipse to a Set of Data Points
  • Direct Least Square Fitting of Ellipses (論文)
  • best-fitting-line-circle-and-ellipse
  • opencv中的橢圓擬合
  • Python and C implementations of an ellipse fitting algorithm in double and fixed point precision.
  • C++ code for circle fitting algorithms
  • OriginDelight/EllipseFit (c++源碼)

論文作者,著名學者主頁:

  • Bob Fisher: http://homepages.inf.ed.ac.uk/rbf/
  • Fitzgibbon, Pilu, Fisher: Direct Least Squares Fitting of Ellipses:http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/FITZGIBBON/ELLIPSE/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/258791.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/258791.shtml
英文地址,請注明出處:http://en.pswp.cn/news/258791.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java與C語言比較(Java參考書中摘錄)

C語言為面向過程的編程語言&#xff0c;Java為面向對象的編程語言。 在面向過程的編程語言(如C語言)中&#xff0c;編程一般面向操作&#xff0c;編程單位是函數(在Java中函數稱為方法)。 在Java中&#xff0c;編程單位是類。最終實例化(即創建)這些類而得到對象&#xff0c;屬…

Android調試技巧之Eclipse行號和Logcat

很多初入Android的開發者可能會發現經常遇到Force Close或ANR這樣的問題&#xff0c;一般我們通過Android系統的錯誤日志打印工具Logcat可以看到出錯的內容&#xff0c;今天一起來說下如何通過 Eclipse行號和Logcat捕捉出錯點&#xff0c;我們遇到錯誤可以首先在Eclipse的DDMS中…

第六章 產權市場

《市場經濟概論》&#xff08;6&#xff09;產權市場一 第六章 產權市場 產權是指人們對于某種資產所擁有的所有權、占有權、支配權、使用權。產權市場是指人們對于某種資產所擁有的所有權、占有權、支配權、使用權進行有償轉讓的場所領域及其有關各方面相互關系的總和。在過去…

js打開本地文件夾_vue + ArcGIS 地圖應用系列一:arcgis api本地部署(開發環境)

1. 下載 ArcGIS API for JavaScript 官網地址&#xff1a; https://developers.arcgis.com/javascript/3/ 下載地址&#xff1a;http://links.esri.com/javascript-api/latest-download需要穩定的網絡環境注冊賬號后才可以下載下載完成后解壓文件&#xff0c;文件比較大可能需要…

基于幾何距離的橢圓擬合

問題 給定離散點集Xi(xi,yi)X_i(x_i,y_i)Xi?(xi?,yi?)&#xff0c;我們希望找到最好的橢圓去擬合這些離散點。 方法 通常我們使用最小二乘法求解如下的最優化問題&#xff1a; Min∑i1Nf(xi,E)2Min \sum_{i1}^N f(x_i,E)^2 Mini1∑N?f(xi?,E)2 這里f(xi,E)f(x_i,E)f(xi…

Generate Parentheses

題目 Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. For example, given n 3, a solution set is: "((()))", "(()())", "(())()", "()(())", "()()()" 方法…

ReportViewer 2010 打印預覽,用鼠標快速切換顯示比例時報錯:存儲空間不足,不能處理此命令...

CreateCompatibleDIB 存儲空間不足 無法處理此命令 安裝 ReportViewer 2010 sp1 即可。轉載于:https://www.cnblogs.com/runliuv/p/3640856.html

貪心/二分查找 BestCoder Round #43 1002 pog loves szh II

題目傳送門 1 /*2 貪心/二分查找&#xff1a;首先對ai%p&#xff0c;然后sort&#xff0c;這樣的話就有序能使用二分查找。貪心的思想是每次找到一個aj使得和為p-1(如果有的話)3 當然有可能兩個數和超過p&#xff0c;那么an的值最優&#xff0c;每次還要和…

nohup命令輸出日志_逼格高又實用的Linux高級命令,開發運維都要懂

在運維的坑里摸爬滾打好幾年了&#xff0c;我還記得我剛開始的時候&#xff0c;我只會使用一些簡單的命令&#xff0c;寫腳本的時候&#xff0c;也是要多簡單有多簡單&#xff0c;所以有時候寫出來的腳本又長又臭&#xff0c;像一些高級點的命令&#xff0c;比如說Xargs 命令、…

JavaScript中OOP——面向對象中的繼承/閉包

前 言 OOP JavaScript中OOP——>>>面向對象中的繼承/閉包 1.1面向對象的概念 使用一個子類繼承另一個父類&#xff0c;子類可以自動擁有父類的屬性和方法。>>> 繼承的兩方&#xff0c;發生在兩個類之間。1.2JS模擬實現繼承的三種方式&#xff1a; 首先&am…

js常用字符串函數

這些東西是以前整理的&#xff0c;放到這里&#xff0c;有需要的可以看看~挺全的~ /** * anchor()方法 * 在對象中的指定文本兩端放置一個有Name屬性的HTML錨點 * strVariable.anchor(anchorString) anchorString為錨點名稱 * 它本身不會檢查其他的ahchor錨點是否有name指…

c++11中的智能指針

在C11中有四種智能指針&#xff0c;auto_ptr&#xff0c;shared-ptr&#xff0c;unique_ptr和weak-ptr&#xff0c;其中auto_ptr有許多不足之處&#xff0c;在C11中已經建議廢棄使用。 1. shared_ptr std::shared_ptr智能指針可以通過共享指向對象的所有權&#xff0c;從而實現…

ubuntu14.04設置靜態IP

啊&#xff0c;最近懶惰了&#xff0c;好久沒有寫博客了。 一般機器啟動的時候會自動從DHCP服務器上面獲取動態IP地址&#xff0c;這是一件很方便的事情&#xff0c;可以不用手動設置網絡相關的蠶參數&#xff0c;但是有時候還是需要機器固定IP地址的。 第一步&#xff0c;編輯…

高中學歷python培訓靠譜嗎_高中學歷學完Python就能干人工智能?

最近Python大熱&#xff0c;主要是人工智能的熱度&#xff0c;昨天后院活動部介紹了一位女網友為男朋友選擇Java還是Python&#xff0c;大量的程序員熱議&#xff0c;也有人詢問如何學習Python&#xff0c;比如這位網友詢問高中學歷學習Python是不是就能干人工智能。兄弟&#…

curl+個人證書(又叫客戶端證書)訪問https站點

目前&#xff0c;大公司的OA管理系統&#xff08;俗稱內網&#xff09;&#xff0c;安全性要求較高&#xff0c;通常采用https的雙向 認證模式。 首先&#xff0c;什么是https&#xff0c;簡單的說就是在SSL協議之上實現的http協議&#xff08;get、post等操作&#xff09;。更…

boot.oat FC問題分析報告

【NE現場】 pid: 5252, tid: 5252, name: ndroid.contacts >>> com.android.contacts <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1458x0 0000000000000000 x1 0000000090d9892c x2 0000000000000001 x3 000000000000012cx4 …

c++ 虛函數的實現機制

轉載自&#xff1a;http://blog.csdn.net/jiangnanyouzi/article/details/3720807 1、c實現多態的方法 其實很多人都知道&#xff0c;虛函數在c中的實現機制就是用虛表和虛指針&#xff0c;但是具體是怎樣的呢&#xff1f;從more effecive c其中一篇文章里面可以知道&#xff…

powerdesigner 技巧

1.修改建表腳本生成規則。如果每個表格都有相同的字段&#xff0c;可以如下修改&#xff1a; Database -> Edit Current DBMS 展開 Script -> Object -> Table -> Create 見右下的Value值&#xff0c;可以直接修改如下&#xff1a;/* tablename: %TNAME% */ create…

勒索病毒攻擊應急防范

北京時間5月12日&#xff0c;互聯網上出現針對Windows操作系統的勒索軟件&#xff08;Wannacry&#xff09;攻擊案例。勒索軟件利用此前披露的Windows SMB服務漏洞&#xff08;對應微軟漏洞公告&#xff1a;MS17-010&#xff09;攻擊手段&#xff0c;向終端用戶進行滲透傳播&am…

C++中虛析構函數的作用

C中的虛析構函數到底什么時候有用的&#xff0c;什么作用呢。 總的來說虛析構函數是為了避免內存泄露&#xff0c;而且是當子類中會有指針成員變量時才會使用得到的。也就說虛析構函數使得在刪除指向子類對象的基類指針時可以調用子類的析構函數達到釋放子類中堆內存的目的&…