1.原理

在现实中经常遇到这样的问题,一个函数并不是以某个数学表达式的形式给出,而是以一些自变量与因变量的对应表给出,老师讲课的时候举的个例子是犯罪人的身高和留下的脚印长,可以测出一些人的数据然后得到一张表,它反应的是一个函数,回归的意思就是将它还原成数学表达式,这个式子也称为经验表达式,之所以叫经验就是说它不完全是实际中的那样准确,是有一定偏差的,只是偏差很小罢了。

最小二乘法     设经验 方程是y=F(x),方程中含有一些待定系数an,给出真实值{(xi,yi)|i=1,2,...n},将这些x,y值代入方程然后作 差,可以描述误差:yi-F(xi),为了考虑整体的误差,可以取平方和,之所以要平方是考虑到误差可正可负直接相加可以相互抵消,所以记误差为:

e=∑(yi-F(xi))^2

它是一个多元函数,有an共n个未知量,现在要求的是最小值。所以必然满足对各变量的偏导等于0,于是得到n个方程:

de/da1=0 de/da2=0 ... de/dan=0

n个方程确定n个未知量为常量是理论上可以解出来的。用这种误差分析的方法进行回归方程的方法就是最小二乘法。

线性回归 如果经验方程是线性的,形如y=ax+b,就是线性回归。按上面的分析,误差函数为:

e=∑(yi-axi-b)^2

各偏导为:

de/da=2∑(yi-axi-b)xi=0 de/db=-2∑(yi-axi-b)=0

于是得到关于a,b的线性方程组:

(∑xi^2)a+(∑xi)b=∑yixi (∑xi)a+nb=∑yi

设A=∑xi^2,B=∑xi,C=∑yixi,D=∑yi,则方程化为:

Aa+Bb=C Ba+nb=D

解出a,b得:

a=(Cn-BD)/(An-BB) b=(AD-CB)/(An-BB) 这就是我们要进行的算法。

2.C++实现 /*  * =====================================================================================  *  *       Filename:  nihe.cpp  *  *    Description:  A least square method for fitting a curve  *  *        Version:  1.0  *        Created:  03/21/2009 12:32:56 PM  *       Revision:  none  *       Compiler:  gcc  *  *         Author:  Futuredaemon (BUPT), gnuhpc@gmail.com  *        Company:  BUPT_UNITED  *  * =====================================================================================  */

#include  <stdlib.h> #include  <iostream> #include  <valarray>

using namespace std;

int main(int argc, char *argv[]) {     int num = 0;

cout << " Input how many numbers you want to calculate:";     cin >> num;

valarray<double> data_x(num);     valarray<double> data_y(num);

while( num )     {         cout << "Input the "<< num <<" of x:";         cin >> data_x[num-1];         cout << "Input the "<< num <<" of y:";         cin >> data_y[num-1];         num--;     }

double A =0.0;     double B =0.0;     double C =0.0;     double D =0.0;

A = (data_x*data_x).sum();     B = data_x.sum();     C = (data_x*data_y).sum();     D = data_y.sum();

double k,b,tmp =0;     if(tmp=(A*data_x.size()-B*B))     {         k = (C*data_x.size()-B*D)/tmp;         b = (A*D-C*B)/tmp;     }

else     {         k=1;         b=0;     }

cout <<"k="<<k<<endl;     cout <<"b="<<b<<endl;

return 0; }

3.OpenCV结构实现 #include "cv.h" #include <iostream>

using namespace std;

int main(int argc, char *argv[]) {   int i=0;   int j=0;   int num;   double A,B,C,D;   double k,b,tmp=0;   cout <<"Input how many numbers you want to calculate:";   cin >>num;

CvMat *mat1=cvCreateMat(1,num,CV_64FC1);   CvMat *mat2=cvCreateMat(1,num,CV_64FC1);   CvMat *mattmp=cvCreateMat(1,num,CV_64FC1);

for (j=0;j<mat1->cols;j++)     {       cout << "data X"<<j<<"=";       cin>>CV_MAT_ELEM(*mat1,double,0,j);       cout << "data Y"<<j<<"=";       cin>>CV_MAT_ELEM(*mat2,double,0,j);

}

for (j=0;j<mat1->cols;j++)     {

cout<<"X="<<CV_MAT_ELEM(*mat1,double,0,j)           <<",Y="<<CV_MAT_ELEM(*mat2,double,0,j)<<endl;     }

cvMul(mat1,mat1,mattmp,1);   A = cvSum(mattmp).val[0];

B = cvSum(mat1).val[0];

cvMul(mat1,mat2,mattmp,1);   C = cvSum(mattmp).val[0];

D = cvSum(mat2).val[0];

tmp = A*mat1->cols-B*B;

k = (C*mat1->cols-B*D)/tmp;   b = (A*D-C*B)/tmp;

cout << "k=" << k <<endl;   cout << "b=" << b <<endl;

cvReleaseMat(&mat1);   cvReleaseMat(&mat2);

return 0; }

