1. 程式人生 > >曲線擬合的最小二乘法(基於OpenCV實現)的,擬合影象中離散點的擬合直線

曲線擬合的最小二乘法(基於OpenCV實現)的,擬合影象中離散點的擬合直線

   今天使用擬合的最小二乘法,求出了給定的一組座標系上的點對最接近的直線的。
  其具體理論如下:
   在科學實驗資料處理中,往往要根據一組給定的實驗資料,求出自變數x與因變數y的函式關係,這是為待定引數,由於觀測資料總有誤差,且待定引數ai的數量比給定資料點的數量少(即n<m),因此它不同於插值問題.這類問題不要求通過點,而只要求在給定點上的誤差的平方和最小.當時,即
         (5.8.1)
這裡是線性無關的函式族,假定在上給出一組資料以及對應的一組權,這裡為權係數,要求使最小,其中
           (5.8.2)

這就是最小二乘逼近,得到的擬合曲線為y=s(x),這種方法稱為曲線擬合的最小二乘法.
  (5.8.2)中

實際上是關於的多元函式,求I的最小值就是求多元函式I的極值,由極值必要條件,可得
      (5.8.3)
根據內積定義(見第三章)引入相應帶權內積記號
             (5.8.4)
則(5.8.3)可改寫為
     
這是關於引數的線性方程組,用矩陣表示為
            (5.8.5)
(5.8.5)稱為法方程.當線性無關,且在點集上至多隻有n個不同零點,則稱在X上滿足Haar條件,此時(5.8.5)的解存在唯一(證明見[3]).記(5.8.5)的解為
        
從而得到最小二乘擬合曲線
          (5.8.6)
可以證明對,有
     
故(5.8.6)得到的
即為所求的最小二乘解.它的平方誤差為
                  (5.8.7)
均方誤差為
          
  在最小二乘逼近中,若取,則,表示為
             (5.8.8)
此時關於係數的法方程(5.8.5)是病態方程,通常當n≥3時都不直接取作為基。

原始碼如下:
基於OpenCV
int calAngle(IplImage **lpSrc, IplImage **lpRes, double* angle)
{
    long double a,b,q;
    long double u11,u12,u21,u22,c1,c2,p;
    int i,j;
    MYPOINT *points = 0;
    IplImage *src = *lpSrc;
    IplImage *res = *lpRes;
    int step = src->widthStep/sizeof(char);    //排列的影象行大小,以位元組為單位   
    uchar *srcData = (uchar*)src->imageData;
    int elementCount = 0;
    MYPOINT tempPoint;
    MYPOINT *interatorPoint;
    CvPoint startPoint, endPoint;
   
    res = cvCreateImage( cvGetSize(src), 8, 3 );
    memset(res->imageData, 0x00, (src->width)*(src->height));

    u11 = 0.0;
    u12 = 0.0;
    u21 = 0.0;
    u22 = 0.0;
    c1 = 0.0;
    c2 = 0.0;
    p = 0.0;
   
    points = (MYPOINT*)malloc((src->height) * sizeof(MYPOINT));
    interatorPoint = points;
    for (j = 0; j < src->height; ++j)
    {
        for (i = 0; i < src->width; ++i)
        {
            if (srcData[j*step + i] == 255)
            {
                tempPoint.x = i;
                tempPoint.y = j;
                *interatorPoint = tempPoint;
                ++interatorPoint;
                ++elementCount;
                break;
            }
        }
    }

    interatorPoint = points;
    for (i = 0; i < elementCount; i++)//列法方程
    {
        if (0 == i)
        {
            startPoint.x = (*interatorPoint).x;
            startPoint.y = (*interatorPoint).y;
        }
        u11+=1.0;
        u12+=(*interatorPoint).x;
        u22+=(*interatorPoint).x*(*interatorPoint).x;
        c1+=(*interatorPoint).y;
        c2+=(*interatorPoint).y*(*interatorPoint).x;
        ++interatorPoint;
        //printf("##:%d:/t    %lf, %lf, %lf, %lf, %lf%\n", i, u11, u12, u22, c1, c2);
    }
    u21=u12;
    a=(c1*u22-c2*u12)*1.0/(u11*u22-u12*u21);//求a,b的解
    b=(c1*u21-c2*u11)*1.0/(u21*u12-u22*u11);

    interatorPoint = points;

    for(i = 0; i < elementCount; i++)
    {
        (*interatorPoint).z=a+b*(*interatorPoint).x;
        p+=pow(((*interatorPoint).z-(*interatorPoint).y),2);
        ++interatorPoint;
    }
   
    q=sqrt(p);

    //輸出線性方程   
    printf("answer:s(x)=%lf+%lf(x)\n",a,b);

    endPoint.y = src->height - 1;
    endPoint.x = ( endPoint.y -a ) / b;
    printf("endPoint:%d, %d\n", endPoint.x, endPoint.y);
    //輸出均方誤差
    printf("均方誤差:q=%lf\n",q);

    *angle = atan(b);
    printf("Angle is: %f", *angle*180.0/PI);
   
    cvLine(res, startPoint, endPoint, CV_RGB(0,255,0), 1, 8 );

    cvReleaseImage(lpRes);
   
    *lpRes = res;
   
    free(points);
    return 0;
}

