直线拟合的三种方法

您所在的位置:网站首页 求直线斜率有几种方法图解大全 直线拟合的三种方法

直线拟合的三种方法

2024-07-14 14:03| 来源: 网络整理| 查看: 265

近日考虑直线拟合相关的知识,大概有所了解,所以打算进行一些总结。

直线拟合常用的三种方法:

一、最小二乘法进行直线拟合

二、梯度下降法进行直线拟合

三、高斯牛顿,列-马算法进行直线拟合

 

一、使用最多的就是最小二乘法,这里我也对最小二乘法进行了一个总结。

1. 假设x是正确值,y存在误差。

根据上面两图的手推公式我们可以编写相关的代码了。此处我们借助opencv工具进行结果显示和分析。

void fitline3(){ float b = 0.0f, k=0.0f; vectorpoints; points.push_back(Point(27, 39)); points.push_back(Point(8, 5)); points.push_back(Point(8, 9)); points.push_back(Point(16, 22)); points.push_back(Point(44, 71)); points.push_back(Point(35, 44)); points.push_back(Point(43, 57)); points.push_back(Point(19, 24)); points.push_back(Point(27, 39)); points.push_back(Point(37, 52)); Mat src = Mat::zeros(400, 400, CV_8UC3); for (int i = 0; i < points.size(); i++) { //在原图上画出点 circle(src, points[i], 3, Scalar(0, 255, 0), 1, 8); } int n = points.size(); double xx_sum = 0; double x_sum = 0; double y_sum = 0; double xy_sum = 0; for (int i = 0; i < n; i++) { x_sum += points[i].x; //x的累加和 y_sum += points[i].y; //y的累加和 xx_sum += points[i].x * points[i].x; //x的平方累加和 xy_sum += points[i].x * points[i].y; //x,y的累加和 } k = (n*xy_sum - x_sum * y_sum) / (n*xx_sum - x_sum * x_sum); //根据公式求解k b = (-x_sum * xy_sum + xx_sum*y_sum) / (n*xx_sum - x_sum * x_sum);//根据公式求解b printf("k = %f, b = %f\n", k, b); //k = 1.555569, b = -4.867031 cv::Point first = { 5, int(k * 5 + b) }, second = { int((400 - b) / k), 400 }; cv::line(src, first, second, cv::Scalar(0, 0, 255), 2); cv::imshow("name", src); cv::waitKey(0); }

上面求解出来的结果是k = 1.555569, b = -4.867031。

图像显示结果:

 

 

下面我们使用opencv自带的函数求解k和b值。此处代码来自互联网。

void fitline1() { vectorpoints; //(27 39) (8 5) (8 9) (16 22) (44 71) (35 44) (43 57) (19 24) (27 39) (37 52) points.push_back(Point(27, 39)); points.push_back(Point(8, 5)); points.push_back(Point(8, 9)); points.push_back(Point(16, 22)); points.push_back(Point(44, 71)); points.push_back(Point(35, 44)); points.push_back(Point(43, 57)); points.push_back(Point(19, 24)); points.push_back(Point(27, 39)); points.push_back(Point(37, 52)); Mat src = Mat::zeros(400, 400, CV_8UC3); for (int i = 0; i < points.size(); i++) { //在原图上画出点 circle(src, points[i], 3, Scalar(0, 0, 255), 1, 8); } //构建A矩阵 int N = 2; Mat A = Mat::zeros(N, N, CV_64FC1); for (int row = 0; row < A.rows; row++) { for (int col = 0; col < A.cols; col++) { for (int k = 0; k < points.size(); k++) { A.at(row, col) = A.at(row, col) + pow(points[k].x, row + col); } } } //构建B矩阵 Mat B = Mat::zeros(N, 1, CV_64FC1); for (int row = 0; row < B.rows; row++) { for (int k = 0; k < points.size(); k++) { B.at(row, 0) = B.at(row, 0) + pow(points[k].x, row)*points[k].y; } } //A*X=B Mat X; //cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3