拟合算法之一 直线拟合

article/2025/11/8 5:00:01

直线拟合

很早就想学习拟合了,经常听同事用到拟合,当时尚且一窍不通,必须快递加急紧追此处才是,也参考了网上大佬的一些宝贵经验,先将拟合方法总结如下:

最小二乘法

1.原理
在这里插入图片描述
2.举例实现

void fitline3(){float b = 0.0f, k=0.0f;vector<Point>points;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); //根据公式求解kb = (-x_sum * xy_sum + xx_sum*y_sum) / (n*xx_sum - x_sum * x_sum);//根据公式求解bprintf("k = %f, b = %f\n", k, b); //k = 1.555569, b = -4.867031cv::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。
图像显示结果为:
在这里插入图片描述
3.使用opencv自带的函数求解k和b值

void fitline1()
{vector<Point>points;//(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++){cicle(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<double>(row, col) = A.at<double>(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<double>(row, 0) = B.at<double>(row, 0) + pow(points[k].x, row)*points[k].y;}}//A*X=BMat X;//cout << A << endl << B << endl;solve(A, B, X, DECOMP_LU);cout << X << endl;vector<Point>lines;for (int x = 0; x < src.size().width; x++){				// y = b + ax;double y = X.at<double>(0, 0) + X.at<double>(1, 0)*x; //b = -4.867031, k = 1.555569,printf("b = %f, k = %f, (%d,%lf)\n", X.at<double>(0, 0), X.at<double>(1, 0), x, y);lines.push_back(Point(x, y));}polylines(src, lines, false, Scalar(255, 0, 0), 1, 8);imshow("src", src);//imshow("src", A);waitKey(0);
}

梯度下降法

1.原理
在这里插入图片描述
2.举例实现

//梯度下降法进行线性拟合
// y = theta0 * x + theta1
void fitline4(){const int m = 10;double Train_set_x[m] = { 27, 8, 8, 16, 44, 35, 43, 19, 27, 37 };double Train_set_y[m] = { 39, 5, 9, 22, 71, 44, 57, 24, 39, 52 };//alpha是学习率,error是结束误差,theta0就是k,theta1就是b。double theta0 = 0.0, theta1 = 0.0, alpha = 0.002, error = 1e-8; double tmp_theta0 = theta0, tmp_theta1 = theta1;double sum_theta0 = 0.0, sum_theta1 = 0.0;while (1){sum_theta0 = 0.0, sum_theta1 = 0.0;for (size_t i = 0; i < m; i++) {sum_theta0 += (theta0 * Train_set_x[i] + theta1 - Train_set_y[i])*Train_set_x[i]; sum_theta1 += (theta0 * Train_set_x[i] + theta1 - Train_set_y[i]);  //累加和}theta0 = theta0 - alpha * (1.0 / m) * sum_theta0; //k更新公式theta1 = theta1 - alpha * (1.0 / m) * sum_theta1; //b更新公式printf("k=%lf, b=%lf\n", theta0, theta1);if (abs(theta0 - tmp_theta0) < error && abs(theta1 - tmp_theta1) < error){ //break;}tmp_theta0 = theta0;tmp_theta1 = theta1;}
}

结果:
在这里插入图片描述
参考:
1.https://blog.csdn.net/stf1065716904/article/details/107594710
2.https://blog.csdn.net/LaplaceSmoothing/article/details/94581854?utm_medium=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.no_search_link


http://chatgpt.dhexx.cn/article/bgZAtYqD.shtml

相关文章

直线拟合问题(Python实现)

程序如下&#xff1a; import matplotlib.pyplot as plt import numpy as npx_list [466, 741, 950, 1422, 1634] y_list [7.04, 4.28, 3.40, 2.54, 2.13] # x_list [0, 1, 3, 5] # y_list [1, 2, 4, 8]l_mat11 len(x_list) l_mat12 l_mat21 sum(x for x in x_list) l_…

OpenCV直线拟合检测

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达本文转自&#xff1a;opencv学堂 OpenCV直线拟合检测 霍夫直线检测容易受到线段形状与噪声的干扰而失真&#xff0c;这个时候我们需要另辟蹊径&#xff0c;通过对图像进行…

RANSAC 直线拟合

result&#xff1a; code&#xff1a; #include "stdafx.h". #include <opencv2\opencv.hpp> #include <iostream> #include <ctime>using namespace std; using namespace cv;//生成[0,1]之间符合均匀分布的数 double uniformRandom(void) {ret…

OpenCV——直线拟合

相比于直线检测&#xff0c;直线拟合的最大特点是将所有数据只拟合出一条直线 void fitLine( InputArray points, OutputArray line, int distType,double param, double reps, double aeps ); points&#xff1a;输入待拟合直线的2D或者3D点集。line&#xff1a;输出描述直线…

直线拟合

在进行直线拟合算法中&#xff0c;一直使用最小二乘法&#xff0c;使用时间长了&#xff0c;也比较熟练了&#xff0c;但是在最近一次使用中&#xff0c;最小二乘法在拟合垂直或者接近垂直的直线时&#xff0c;效果不好&#xff1b;斜率很大&#xff0c;使用稳定性不好。查阅《…

Android 冷启动 热启动 测试

一、应用的启动 启动方式 通常来说&#xff0c;在安卓中应用的启动方式分为两种&#xff1a;冷启动和热启动。 1、冷启动&#xff1a;当启动应用时&#xff0c;后台没有该应用的进程&#xff0c;这时系统会重新创建一个新的进程分配给该应用&#xff0c;这个启动方式就是冷启动…

