大家在網上搜索“fit_line_contour_xld”應該很容易就能發現這樣的幾行字:(沒耐心看的話,可以直接看文末三行研究結論)
regression:回歸,標准的最小二乘法擬合
huber:加權的最小二乘法擬合,異常值的影響被減小基於Huber方法
tukey:加權的最小二乘法擬合,異常值的影響被減小基於Tukey方法(系統推薦方法)
gauss:加權的最小二乘法擬合,異常值的影響被減小基於最逼近線上的所有其輪廓點的平均值和距離標准方差
drop:加權的最小二乘法擬合,異常值的影響被消除
fit_line_contour_xld算子的簽名如下:
fit_line_contour_xld(Contours : : Algorithm, MaxNumPoints, ClippingEndPoints, Iterations, ClippingFactor : RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
其中Algorithm參數可選擇上面的5種算法之一。
如果有讀者朋友圖像處理理論基礎深厚,自然知道每種算法擬合的准確度優劣和適應情況。但是就算不知道,也可以通過一定的方法研究得出結論。
我的研究方法如下:
① 找幾十張有邊可抓的圖像。(待抓的邊最好不要太直)
② 抓取圖像的某一條邊緣,抓邊時會生成很多邊緣交點,並生成最終擬合的直線。
③ 輸出所有邊緣交點到直線的距離,對這些距離進行從大到小排序。
④ 取第8號點(也可以取其他點,我這里擬合直線一共用了60個點)的值輸出,命名為Offset,該值表示擬合的直線跟實際邊緣點的近似最大偏差值。
分別采用 'regression'、'huber'、'tukey'、'gauss'、'drop'五種參數(Algortim算法)執行上述過程,並將每一張圖的5個Offset值都輸出到.csv文件中。
求出采用不同算法的每組數據的標准差,標准差越小,說明直線擬合准確度越高。(可以多測一些圖片,多抓一些不同的邊)
部分代碼如下:
1 get_image_size (ImageR, Width, Height) 2 gen_rectangle1 (Rect, 600, 0, Height - 600, 800) 3
4 count_seconds (Seconds) 5 find_line (ImageR, Rect, Line, Region1, Cross, 60, 8, 1, 12, 'positive', 'first', 'no', 5, Algortim) 6 count_seconds (Seconds1) 7
8 Time := (Seconds1 - Seconds) * 1000
9
10 area_center_xld(Cross, Area2, Row4, Column4, PointOrder) 11 get_contour_xld(Line, row, col) 12 distance_pl(Row4, Column4, row[0], col[0], row[1], col[1], Distance) 13
14 tuple_sort(Distance, Sorted) 15 tuple_inverse(Sorted, Inverted) //反轉以后是從大到小排序
16
17 Offset := Inverted[8] //取第8號值是為了忽略偶然的極端值
注:擬合直線算子fit_line_contour_xld在第五行自己封裝的find_line函數內部。
【研究結論】:
1、'regression'、'gauss'擬合效果很差,基本不用考慮。其他三種算法效果基本差不多。(五種算法的執行時間無明顯差異)
2、少部分時候'tukey'擬合偏差有點大。雖然系統推薦的是'tukey'算法,,但經過我大量研究測試,效果最好的應該是'drop'。
3、如果非要對擬合准確度進行排序的話,那么我的結論是:'drop' > 'tukey' >≈ 'huber' > 'gauss' >> 'regression'。(>≈意思是左邊的要好一些,但好得非常有限)