OpenCV 最小二乘擬合方法求取直線傾角
阿新 • • 發佈:2019-02-18
工業相機拍攝的影象中,由於攝像質量的限制,影象中的直線經過處理後,會表現出比較嚴重的鋸齒。在這種情況下求取直線的傾角(其實就是直線的斜率),如果是直接選取直線的開始點和結束點來計算,或是用opencv自帶的哈夫曼直線方法,都會引起較大的角度偏差,一般會達到好幾度。誤差這麼大,顯然達不到工控要求。後來嘗試採取直線點集做最小二乘擬合,誤差縮小到0.5以下。以下是演算法的程式碼:
//最小二乘擬合計算直線的傾角 int pointCount = pointVect.size(); if (pointCount > 0) { int xCount = 0; int yCount = 0; int xyCount = 0; int xxCount = 0; for (int i = 0; i< pointCount; i++) { xCount += pointVect.at(i).x; yCount += pointVect.at(i).y; xyCount += (pointVect.at(i).x * pointVect.at(i).y); xxCount += (pointVect.at(i).x * pointVect.at(i).x); } double k = (double)(pointCount * xyCount - xCount * yCount) / (double)(pointCount * xxCount - xCount * xCount); double sinValue = - k / (sqrt(1 + k * k)); double radian = asin(sinValue); double pi = 3.1415926535; double angle = radian * 180.0 / pi; }
下面是最小二乘的理論基礎:
曲線擬合中最基本和最常用的是直線擬合。設x和y之間的函式關係為:
y=a+bx
式中有兩個待定引數,a代表截距,b代表斜率。對於等精度測量所得到的N組資料(xi,yi),i=1,2……,N,xi值被認為是準確的,所有的誤差只聯絡著yi。下面利用最小二乘法把觀測資料擬合為直線。
用最小二乘法估計引數時,要求觀測值yi的偏差的加權平方和為最小。對於等精度觀測值的直線擬合來說,可使下式的值最小:
整理後得到方程組
解上述方程組便可求得直線引數a和b的最佳估計值。
相關係數r:
最小二乘法處理資料除給出a、b外,常常還給出相關係數r, r定義為
計算:
代入上面推匯出來的計算公式可得:
a=13.6284394650024 b=-0.0799231779033084