Spring Boot 热启动

目的&#xff1a;修改类文件可以马上编译发布&#xff0c;提高了工作效率 步骤&#xff1a; 第一步&#xff1a; 修改pom.xml <!-- 热启动 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools&l…

APP冷热启动专项测试

一、冷热启动的概念 冷启动&#xff1a;当启动应用时&#xff0c;后台没有该应用的进程&#xff0c;这时系统会重新创建一个新的进程分配给该应用&#xff0c;这个启动方式就是冷启动。 热启动&#xff1a;当启动应用时&#xff0c;后台已有该应用的进程&#xff08;例&#…

嵌入式linux热启动和冷启动,使用keil判断ARM的冷启动和热启动的方法

微处理器:LPC2114 编译环境:Keil MDK V4.10 思路: 常把单片机系统的复位分为冷启动和热启动。所谓冷启动&#xff0c;也就是一般所说的上电复位&#xff0c;冷启动后片内外RAM的内容是随机的&#xff0c;通常是0x00或0xFF&#xff1b;单片机的热启动是通过外部电路给运行中的单…

Android冷启动和热启动以及冷启动优化方案

1、什么是冷启动和热启动 冷启动&#xff1a; 当启动应用时&#xff0c;后台没有该应用的进程&#xff0c;这时系统会重新创建一个新的进程分配给该应用&#xff0c;这个启动方式就是冷启动&#xff0c;也就是先实例化Application。热启动&#xff1a; 当启动应用时&#xff0…

冷启动和热启动的区别android,app冷启动和热启动的区别(详解两者定义及区别)...

介绍一下 app 冷启动和热启动方式来实现 app 秒开的效果。那么,先来看看什么叫冷启动和热启动。 冷启动:指 app 被后台杀死后,在这个状态打开 app,这种启动方式叫做冷启动。 热启动:指 app 没有被后台杀死,仍然在后台运行,通常我们再次去打开这个 app,这种启动方式叫热…

热启动和冷启动以及复位启动的小知识

热启动和冷启动的区别&#xff1a; 1、重启是热启动。开机是冷启动。 2、热启动是通过开始菜单、任务管理器或者快捷键&#xff0c;重新启动计算机&#xff0c;叫热启动。冷启动是在关机状态下按POWER启动计算机&#xff0c;叫做冷启动 。 3、热启动是在计算机已经开启的状态…

dimen属性报错

<TextViewandroid:id"id/tvQuote1"android:layout_width"fill_parent"android:layout_height"wrap_content"android:textColor"#FFFFFF"android:textSize"dimen/text_size" /> 发现问题是dimen属性出现错误 别的手机上…

解决android:padding=“@dimen/activity_vertical_margin“> 标红问题

解决android:padding“dimen/activity_vertical_margin”> 标红问题 如果有这个问题&#xff0c;可以在values中新建一个dimen.xml文件 在dimen.xml里增加如下代码&#xff1a; <?xml version"1.0" encoding"utf-8"?><resources><…

android:paddingTop=“@dimen/activity_horizontal_margin“报错(报红)解决方法

android:paddingTop"dimen/activity_horizontal_margin"报错&#xff08;报红&#xff09;解决方法 在app----->res----->values------>dimens.xml中添加如下代码&#xff1a; <dimen name“activity_horizontal_margin” / (后面还有一个尖括号)&#…

android 手机适配之values适配dimen值

android 适配屏幕的方式有很多,最方便最直接的无非就是适配values里的dimens文件值来进行适配. 张鸿洋大神已经写过一篇适配的文章,很详细 但是我在阅读的时候还是有点疑问,这个values-1920x1080到底是dp值还是手机分辨率,因为我在实际操作中发现这样一句话. 很明显可以看…

Android开发——AS插件批量解决XML中的String/Color/Dimen硬编码

1. 问题抛出 1.1 开发方面 对于日常开发中&#xff0c;每写一个"#333"&#xff0c;都要手动的在当前xml与colors.xml中来回切换&#xff0c;查看是否已经定义过&#xff0c;如果定义过则拿过来复用&#xff0c;如果没有就要新定义一个叫"#333"的资源名&a…

dimen.xml浅析

转自&#xff1a;http://blog.csdn.net/kazeik/article/details/8268721 有时候我们为了维护一个工程&#xff0c;或者想定义一个button样式&#xff0c;或textView样式&#xff0c;这些样式中包含着文字的大小&#xff0c;背景图片&#xff0c;前置图片等一些资源。而且这个…

android:屏幕自适应之dimen使用

From&#xff1a;4种必须知道的Android屏幕自适应解决方案&#xff08;求投票支持&#xff09; demo下载&#xff1a;http://www.eoeandroid.com/forum.php?modattachment&aidNjE0Njh8ZTIyZDA2M2N8MTMzODgyOTQxN3w1NzAwOTV8MTczOTcz 以下是Demo首页的预览图 一、细说 layo…

android屏幕适配,生成不同分辨率的dimen.xml文件

1.在项目下新建moudle&#xff0c;选择Java Library&#xff0c;如图&#xff1a; 2.编写工具类&#xff1a; public class DimenUtils {//文件保存的路径 是在该项目下根路径下创建 比如该项目创建的路径是C:\MyProject\&#xff0c;// 则保存的文件路径是C:\MyProject\Di…