OpenCV 與 Matlab 中最小二乘法擬合直線數據不一致的問題

OpenCV 與 Matlab 中最小二乘法擬合直線數據不一致的問題

在使用最小二乘法擬合直線時,在 OpenCV 中擬合出的結果與 Matlab 中不一致。查閱資料後,發現 Matlab 中,使用最小二乘擬合時,使用的殘差函數爲y 的差值,即擬合值與實際值之間的差值,並不符合要使用點到直接的距離誤差最小的思想;OpenCV 中的殘差計算,則是使用了點到直線的距離誤差最小,但opencv 中,使用了 M 估計對各個點的權重進行調整,因此,在使用過程中,需要注意;
以下爲最小二乘法擬合直線的 Python 代碼:

import numpy as np
import cv2 as cv
from scipy.optimize import leastsq


def func(p, x):
    k, b = p
    return k * x + b


def error(p, x, y):
    return func(p, x) - y


def dist_error(p, x, y):
    k, b = p
    dist = np.abs(k * x + b - y) / np.sqrt(k**2 + 1)
    return dist


def main():
    pts = np.array([(1, 3), (2, 5), (3, 8)], dtype=np.float64)
    x = pts[:, 0]
    y = pts[:, 1]
    para = leastsq(error, [1, 0], args=(x, y))
    para1 = leastsq(dist_error, [1, 0], args=(x, y))
    vx, vy, x0, y0 = cv.fitLine(pts, cv.DIST_L2, 0, 0.01, 0.01)
    k = vy / vx
    b = y0 - k * x0
    print("y 絕對值最小:", para[0])
    print("距離最小:", para1[0])
    print("opencv 擬合結果:", k, b)


if __name__ == '__main__':
    main()


在這裏插入圖片描述
通過以上結果,可以看出,OpenCV 中的直線擬合,使用的最小二乘法的殘差是距離的最小值;
注:由於 opencv 中使用了 M 估計進行了權重的調整,所以,如果只想用單純的最小二乘法時,可根據需要自行編寫算法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章