久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9580|回復: 25
打印 上一主題 下一主題
收起左側(cè)

最小二乘法橢球擬合源碼

  [復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:166068 發(fā)表于 2018-5-24 23:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
受這篇帖子啟發(fā),http://www.zg4o1577.cn/bbs/dpj-97791-1.html
超詳細講解:羅盤和加速度計校正方法
但是實話說,這個代碼好像還是有點問題的,超過6個采樣點就不能用了,少于6個采樣點也不能用,
沒辦法,自己就重新寫了一遍,
我的思路是基于最小二乘法的橢球擬合,正統(tǒng)樸素方法
可以轉(zhuǎn)看知乎
https://www.zhihu.com/people/mo-tian-lun-1111/posts
也可以直接看這里貼的代碼,回復可見把,免的雁過不留毛的


//橢球校準.cpp
//最小二乘的橢球擬合
//((x-x0)/A)^2 + ((y-y0)/B)^2 + ((z-z0)/C)^2 = 1 的空間任意橢球方程式
//x^2 + a*y^2 + b*z^2 + c*x + d*y + e*z + f = 0 簡化后的方程
//問題轉(zhuǎn)換為由a,b,c,d,e,f,來求解x0,y0,z0 以及 A,B,C
//作者:摩天輪1111
//知乎ID:摩天輪1111 轉(zhuǎn)載請注明出處 尊重勞動者成果

#include "stdafx.h"
#include "stdio.h"
#include "string.h"
#include "math.h"

#define MATRIX_SIZE 6
#define u8 unsigned char
double m_matrix[MATRIX_SIZE][MATRIX_SIZE + 1];//系數(shù)矩陣
double solve[MATRIX_SIZE] = { 0 };//方程組的解對應最小二乘橢球擬合中的,a,b,c,d,e,f,

double m_result[MATRIX_SIZE];
int N = 0;//計算累計的采樣點次數(shù)的

//取絕對值
double Abs(double a)
{
return a < 0 ? -a : a;
}

//把矩陣系數(shù)全部清除為0
void ResetMatrix(void)
{
for (u8 row = 0; row < MATRIX_SIZE; row++)
{
for (u8 column = 0; column < MATRIX_SIZE + 1; column++)
m_matrix[row][column] = 0.0f;
}
}

//把輸入的數(shù)據(jù)先生成矩陣的元素的總和
void CalcData_Input(double x, double y, double z)
{
double V[MATRIX_SIZE + 1];
N++;
V[0] = y*y;
V[1] = z*z;
V[2] = x;
V[3] = y;
V[4] = z;
V[5] = 1.0;
V[6] = -x*x;
//構建系數(shù)矩陣,并進行累加
for (u8 row = 0; row < MATRIX_SIZE; row++)
{
for (u8 column = 0; column < MATRIX_SIZE + 1; column++)
{
m_matrix[row][column] += V[row] * V[column];
}
}
//b向量是m_matrix[row][6]
}

//化簡系數(shù)矩陣,把除以N帶上
void CalcData_Input_average()
{
for (u8 row = 0; row < MATRIX_SIZE; row++)
for (u8 column = 0; column < MATRIX_SIZE + 1; column++)
m_matrix[row][column] /= N;
//b向量是m_matrix[row][6]
}

//顯示出來系數(shù)矩陣和增廣矩陣[A|b]
void DispMatrix(void)
{
for (u8 row = 0; row < MATRIX_SIZE; row++)
{
for (u8 column = 0; column < MATRIX_SIZE + 1; column++)
{
printf("%23f ", m_matrix[row][column]);
if (column == MATRIX_SIZE - 1)
printf("|");
}
printf("\r\n");
}
printf("\r\n\r\n");
}

//交換兩行元素位置
void Row2_swop_Row1(int row1, int row2)
{
double tmp = 0;
for (u8 column = 0; column < MATRIX_SIZE + 1; column++)
{
tmp = m_matrix[row1][column];
m_matrix[row1][column] = m_matrix[row2][column];
m_matrix[row2][column] = tmp;
}
}

//用把row行的元素乘以一個系數(shù)k
void k_muiltply_Row(double k, int row)
{
for (u8 column = 0; column < MATRIX_SIZE + 1; column++)
m_matrix[row][column] *= k;
}

//用一個數(shù)乘以row1行加到row2行上去
void Row2_add_kRow1(double k, int row1, int row2)
{
for (u8 column = 0; column < MATRIX_SIZE + 1; column++)
m_matrix[row2][column] += k*m_matrix[row1][column];
}


//列主元,第k次消元之前,把k行到MATRIX_SIZE的所有行進行冒泡排出最大,排序的依據(jù)是k列的元素的大小
void MoveBiggestElement_to_Top(int k)
{
int row = 0, column = 0;

for (row = k + 1; row < MATRIX_SIZE; row++)
{
if (Abs(m_matrix[k][k]) < Abs(m_matrix[row][k]))
{
Row2_swop_Row1(k, row);
}
}
}

//高斯消元法,求行階梯型矩陣
u8 Matrix_GaussElimination(void)
{
double k = 0;
for (u8 cnt = 0; cnt < MATRIX_SIZE; cnt++)//進行第k次的運算,主要是針對k行以下的行數(shù)把k列的元素都變成0
{
//把k行依據(jù)k列的元素大小,進行排序
MoveBiggestElement_to_Top(cnt);
if (m_matrix[cnt][cnt] == 0)
return(1);//返回值表示錯誤
//把k行下面的行元素全部消成0,整行變化
for (u8 row = cnt + 1; row < MATRIX_SIZE; row++)
{
k = -m_matrix[row][cnt] / m_matrix[cnt][cnt];
Row2_add_kRow1(k, cnt, row);
}
DispMatrix();
}
return 0;
}

//求行最簡型矩陣,即把對角線的元素全部化成1
void Matrix_RowSimplify(void)
{
double k = 0;
for (u8 row = 0; row < MATRIX_SIZE; row++)
{
k = 1 / m_matrix[row][row];
k_muiltply_Row(k, row);
}
DispMatrix();
}

//求非齊次線性方程組的解
void Matrix_Solve(double* solve)
{
for (short row = MATRIX_SIZE - 1; row >= 0; row--)
{
solve[row] = m_matrix[row][MATRIX_SIZE];
for (u8 column = MATRIX_SIZE - 1; column >= row + 1; column--)
solve[row] -= m_matrix[row][column] * solve[column];
}
printf(" a = %f| b = %f| c = %f| d = %f| e = %f| f = %f ", solve[0], solve[1], solve[2], solve[3], solve[4], solve[5]);
printf("\r\n");
printf("\r\n");
}

//整個橢球校準的過程
void Ellipsoid_fitting_Process(void)
{
ResetMatrix();

//這里輸入任意個點加速度參數(shù),盡量在球面上均勻分布
CalcData_Input(87, -52, -4454);
CalcData_Input(301, -45, 3859);
CalcData_Input(274, 4088, -303);
CalcData_Input(312, -4109, -305);
CalcData_Input(-3805, -24, -390);
CalcData_Input(4389, 6, -228);
CalcData_Input(261, 2106, -3848);
CalcData_Input(327, -2047, -3880);
CalcData_Input(-1963, -13, -3797);
CalcData_Input(3024, 18, -3449);

CalcData_Input_average();//對輸入的數(shù)據(jù)到矩陣元素進行歸一化
DispMatrix();//顯示原始的增廣矩陣
if (Matrix_GaussElimination())        //求得行階梯形矩陣
printf("the marix could not be solved\r\n");
else
{
Matrix_RowSimplify();//化行最簡形態(tài)
Matrix_Solve(solve);//求解a,b,c,d,e,f

double a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;
a = solve[0];
b = solve[1];
c = solve[2];
d = solve[3];
e = solve[4];
f = solve[5];

double X0 = 0, Y0 = 0, Z0 = 0, A = 0, B = 0, C = 0;
X0 = -c / 2;
Y0 = -d / (2 * a);
Z0 = -e / (2 * b);
A = sqrt(X0*X0 + a*Y0*Y0 + b*Z0*Z0 - f);
B = A / sqrt(a);
C = A / sqrt(b);
printf(" ((x - x0) / A) ^ 2 + ((y - y0) / B) ^ 2 + ((z - z0) / C) ^ 2 = 1 Ellipsoid result as below:\r\n");
printf("\r\n");
printf(" X0 = %f| Y0 = %f| Z0 = %f| A = %f| B = %f| C = %f \r\n", X0, Y0, Z0, A, B, C);
}
while (1);
}


int main(int argc, char* argv[])
{
Ellipsoid_fitting_Process();
return 0;
}





評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:241506 發(fā)表于 2018-6-14 12:47 | 只看該作者
謝謝分享,學習了
回復

使用道具 舉報

板凳
ID:127875 發(fā)表于 2018-7-19 12:29 | 只看該作者
謝謝分享,學習了
回復

使用道具 舉報

地板
ID:383388 發(fā)表于 2018-8-6 12:08 | 只看該作者
謝謝LZ,學習了
回復

使用道具 舉報

5#
ID:380389 發(fā)表于 2018-9-19 11:19 來自手機 | 只看該作者
查看隱藏信息
回復

使用道具 舉報

6#
ID:446170 發(fā)表于 2018-12-14 10:03 | 只看該作者
查看隱藏信息
回復

使用道具 舉報

7#
ID:452413 發(fā)表于 2018-12-23 00:05 | 只看該作者
看隱藏
回復

使用道具 舉報

8#
ID:480934 發(fā)表于 2019-2-26 14:19 | 只看該作者
原作者的半徑2.0如何計算出來的
回復

使用道具 舉報

9#
ID:500463 發(fā)表于 2019-3-29 10:59 | 只看該作者
查看隱藏內(nèi)容
回復

使用道具 舉報

10#
ID:421862 發(fā)表于 2019-3-30 20:40 | 只看該作者
好資料。謝謝分享
回復

使用道具 舉報

11#
ID:523873 發(fā)表于 2019-4-28 18:28 | 只看該作者
查看隱藏內(nèi)容
回復

使用道具 舉報

12#
ID:149528 發(fā)表于 2019-6-23 21:25 | 只看該作者
給樓主點贊
回復

使用道具 舉報

13#
ID:481104 發(fā)表于 2019-8-7 14:59 | 只看該作者
感謝樓主分享
回復

使用道具 舉報

14#
ID:607865 發(fā)表于 2019-9-7 15:39 | 只看該作者
很強,正在學習
回復

使用道具 舉報

15#
ID:609998 發(fā)表于 2019-9-10 14:45 | 只看該作者
謝謝LZ,學習了
回復

使用道具 舉報

16#
ID:640043 發(fā)表于 2019-11-11 21:41 | 只看該作者
學習學習,我是學習數(shù)學專業(yè)的,看看能理解不
回復

使用道具 舉報

17#
ID:640043 發(fā)表于 2019-11-11 21:42 | 只看該作者
數(shù)學專業(yè),試試理解
回復

使用道具 舉報

18#
ID:244139 發(fā)表于 2019-12-10 15:58 | 只看該作者
看隱藏內(nèi)容
回復

使用道具 舉報

19#
ID:631127 發(fā)表于 2020-1-14 11:25 | 只看該作者
為什么定義六行七列呢。。。什么意思呢。。正常來說每列表示的不是x。y。z。軸的數(shù)據(jù)嗎
回復

使用道具 舉報

20#
ID:631127 發(fā)表于 2020-1-14 11:27 | 只看該作者
為什么是六行七列、、我的理解是每一列表示的是各軸的數(shù)據(jù)嗎、那么列數(shù)應該是3的倍數(shù)呀、、求指教。
回復

使用道具 舉報

21#
ID:231901 發(fā)表于 2020-1-20 10:44 | 只看該作者
學習一下,謝謝
回復

使用道具 舉報

22#
ID:690248 發(fā)表于 2020-2-5 15:31 | 只看該作者
學習一下,謝謝!
回復

使用道具 舉報

23#
ID:762638 發(fā)表于 2020-5-27 16:35 | 只看該作者
謝謝分享
回復

使用道具 舉報

24#
ID:773091 發(fā)表于 2020-6-8 17:18 | 只看該作者
謝謝樓主分享
回復

使用道具 舉報

25#
ID:202872 發(fā)表于 2020-9-29 16:15 | 只看該作者
知乎的網(wǎng)址打不開
回復

使用道具 舉報

26#
ID:202872 發(fā)表于 2020-9-29 17:28 | 只看該作者
原來的超過六個參數(shù)為啥不能用了
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久精品视频一区二区三区 | 久久国产成人 | 午夜精品三区 | 自拍偷拍在线视频 | 欧美中文一区 | 一区二区在线 | 久久久久国产精品 | 欧美日韩综合 | 日韩视频在线播放 | 精品欧美一区二区中文字幕视频 | 欧美一二三四成人免费视频 | 性欧美精品一区二区三区在线播放 | 久久国产精品视频 | 欧美成人在线影院 | 国产成人精品av | 欧美一区二区在线播放 | 国产区在线观看 | 超碰最新在线 | 亚洲综合视频一区 | 在线日韩欧美 | 奇米影视77 | 日日操夜夜摸 | jlzzjlzz欧美大全 | 午夜视频在线观看一区二区 | 日本不卡免费新一二三区 | 亚洲精品久久久久久国产精华液 | 可以在线看的黄色网址 | 97人人超碰 | 欧美中文字幕一区二区三区亚洲 | 国产毛片视频 | 精品视频在线免费观看 | 看片网站在线 | 国产一级片av | 日韩字幕| 国产三区精品 | 国产高清视频在线观看 | 国产91久久久久 | 一区二区在线免费观看 | 在线免费观看黄a | 国产91亚洲精品 | 在线观看av网站永久 |