c++多项式拟合

c++多项式拟合基本原理 幂函数可逼近任意函数 上式中 N 表示多项式阶数 实际应用中一般取 3 或 5 假设 N 5 则 共有 6 个未知数 仅需 6 个点即可求解 可表示为矩阵方程 Y 的维数为 R 1 U 的维数 R 6 K 的维数 6 1 R gt 6 时 超定方程求解 下面是使用 C 实现的多项式拟合的程序 程序中使用 opencv 进行矩阵运算和图像显示 程序分别运行了 N 3 5 7 9 时的情况 结果如下 include opencv2 opencv hpp include opencv2 opencv hpp

基本原理:幂函数可逼近任意函数。

上式中,N表示多项式阶数,实际应用中一般取3或5;

假设N=5,则:

共有6个未知数,仅需6个点即可求解;

可表示为矩阵方程:

Y的维数为[R*1],U的维数[R * 6],K的维数[6 * 1]。

R> 6时,超定方程求解:

下面是使用C++实现的多项式拟合的程序,程序中使用opencv进行矩阵运算和图像显示。程序分别运行了N=3,5,7,9时的情况,结果如下:

#include


#include


#include


using namespace cv;
using namespace std;
 
Mat polyfit(vector & in_point, int n);

 
int main()
{

    //数据输入
    Point in[19] = { Point(50,120),Point(74,110),Point(98,100),Point(122,100),Point(144,80)
        ,Point(168,80),Point(192,70),Point(214,50),Point(236,40),Point(262,20)
        ,Point(282,20),Point(306,30),Point(328,40),Point(356,50),Point(376,50)
        ,Point(400,50),Point(424,50),Point(446,40),Point(468,30) };
 
    vector in_point(begin(in),end(in));

    
    //n:多项式阶次
    int n = 9;
    Mat mat_k = polyfit(in_point, n);
 
 
    //计算结果可视化
    Mat out(150, 500, CV_8UC3,Scalar::all(0));
 
    //画出拟合曲线
    for (int i = in[0].x; i < in[size(in)-1].x; ++i)
    {

        Point2d ipt;
        ipt.x = i;
        ipt.y = 0;
        for (int j = 0; j < n + 1; ++j)
        {

            ipt.y += mat_k.at

(j, 0)*pow(i,j);

        }
        circle(out, ipt, 1, Scalar(255, 255, 255), CV_FILLED, CV_AA);
    }
 
    //画出原始散点
    for (int i = 0; i < size(in); ++i)
    {

        Point ipt = in[i];
        circle(out, ipt, 3, Scalar(0, 0, 255), CV_FILLED, CV_AA);
    }
 
    imshow(“9次拟合”, out);
    waitKey(0);
    
    return 0;
}
 
Mat polyfit(vector & in_point, int n)

{

    int size = in_point.size();
    //所求未知数个数
    int x_num = n + 1;
    //构造矩阵U和Y
    Mat mat_u(size, x_num, CV_64F);
    Mat mat_y(size, 1, CV_64F);
 
    for (int i = 0; i < mat_u.rows; ++i)
        for (int j = 0; j < mat_u.cols; ++j)
        {

            mat_u.at

(i, j) = pow(in_point[i].x, j);

        }
 
    for (int i = 0; i < mat_y.rows; ++i)
    {

        mat_y.at

(i, 0) = in_point[i].y;

    }
 
    //矩阵运算,获得系数矩阵K
    Mat mat_k(x_num, 1, CV_64F);
    mat_k = (mat_u.t()*mat_u).inv()*mat_u.t()*mat_y;
    cout << mat_k << endl;
    return mat_k;

















































































}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222417.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午3:50
下一篇 2026年3月17日 下午3:51


相关推荐

  • 自然语言处理——BLEU详解以及简单的代码实现

    自然语言处理——BLEU详解以及简单的代码实现引子何为 BLEU 最初的 BLEU 改良型 BLEU n gram 短译句的惩罚因子总结附录 源代码 引子最近在做一个深度学习的小项目 Captiongener 其中在快速评估模型的时候使用到了 Bleu 这一个指标 于是花了一点时间来研究了这个指标代表的意义以及如何计算这个指标 附带源码 何为 BLEU 在机器翻译领域 我

    2026年3月18日
    1
  • 代码注册广播需要调用registerReceiver()方法_设计一个注册页面register

    代码注册广播需要调用registerReceiver()方法_设计一个注册页面register前面我们介绍了Android系统的广播机制,从本质来说,它是一种消息订阅/发布机制,因此,使用这种消息驱动模型的第一步便是订阅消息;而对Android应用程序来说,订阅消息其实就是注册广播接收器,本文将探讨Android应用程序是如何注册广播接收器以及把广播接收器注册到哪里去的。     在Android的广播机制中,ActivityManagerService扮演着广播中心的角色,负责系统

    2025年11月1日
    4
  • linux下快速查找文件

    linux下快速查找文件在使用linux时,经常需要进行文件查找。其中查找的命令主要有find和grep。两个命令是有区的。  区别:(1)find命令是根据文件的属性进行查找,如文件名,文件大小,所有者,所属组,是否为空,访问时间,修改时间等。          (2)grep是根据文件的内容进行查找,会对文件的每一行按照给定的模式(patter)进行匹配查找。       …

    2022年7月26日
    9
  • iBatis和 MyBatis的区别

    iBatis和 MyBatis的区别本文主要讲述了 iBatis2 x 和 MyBatis3 0 x 的区别 以及从 iBatis 向 MyBatis 移植时需要注意的地方 通过对本文的学习 读者基本能够了解 MyBatis 有哪些方面的改进 并能够顺利使用 MyBatis 进行开发 本文更适合有 iBatis 基础的开发人员阅读 从 iBatis 到 MyBatis 你准备好了吗 对于从事 Jav

    2026年3月17日
    3
  • 学算法先学数据结构?是否是无稽之谈?[通俗易懂]

    学算法先学数据结构?是否是无稽之谈?[通俗易懂]头发没了

    2022年8月10日
    7
  • 驱动总裁怎么使用U盘装机 驱动总裁怎么制作启动盘【必看】

    驱动总裁怎么使用U盘装机 驱动总裁怎么制作启动盘【必看】

    2026年3月13日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号