通过离散点拟合曲线

文章目录

    • 使用离散点拟合曲线
      • 参考代码路径:
      • 作者源码:
      • 测试代码
      • 效果图:
        • k=3
        • k=4
        • k=5

使用离散点拟合曲线

参考代码路径:

https://www.bragitoff.com/2015/09/c-program-for-polynomial-fit-least-squares/

https://gist.github.com/Thileban/272a67f2affdc14a5f69ad3220e5c24b

https://blog.csdn.net/jpc20144055069/article/details/103232641

作者源码:

//Polynomial Fit
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
int main()
{int i,j,k,n,N;cout.precision(4);                        //set precisioncout.setf(ios::fixed);cout<<"\nEnter the no. of data pairs to be entered:\n";        //To find the size of arrays that will store x,y, and z valuescin>>N;double x[N],y[N];cout<<"\nEnter the x-axis values:\n";                //Input x-valuesfor (i=0;i<N;i++)cin>>x[i];cout<<"\nEnter the y-axis values:\n";                //Input y-valuesfor (i=0;i<N;i++)cin>>y[i];cout<<"\nWhat degree of Polynomial do you want to use for the fit?\n";cin>>n;                                // n is the degree of Polynomial double X[2*n+1];                        //Array that will store the values of sigma(xi),sigma(xi^2),sigma(xi^3)....sigma(xi^2n)for (i=0;i<2*n+1;i++){X[i]=0;for (j=0;j<N;j++)X[i]=X[i]+pow(x[j],i);        //consecutive positions of the array will store N,sigma(xi),sigma(xi^2),sigma(xi^3)....sigma(xi^2n)}double B[n+1][n+2],a[n+1];            //B is the Normal matrix(augmented) that will store the equations, 'a' is for value of the final coefficientsfor (i=0;i<=n;i++)for (j=0;j<=n;j++)B[i][j]=X[i+j];            //Build the Normal matrix by storing the corresponding coefficients at the right positions except the last column of the matrixdouble Y[n+1];                    //Array to store the values of sigma(yi),sigma(xi*yi),sigma(xi^2*yi)...sigma(xi^n*yi)for (i=0;i<n+1;i++){    Y[i]=0;for (j=0;j<N;j++)Y[i]=Y[i]+pow(x[j],i)*y[j];        //consecutive positions will store sigma(yi),sigma(xi*yi),sigma(xi^2*yi)...sigma(xi^n*yi)}for (i=0;i<=n;i++)B[i][n+1]=Y[i];                //load the values of Y as the last column of B(Normal Matrix but augmented)n=n+1;                //n is made n+1 because the Gaussian Elimination part below was for n equations, but here n is the degree of polynomial and for n degree we get n+1 equationscout<<"\nThe Normal(Augmented Matrix) is as follows:\n";    for (i=0;i<n;i++)            //print the Normal-augmented matrix{for (j=0;j<=n;j++)cout<<B[i][j]<<setw(16);cout<<"\n";}    for (i=0;i<n;i++)                    //From now Gaussian Elimination starts(can be ignored) to solve the set of linear equations (Pivotisation)for (k=i+1;k<n;k++)if (B[i][i]<B[k][i])for (j=0;j<=n;j++){double temp=B[i][j];B[i][j]=B[k][j];B[k][j]=temp;}for (i=0;i<n-1;i++)            //loop to perform the gauss eliminationfor (k=i+1;k<n;k++){double t=B[k][i]/B[i][i];for (j=0;j<=n;j++)B[k][j]=B[k][j]-t*B[i][j];    //make the elements below the pivot elements equal to zero or elimnate the variables}for (i=n-1;i>=0;i--)                //back-substitution{                        //x is an array whose values correspond to the values of x,y,z..a[i]=B[i][n];                //make the variable to be calculated equal to the rhs of the last equationfor (j=0;j<n;j++)if (j!=i)            //then subtract all the lhs values except the coefficient of the variable whose value                                   is being calculateda[i]=a[i]-B[i][j]*a[j];a[i]=a[i]/B[i][i];            //now finally divide the rhs by the coefficient of the variable to be calculated}cout<<"\nThe values of the coefficients are as follows:\n";for (i=0;i<n;i++)cout<<"x^"<<i<<"="<<a[i]<<endl;            // Print the values of x^0,x^1,x^2,x^3,....    cout<<"\nHence the fitted Polynomial is given by:\ny=";for (i=0;i<n;i++)cout<<" + ("<<a[i]<<")"<<"x^"<<i;cout<<"\n";return 0;
}//output attached as .jpg

