欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV 与 Matlab 中最小二乘法拟合直线数据不一致的问题

程序员文章站 2024-03-20 22:32:28
...

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 与 Matlab 中最小二乘法拟合直线数据不一致的问题
通过以上结果,可以看出,OpenCV 中的直线拟合,使用的最小二乘法的残差是距离的最小值;
注:由于 opencv 中使用了 M 估计进行了权重的调整,所以,如果只想用单纯的最小二乘法时,可根据需要自行编写算法。

相关标签: 参考文档 代码