擬合後的結果如下:
其中左邊是離散的一些點,右邊綠色的線是擬合後的直線。

相關推薦

曲線乘法基於OpenCV實現

在科學實驗資料處理中,往往要根據一組給定的實驗資料,求出自變數x與因變數y的函式關係,這是為待定引數,由於觀測資料總有誤差,且待定引數ai的數量比給定資料點的數量少(即n<m),因此它不同於插值問題.這類問題不要求通過點,而只要求在給定點上的誤差的平方和最小.當時,即   

曲線乘法基於OpenCV實現影象離散直線

   今天使用擬合的最小二乘法,求出了給定的一組座標系上的點對最接近的直線的。  其具體理論如下:    在科學實驗資料處理中,往往要根據一組給定的實驗資料,求出自變數x與因變數y的函式關係,這是為待定引數,由於觀測資料總有誤差,且待定引數ai的數量比給定資料點的數量少(

Python 迴歸 普通乘法Ordinary Least Squares

廣義線性迴歸模型: 把作為係數向量(coef_);把作為截距(intercept_) 1.普通最小二乘法(Ordinary Least Squares) 線性迴歸的目的就是是的預測值與實際值的殘差平方和最小: import matplotlib.

移動乘法MLS曲線曲面C++程式碼實現

移動最小二乘法(MLS)曲線曲面擬合 曲線曲面擬合有很多種方法,Beizer,B樣條等,曲面擬合移動最小二乘法是一個很好的選擇,本文會詳細講解一下移動最小二乘法方法擬合曲面,並給出C++程式碼實現。 本文首先是最小二乘法的分析,然後是畫曲面曲線圖。 目錄

Python 普通乘法OLS進行多項式

zlabel predict ylabel model for font 結果 param col 多元函數擬合。如 電視機和收音機價格多銷售額的影響,此時自變量有兩個。 python 解法: import numpy as np import pandas as

線性乘法Python實現

下面程式碼實現的是最小二乘法線性擬合,並且包含自己造的輪子與別人造的輪子的結果比較。問題:對y=2.5x+0.8y=2.5x+0.8直線附近的帶有噪聲的資料進行線性擬合,最終求出w,b的估計值。最小二乘法基本思想是使得樣本方差最小。程式碼中self_func()函式為自定義擬

【機器學習筆記02】乘法多元線性迴歸模型

數學基礎 1.轉置矩陣 定義: 將矩陣A同序數的行換成列成為轉置矩陣ATA^TAT,舉例: A=(1203−11)A=\begin{pmatrix} 1 &amp; 2 &amp; 0 \\ 3 &amp; -1 &amp;

【機器學習筆記01】乘法一元線性迴歸模型

【參考資料】 【1】《概率論與數理統計》 【2】 http://scikit-learn.org /stable/auto_examples/ linear_model/ plot_ols.html # sphx-glr-auto-examples-

常用演算法之:1、乘法1

深度學習發展到如今的地位,離不開下面這 6 段程式碼。本文介紹了這些程式碼的創作者及其完成這些突破性成就的故事背景。每個故事都有簡單的程式碼示例,讀者們可以在 FloydHub 和 GitHub 找到相關程式碼。 最小二乘法 所有的深度學習演算法都始於下面這個數學公式(

普通乘法 Ordinary Least SquareOLS

我們以最簡單的一元線性模型來解釋最小二乘法。什麼是一元線性模型呢? 監督學習中,如果預測的變數是離散的,我們稱其為分類(如決策樹,支援向量機等),如果預測的變數是連續的,我們稱其為迴歸。迴歸分析中,如果只包括一個自變數和一個因變數,且二者的關係可用一條直線近似表示,這種迴歸分析稱為一元線性迴

乘法平方法(generalized least squares)

       許多工程問題,常常需要根據兩個變數的幾組實驗數值:實驗資料,來找出這個兩個變數的函式關係的近似表示式。通常把這樣得到的函式的近似表示式叫做經驗公式。經驗公式建立以後,就可以把生產或實驗中所積累的某些經驗,提高到理論上加以分析。下面我們通過舉例介紹常用的一種建立

迴歸分析的引數估計為何是乘法least squares不是乘法(least absolute deviations)

如題,面試被問到了。今天網上找了些資料,整理了一下。 迴歸分析就是找到一條最合適的擬合線來逼近所有的觀測點。如何衡量擬合的好壞程度呢,直接地,就是看擬合值與觀測值之間的距離了。在這種情況下,我們直接用擬合值與觀測值差的絕對值就可以衡量誤差(如公式1),為什麼要用差的平方呢(

python3__機器學習__神經網路基礎演算法__乘法LS演算法

1.LS演算法說明 LS演算法是一種數學優化技術,也是一種機器學習常用演算法。他通過最小化誤差的平方和尋找資料的最佳函式匹配。利用最小二乘法可以簡便的求得未知的資料(1),並使得這些求得的資料與實際資料之間誤差的平方和最小。除此之外最小二乘法還可用於曲線擬合(2),其他一些優化問題(

乘法自我理解+自我熟悉(1)

    最近一直在看機器學習的東西,看了好些論文,但奈何基礎實在太差,有很多東西都不懂。所以就看各種演算法。雖然當然看完覺得理解了,但一段時間過去又忘的差不多,無奈之舉,希望通過部落格來加深自己對基礎知識的理解和掌握。這次總結也是通過各種部落格和材料收集得到的,所以只能說是

乘法在飛思卡爾智慧車路徑搜尋的應用

1、什麼是最小二乘法 最小二乘法就是要使得觀測點和估計點的距離的平方達到最小,我們可以使用一些已知的離散的點,擬合出一條與這些離散點最為接近的曲線,從而可以分析出這些離散點的走向趨勢。 如圖所示是一個線性擬合,紅色的線代表觀測點與估計點的距離,使得這些距離的平方和最小這

乘法的C語言實現

1.  前言 最近斷斷續續重溫了一些數學書,有高等數學,也有初等數學。 有時候,覺得數學才是世界上最美的東西,但有時候又覺得數學很高冷,不接地氣。 不過,前段時間工作中用到了最小二乘法,下面記錄一些用法。 2. 最小二乘法 根據維基百科的說明: 最小二乘法(又稱最小平

乘法C語言的實現

1.實驗目的: 進一步熟悉曲線擬合的最小二乘法。 掌握程式語言字元處理程式的設計和除錯技術。 2.實驗要求: 輸入:已知點的數目以及各點座標 。 輸出:根據最小二乘法原理以及各點座標求出擬合曲線 。 3.程式流程: (1)輸入已知點的個數; (2)分別輸入已知點的X座標

編寫一個函式 reverse_string(char * string)遞迴實現將引數字串的字元反向排列。 要求不能使用C函式庫的字串操作函式

#include<stdio.h> #include<stdlib.h> int str(char *string) { int n = 0; while (*string) { n++; string++; } return n; } void rever

乘法多項式曲線原理與實現錯誤地方已經修改底層補充自己寫的java實現

也可使用Apache開源庫commons math,提供的功能更強大, http://commons.apache.org/proper/commons-math/userguide/fitting.html package com.fjsh.algorithm.leastSquareMethod.d