测试代码

#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <numeric>//第一种方式
QList<double> discrete_point_fitting_curve(std::vector<cv::Point2d> inPoints, int degreeOfPolynomial) {int numPoints = inPoints.size();std::vector<double> posXs;std::vector<double> posYs;for (int i = 0; i < numPoints; i++){cv::Point2d tmpPoint = inPoints.at(i);posXs.push_back(tmpPoint.x);posYs.push_back(tmpPoint.y);}int k = degreeOfPolynomial; //多项式的次数//存储 sigma(xi),sigma(xi^2),sigma(xi^3)....sigma(xi^2n)std::vector<double> xValue(2 * k + 1);for (int i = 0; i < 2 * k + 1; i++){xValue[i] = 0;for (int j = 0; j < numPoints; j++) {xValue[i] = xValue[i] + pow(posXs[j], i);}}//Normal matrix(augmented)std::vector<std::vector<double>> matrixNormal(k + 1, std::vector<double>(k + 2, 0));//保存参数方程的系数std::vector<double> finalParas(k + 1);for (int i = 0; i <= k; i++) {for (int j = 0; j <= k; j++) {matrixNormal[i][j] = xValue[i + j];}}//存储sigma(yi),sigma(xi*yi),sigma(xi^2*yi)…sigma(xi^n*yi)std::vector<double> yValue(k + 1);for (int i = 0; i < k + 1; i++){yValue[i] = 0;for (int j = 0; j < numPoints; j++) {yValue[i] = yValue[i] + pow(posXs[j], i)*posYs[j];}}//加载yValue作为matrixNormal的最后一列(普通矩阵但增强)for (int i = 0; i <= k; i++) {matrixNormal[i][k + 1] = yValue[i];}//k变为n+1,因为下面的高斯消去部分是针对k个方程,但这里k是多项式的次数,对于k次我们得到k+1个方程k = k + 1;//高斯消元法求解线性方程组for (int i = 0; i < k; i++) {for (int n = i + 1; n < k; n++) {if (matrixNormal[i][i] < matrixNormal[n][i]) {for (int j = 0; j <= k; j++){double temp = matrixNormal[i][j];matrixNormal[i][j] = matrixNormal[n][j];matrixNormal[n][j] = temp;}}}}//循环执行高斯消除for (int i = 0; i < k - 1; i++){for (int n = i + 1; n < k; n++){double t = matrixNormal[n][i] / matrixNormal[i][i];for (int j = 0; j <= k; j++) {//使主元元素下面的元素等于0或消除变量matrixNormal[n][j] = matrixNormal[n][j] - t * matrixNormal[i][j];}}}//回代//使要计算的变量等于最后一个方程的rhs,然后减去除正在计算的变量的系数之外的所有lhs值,现在最后将 rhs 除以要计算的变量的系数for (int i = k - 1; i >= 0; i--){finalParas[i] = matrixNormal[i][k];for (int j = 0; j < k; j++) {if (j != i) {finalParas[i] = finalParas[i] - matrixNormal[i][j] * finalParas[j];}}finalParas[i] = finalParas[i] / matrixNormal[i][i];}QList<double> resParas;for (int i = 0; i < finalParas.size(); i++){qDebug() << "1--final:" << i << finalParas[i];resParas.push_back(finalParas[i]);}return resParas;
}//第二种方式--best
QList<double> polyfit(std::vector<cv::Point2d> &chain, int n)
{cv::Mat y(chain.size(), 1, CV_32F, cv::Scalar::all(0));/* ********【预声明phy超定矩阵】************************//* 多项式拟合的函数为多项幂函数* f(x)=a0+a1*x+a2*x^2+a3*x^3+......+an*x^n*a0、a1、a2......an是幂系数,也是拟合所求的未知量。设有m个抽样点,则:* 超定矩阵phy=1 x1 x1^2 ... ...  x1^n*           1 x2 x2^2 ... ...  x2^n*           1 x3 x3^2 ... ...  x3^n*              ... ... ... ...*              ... ... ... ...*           1 xm xm^2 ... ...  xm^n*  ΦT∗Φ∗a=ΦT∗y* *************************************************/cv::Mat phy(chain.size(), n, CV_32F, cv::Scalar::all(0));for (int i = 0; i < phy.rows; i++){float* pr = phy.ptr<float>(i);for (int j = 0; j < phy.cols; j++){pr[j] = pow(chain[i].x, j);}y.at<float>(i) = chain[i].y;}cv::Mat phy_t = phy.t();cv::Mat phyMULphy_t = phy.t()*phy;cv::Mat phyMphyInv = phyMULphy_t.inv();cv::Mat a = phyMphyInv * phy_t;a = a * y;qDebug() << a.rows << a.cols;std::cout << "res a = " << a << ";" << std::endl << std::endl;QList<double> resParas;for (int i = 0; i < a.rows; i++){qDebug() << "2--final:" << i << a.at<float>(i,0);resParas.push_back(a.at<float>(i, 0));}return resParas;
}//第三种方式  最小二乘曲线拟合
//x[n]       存放给定数据点的X坐标。
//y[n]       存放给定数据点的Y坐标。
//n          给定数据点的个数。
//a[m]       返回m - 1次拟合多项式的系数。
//m          拟合多项式的项数。要求m<=min(n,20)。
//dt[3]      分别返回误差平方和,误差绝对值之和与误差绝对值的最大值。
//void pir1(double x[], double y[], int n, double a[], int m, double dt[])
QList<double> least_squares_curve_fitting(std::vector<cv::Point2d> &inPoins, int m)
{double dt[3] = { 0.0 };int n = inPoins.size();std::vector<double> a(m);std::vector<double> x;std::vector<double> y;for (int i = 0; i < n; i++){cv::Point2d tmpPoint = inPoins.at(i);x.push_back(tmpPoint.x);y.push_back(tmpPoint.y);}int i, j, k;double p, c, g, q, d1, d2, s[20], t[20], b[20];for (i = 0; i <= m - 1; i++) a[i] = 0.0;if (m > n) m = n;if (m > 20) m = 20;b[0] = 1.0; d1 = 1.0*n; p = 0.0; c = 0.0;for (i = 0; i <= n - 1; i++){p = p + x[i]; c = c + y[i];}c = c / d1; p = p / d1;a[0] = c * b[0];if (m > 1){t[1] = 1.0; t[0] = -p;d2 = 0.0; c = 0.0; g = 0.0;for (i = 0; i <= n - 1; i++){q = x[i] - p; d2 = d2 + q * q;c = c + y[i] * q;g = g + x[i] * q*q;}c = c / d2; p = g / d2; q = d2 / d1;d1 = d2;a[1] = c * t[1]; a[0] = c * t[0] + a[0];}for (j = 2; j <= m - 1; j++){s[j] = t[j - 1];s[j - 1] = -p * t[j - 1] + t[j - 2];if (j >= 3)for (k = j - 2; k >= 1; k--)s[k] = -p * t[k] + t[k - 1] - q * b[k];s[0] = -p * t[0] - q * b[0];d2 = 0.0; c = 0.0; g = 0.0;for (i = 0; i <= n - 1; i++){q = s[j];for (k = j - 1; k >= 0; k--)  q = q * x[i] + s[k];d2 = d2 + q * q; c = c + y[i] * q;g = g + x[i] * q*q;}c = c / d2; p = g / d2; q = d2 / d1;d1 = d2;a[j] = c * s[j]; t[j] = s[j];for (k = j - 1; k >= 0; k--){a[k] = c * s[k] + a[k];b[k] = t[k]; t[k] = s[k];}}dt[0] = 0.0; dt[1] = 0.0; dt[2] = 0.0;for (i = 0; i <= n - 1; i++){q = a[m - 1];for (k = m - 2; k >= 0; k--) q = a[k] + q * x[i];p = q - y[i];if (fabs(p) > dt[2]) dt[2] = fabs(p);dt[0] = dt[0] + p * p;dt[1] = dt[1] + fabs(p);}QList<double> resParas;for (int i = 0; i < m; i++){qDebug() << "3--final:" << i << a[i];resParas.push_back(a[i]);}return resParas;
}// 测试程序
void curveFit() {std::vector<cv::Point2d> inPoints;inPoints.push_back(cv::Point2d(34, 36));inPoints.push_back(cv::Point2d(50, 82));inPoints.push_back(cv::Point2d(74, 142));inPoints.push_back(cv::Point2d(100, 200));inPoints.push_back(cv::Point2d(123, 242));inPoints.push_back(cv::Point2d(160, 281));inPoints.push_back(cv::Point2d(215, 236));inPoints.push_back(cv::Point2d(250, 150));inPoints.push_back(cv::Point2d(300, 84));inPoints.push_back(cv::Point2d(367, 74));inPoints.push_back(cv::Point2d(403, 139));inPoints.push_back(cv::Point2d(442, 550));inPoints.push_back(cv::Point2d(481, 300));QList<double> resParas3 = least_squares_curve_fitting(inPoints, 5);QList<double> resParas2 = polyfit(inPoints, 5);QList<double> resParas = discrete_point_fitting_curve(inPoints, 4);qDebug() << "resParas size:" << resParas;std::vector<cv::Point2d> newPoints;for (int i = 0; i < 500; i++){double newY = 0;for (int j = 0; j < resParas.size(); j++){newY += resParas.at(j) * pow(i, j);}newPoints.push_back(cv::Point(i, newY));newY = 0;}cv::Mat whiteImage = cv::Mat::zeros(500, 500, CV_8UC3);for (size_t i = 0; i < inPoints.size(); i++) {cv::circle(whiteImage, inPoints[i], 5.0, cv::Scalar(0, 0, 255), -1);}for (size_t i = 0; i < newPoints.size() - 1; i++) {cv::line(whiteImage, newPoints[i], newPoints[i + 1], cv::Scalar(0, 255, 255), 2, cv::LINE_AA);}//cv::imwrite("whiteImage.png", whiteImage);cv::namedWindow("curveFit");cv::imshow("curveFit", whiteImage);cv::waitKey(0);}

效果图:

k=3

在这里插入图片描述

k=4

在这里插入图片描述

k=5

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/617820.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker安装nacos+mysql+配置网络

一、配置网络 为什么要配置网络&#xff1f;因为 Nacos 内要连接MySQL数据库的&#xff0c;我的 MySQL 数据库也是用 Docker启动的&#xff0c;所以2个容器间要通信是需要配置他们使用相同的网络。这个操作要在启动Nacos容器之前。 注意&#xff1a;这里配置的网络只在镜像内部…

【python】OpenCV—Histogram(9)

学习参考来自 Python下opencv使用笔记&#xff08;九&#xff09;&#xff08;图像直方图&#xff09; 更多学习笔记可以参考 【python】OpenCV—RGB&#xff08;1&#xff09;【python】OpenCV—Rectangle, Circle, Selective Search&#xff08;1.2&#xff09;【python】…

Python学习从0到1 day3 python变量和debug

没关系&#xff0c;这破败的生活压不住我 ——24.1.13 一、变量的定义 1.什么是量&#xff1f; 量是程序运行中的最小单元 2.什么是变量呢&#xff1f; ①变量是存储数据的容器 ②变量存储的数据时临时的&#xff0c;变量只有在程序运行过程中是有效的&#xff0c;当程序执行结…

在vue中实现树形结构的表格,以及对数据结构的处理

需求&#xff1a;有一些告警数据&#xff0c;如果他们的计划编码相同则实现折叠效果&#xff0c;单击某行数据可以进行关闭&#xff0c;状态发生改变&#xff0c;关闭以后按钮禁用。 实现效果&#xff1a;目前所有告警消息都被关闭&#xff0c;如果未被关闭则可以进行关闭 实现…

【Python】编程练习的解密与实战(四)

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《Python | 编程解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 &#x1fa90;1. 初识Python &a…

集简云动作管理平台上线:创建强大且可分享的AI助手(GPTs)

OpenAI的GPT Store于昨天上线&#xff0c;用户可以找到好用的GPTs&#xff0c;也可以将自己的GPTs分享到GPT Store中。未来&#xff08;预计今年1季度&#xff09;甚至可以从GPTs Store中获取利润分成。 要创建强大的GPTs离不开调用外部的软件工具&#xff0c;比如查询CRM/ERP软…

Stable Diffusion初体验

体验了下 Stable Diffusion 2.0 的图片生成&#xff0c;效果还是挺惊艳的&#xff0c;没有细调prompt输入&#xff0c;直接输入了下面的内容&#xff1a; generate a Elimination Game image of burnning tree, Cyberpunk style 然后点击生成&#xff0c;经过了10多秒的等待就输…

TensorRT模型优化模型部署(七)--Quantization量化(PTQ and QAT)(二)

系列文章目录 第一章 TensorRT优化部署&#xff08;一&#xff09;–TensorRT和ONNX基础 第二章 TensorRT优化部署&#xff08;二&#xff09;–剖析ONNX架构 第三章 TensorRT优化部署&#xff08;三&#xff09;–ONNX注册算子 第四章 TensorRT模型优化部署&#xff08;四&am…

国产麒麟系统开机没有网络需要点一下这个设置

问题描述&#xff1a; 一台国产电脑网线连接正常&#xff0c;打开网页后显示无法访问&#xff0c;那么是什么原因无法上网呢&#xff1f;下面就告诉你一个小方法去解决一下这个问题&#xff1b; 检查故障&#xff1a; 检测交换机、网线、水晶头全都正常&#xff0c;同房间摆放的…

Hive基础知识(十):Hive导入数据的五种方式

1. 向表中装载数据&#xff08;Load&#xff09; 1&#xff09;语法 hive> load data [local] inpath 数据的 path[overwrite] into table student [partition (partcol1val1,…)]; &#xff08;1&#xff09;load data:表示加载数据 &#xff08;2&#xff09;local:表示…

【从0上手cornerstone3D】如何渲染一个基础的Dicom文件(含演示)

一、Cornerstone3D 是什么&#xff1f; Cornerstone3D官网&#xff1a;https://www.cornerstonejs.org/ 在线查看显示效果&#xff08;加载需时间&#xff0c;可先点击运行&#xff09;&#xff0c;欢迎fork 二、代码示例 了解了Cornerstone是什么&#xff0c;有什么作用后&…

竞赛保研 基于深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的视频多目标跟踪实现 …

2024年湖北职称评审对论文的要求

1.期刊发表版面的时间节点2024年12月及之前 2.期刊是正规的期刊&#xff0c;有国内刊号 3.期刊能在国家出版社总署检索到 4.文章内容查重符合知网查重标准 5.论文方向和申报专业方向一致 6.必须要是第一作者或者独著 7.评正高的人才们要准备中文核心论文两篇或出版专业学术论著…

UE5 简易MC教程学习心得

https://www.bilibili.com/video/BV12G411J7hV?p13&spm_id_frompageDriver&vd_sourceab35b4ab4f3968642ce6c3f773f85138 ———— 目录 0.摧毁逻辑学习 1.发光材质灯方块 2.封装。想让子类 不更改父类的变量。 3.材质命名习惯。 0.摧毁逻辑学习 达到摧毁的条件…

用模方软件进行模型的透明贴图,为什么翻出来透明部分是黑的?

答&#xff1a;透贴需要用PNG格式。 模方是一款针对实景三维模型的冗余碎片、水面残缺、道路不平、标牌破损、纹理拉伸模糊等共性问题研发的实景三维模型修复编辑软件。模方4.1新增自动单体化建模功能&#xff0c;支持一键自动提取房屋结构&#xff0c;平均1栋复杂建筑物只需3…

JAVA毕业设计121—基于Java+Springboot的房屋租赁管理系统(源代码+数据库+9000字文档)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringboot的房屋租赁管理系统(源代码数据库9000字文档)121 一、系统介绍 本项目还有ssm版本&#xff0c;分为用户、房东、管理员三种角色 1、用户&#xff1a; 注册、登…

【机器学习300问】5、什么是强化学习?

我将从三个方面为大家简明阐述什么是强化学习&#xff0c;首先从强化学习的定义大家的了解强化学习的特点&#xff0c;其次学习强化学习里特殊的术语加深对强化学习的理解&#xff0c;最后通过和监督学习与无监督学习的比较&#xff0c;通过对比学习来了解强化学习。 一、强化…

thinkphp6报错Driver [Think] not supported.

thinkphp6报错Driver [Think] not supported. 问题解决方法测试 问题 直接使用 View::fetch();渲染模板报错 解决方法 这个报错是由于有安装视图驱动造成的 运行如下命令安装即可 composer require topthink/think-view官方文档中是这么写的 视图功能由\think\View类配合视…

JavaScript基础03

1 - 循环 1.1 for循环 语法结构 for(初始化变量; 条件表达式; 操作表达式 ){//循环体 } 名称作用初始化变量通常被用于初始化一个计数器&#xff0c;该表达式可以使用 var 关键字声明新的变量&#xff0c;这个变量帮我们来记录次数。条件表达式用于确定每一次循环是否能被执行…

Python元组(tuple)

目录 元组元组的创建和删除访问元组元素修改元组元组方法 元组 元组是有序且不可更改的集合。在 Python 中&#xff0c;元组是用圆括号编写的。 元组的创建和删除 实例 创建元组&#xff1a; thistuple ("a", "b", "c") print(thistuple)删除…