曲线拟合的最小二乘法(基于OpenCV实现)的更多相关文章

  1. 图像矫正-基于opencv实现

    一.引言 上篇文章中四种方法对图像进行倾角矫正都非常有效.Hough变换和Radon相似,其抗干扰能力比较强,但是运算量大,程序执行慢,其改进方法为:我们可以不对整幅图像进行操作,可以在图像中选取一块 ...

  2. [转载]卡尔曼滤波器及其基于opencv的实现

    卡尔曼滤波器及其基于opencv的实现 源地址:http://hi.baidu.com/superkiki1989/item/029f65013a128cd91ff0461b 这个是维基百科中的链接, ...

  3. 基于Opencv和Mfc的图像处理增强库GOCVHelper(索引)

    GOCVHelper(GreenOpen Computer Version Helper )是我在这几年编写图像处理程序的过程中积累下来的函数库.主要是对Opencv的适当扩展和在实现Mfc程序时候的 ...

  4. 基于OpenCv的人脸检测、识别系统学习制作笔记之一

    基于OpenCv从视频文件到摄像头的人脸检测 在OpenCv中读取视频文件和读取摄像头的的视频流然后在放在一个窗口中显示结果其实是类似的一个实现过程. 先创建一个指向CvCapture结构的指针 Cv ...

  5. 基于opencv网络摄像头在ubuntu下的视频获取

     基于opencv网络摄像头在ubuntu下的视频获取 1  工具 原料 平台 :UBUNTU12.04 安装库  Opencv-2.3 2  安装编译运行步骤 安装编译opencv-2.3  参 ...

  6. 基于opencv的小波变换

    基于opencv的小波变换 提供函数DWT()和IDWT(),前者完成任意层次的小波变换,后者完成任意层次的小波逆变换.输入图像要求必须是单通道浮点图像,对图像大小也有要求(1层变换:w,h必须是2的 ...

  7. 基于opencv在摄像头ubuntu根据视频获取

     基于opencv在摄像头ubuntu根据视频获取 1  工具 原料 平台 :UBUNTU12.04 安装库  Opencv-2.3 2  安装编译执行步骤 安装编译opencv-2.3  參考h ...

  8. OpenCV2学习笔记(十四):基于OpenCV卡通图片处理

    得知OpenCV有一段时间.除了研究的各种算法的内容.除了从备用,据导游书籍和资料,尝试结合链接的图像处理算法和日常生活,第一桌面上(随着摄像头)完成了一系列的视频流处理功能.开发平台Qt5.3.2+ ...

  9. Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图

    Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图 分类: OpenCV图像处理2013-02-21 21:35 6459人阅读 评论(8) 收藏 举报   原文链接  ht ...

  10. 每日一练之自适应中值滤波器(基于OpenCV实现)

    本文主要介绍了自适应的中值滤波器,并基于OpenCV实现了该滤波器,并且将自适应的中值滤波器和常规的中值滤波器对不同概率的椒盐噪声的过滤效果进行了对比.最后,对中值滤波器的优缺点了进行了总结. 空间滤 ...

随机推荐

  1. 搞清css的单位 px,em,rem的区别

    前言:现在上大街一眼望去,基本上90%的人都拿着手机,走路,逛街,吃东西都不停着,所以对于我们这种前端开发的程序猿来说,让网页适应于移动端可以说是必须要满足的.所以最近也是一直在学习和实践.然后就接触 ...

  2. 发布一个开源极致的javascript模板引擎tpl.js

    tpl.js(大家直接去https://git.oschina.net/tianqiq/tpl.js这个上面看) 简介 tpl.js是一个比较极致(极小,极快,极简单)的js模板引擎,可以在各种js环 ...

  3. localhost访问错误Forbidden You don't have permission to access / on this server.解决办法(亲测)

    在httpd.conf文件下找到这段: <Directory /> Options FollowSymLinks AllowOverride None Order deny,allow D ...

  4. 让Java和MySQL连接起来

    Java 连接 MySQL 需要驱动包,可以下载菜鸟教程提供的 jar 包:http://static.runoob.com/download/mysql-connector-java-5.1.39- ...

  5. js平滑滚动到顶部,底部,指定地方

    [原文链接] 采用锚点进行页面中的跳转的确很方便,但是要想增加网页的效果,可以使用jquery中的animate,实现滚动的一个动作,慢慢的滚动到你想跳转到的位置,从而看起来会非常高大上. [示例演示 ...

  6. python 中字典实用操作

    1.字典转化为列表 a={"username":"12","password":"89"} print a.items( ...

  7. Ruby--学习记录(实时更新)

    变量的命名方式决定了变量的种类: 局部变量  以英文字母或者_开头: 全局变量  以$开头: 实例变量  以@开头: 类变量     以@@开头:

  8. trim(),正则表达式中文匹配

    ^[/u4E00-/u9FA5]+$ 匹配中文 验证Email地址:“^w+[-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$”  验证InternetURL:“^http://([ ...

  9. JavaScript中的splice方法

    splice方法根据传入的不同参数可分别实现删除和插入操作 使用splice(pra1,pra2,pra3)方法,需要为其提供如下参数: 1.pra1为其起始索引(即希望开始添加元素的地方) 2.pr ...

  10. 非常有趣的Console

    原文地址: http://www.helloweba.com/view-blog-383.html 批量去掉或替换文本中的换行符(notepad++.sublime text2) 原文地址:http: ...