首页 > 编程知识 正文

均方根值计算公式,mse均方误差计算公式

时间:2023-05-03 20:20:16 阅读:144268 作者:882

为了理解RMSE,首先介绍统计学的概念,

其次,介绍SLAM领域的计算精度ATE和RPE的使用方法。 中值数据组按大小顺序排列,最中间的一个数据(如果有偶数个数据,则为最中间两个数据的平均值)称为中值。

使用中值作为数据组的代表,可靠性不高,但受极端数据影响的可能性较低,有利于表现该数据组的“集中倾向”。

在众数组的数据中出现次数最多的数据称为众数。

使用众数作为一组数据的代表,虽然可靠性低,但众数不受极端数据的影响,且求解方法简单。 在一组数据中个别数据变动较大的情况下,选择众数来表示这一组数据的“集中倾向”比较合适。

平均数是一组数据之和除以这一组数据的个数所得的商,反映一组数的总体情况比中位数、众数更可靠、稳定。

方差(variance )方差是与各数据平均值的偏差的平方和的平均值。

方差用于测量随机变量与其数学期望(即平均值)的偏离程度。

标准偏差(均方误差)标准偏差(也称为均方误差)的平方是方差。

标准差反映一个数据集的离散度。 也就是说,它被理解为数据集波动的大小。

方差与我们处理的数据的维度不一致。 单位不一致。 虽然数据和平均的偏差程度可以很好地记述,但是处理结果不符合我们的直觉思维。

均方误差MSE(meansquarederror,均方误差)一般来说,方差是数据序列与平均值的关系,均方误差是数据序列与真值的关系,需要注意区分真值与平均值的关系。 均方差(MSE )是各数据与真值的差的平方和的均方差是平均值,均方差是真值。

均方根误差RMSE (均方根)均方根也被称为标准误差,

均方误差是各数据偏离真值的差分的平方和的平均,即误差的平方和的平均,均方根误差在形式上接近标准偏差。

举个例子吧。 测量房间的温度。 很遗憾温度计的精度不高。

因此,需要测量5次,得到一系列数据[x1、x2、x3、x4、x5]。

设温度的真值为x,则数据和真值之间的误差e=x-xi。 均方误差和均方根误差可以求出。 一般来说,均方误差(标准偏差)是数据序列与平均值的关系,均方根误差是数据序列与真值的关系。 因此,标准差用于测量一组数本身的离散度,均方根误差用于测量观测值与真值的偏差,研究对象和研究目的不同,但计算过程相似。

协方差/标准差描述了一维数据集合的离散度,但一般情况下,世界现象是用多维数据描述的,自然会考虑现象和数据的关联度,以及各维之间的关联度。

例如,一个产品能否畅销是由产品的质量、价格等多个要素构成的。 价格质量有相关性吗? 这个问题可以用协方差来解决。

向量范数可以从函数、几何、矩阵的角度理解范数。

众所周知,函数与几何图形有对应关系。 这很好想象。 特别是在三维以下空间中,函数是几何图像的数学概括,几何图像是函数的高级图像化,例如一个函数是与几何空间上的几个点相对应地构成的图形。

但是,如果函数和几何学超过三维空间,就很难得到好的想象,就有了映射的概念,映射表示就是以一种集合的关系转换成另一种集合。 通常,数学书先说映射,然后讨论函数。 这是因为函数是映射的特例。

为了更数学地表达这种映射关系,引入了矩阵。 这里的矩阵是表示上述空间映射的线性关系。 用向量表示上述映射中的这个集合,我们一般说的基底是这个集合最常见的关系。

于是,可以理解为一个集合(向量)通过一个映射关系(矩阵)得到了另一个集合)。

那么向量的范数表示这个原始集合的大小。

的范数表示该变化过程大小的测量值。

简单地说:

范数0表示向量中非零元素的数量,即稀疏性。

1范数表示为绝对值之和。 2范数是指模型。

经过前面的铺垫,成为了真正的大规模BOOSate。 absolutetrajectoryerror绝对轨迹误差绝对轨迹误差可以直接计算摄像机姿态真值与SLAM系统估计值之间的差值,非常直观地反应算法的精度和轨迹的全局一致性。

应该注意的是,由于估计姿势和groundtruth通常不在同一坐标系中,所以程序首先根据姿势的时间戳对真值和估计值进行对位,然后计算各对位姿势之间的差分,最终作为图表输出。 该标准最适合评价视觉SLAM系统的性能。

在双目SLAM和RGB-D SLAM中,由于尺度统一,所以需要用最小二乘法计算从估计姿势到真实姿势的变换矩阵SE3;

在单眼摄像机中,由于存在尺度不确定性,所以需要计算从估计姿势向真姿势的相似变换矩阵sim

3 。

ATE-all RMSE

ATE-all实际上是每个位姿李代数的均方根误差RMSE(Root Mean Squard Error)。这种误差可以刻画两条轨迹的旋转和平移误差。

ATE-trans RMSE

ATE-trans仅考虑平移误差的情况,trans表示取括号内部标量的平移部分,因为从整条轨迹上看,旋转出现误差后,随后的平移上会出现误差,所以这两种指标在实际中都适用。

RPE:relative pose error 相对位姿误差

相对位姿误差主要描述的是相隔固定时间差两帧位姿差的精度(相比真实位姿),相当于直接测量里程计的误差。

当然也有人不用RMSE,直接使用平均值、甚至中位数来描述相对误差情况。

需要注意的是,RPE包含两部分误差,分别是旋转误差和平移误差,通常使用平移误差进行评价已经足够,但是如果需要,旋转角的误差也可以使用相同的方法进行统计。

RPE-all RMSE

RPE-trans RMSE

源码解读 #include #include #include #include #include using namespace Sophus;using namespace std;// 更高精度的轨迹 作为你真实轨迹string groundtruth_file = "/home/projects/sophus/trajectoryError/groundtruth.txt";// 算法计算出来的轨迹string estimated_file = "/home/projects/sophus/trajectoryError/estimated.txt";// Twc 的平移部分构成了机器人的轨迹// aligned_allocator管理C++中的各种数据类型的内存方法是一样的// 在C++11标准中,一般情况下定义容器的元素都是C++中的类型,// 在Eigen管理内存和C++11中的方法不一样,需要单独强调元素的内存分配和管理typedef vector<:se3d eigen::aligned_allocator>> TrajectoryType;TrajectoryType ReadTrajectory(const string &path);void DrawTrajectory(const TrajectoryType &gt, const TrajectoryType &esti);int main(int argc, char **argv) { TrajectoryType groundtruth = ReadTrajectory(groundtruth_file); TrajectoryType estimated = ReadTrajectory(estimated_file); assert(!groundtruth.empty() && !estimated.empty()); assert(groundtruth.size() == estimated.size()); // compute rmse 位姿的均方根误差 // ATE double rmse = 0; for (size_t i = 0; i < estimated.size(); i++) { Sophus::SE3d p1 = estimated[i], p2 = groundtruth[i]; // 李群SE3的对数映射求李代数se3 // 对应视觉SLAM十四讲第二版p89 公式4.44    // .norm();代表二范数的计算过程 double error = (p2.inverse() * p1).log().norm(); rmse += error * error; } rmse = rmse / double(estimated.size()); rmse = sqrt(rmse); cout << "RMSE = " << rmse << endl; DrawTrajectory(groundtruth, estimated); return 0;}TrajectoryType ReadTrajectory(const string &path) { ifstream fin(path); TrajectoryType trajectory; if (!fin) { cerr << "trajectory " << path << " not found." << endl; return trajectory; } while (!fin.eof()) { double time, tx, ty, tz, qx, qy, qz, qw; // tx ty tz 为Twc的平移部分 // qx qy qz qw 是四元数表示的 Twc的旋转部分 qw 是四元数的实部 fin >> time >> tx >> ty >> tz >> qx >> qy >> qz >> qw; // 四元数和平移向量构造李群SE3变换矩阵 Sophus::SE3d p1(Eigen::Quaterniond(qw, qx, qy, qz), Eigen::Vector3d(tx, ty, tz)); trajectory.push_back(p1); } return trajectory;}void DrawTrajectory(const TrajectoryType &gt, const TrajectoryType &esti) { // create xndpd window and plot the trajectory xndpd::CreateWindowAndBind("Trajectory Viewer", 1024, 768); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); xndpd::OpenGlRenderState s_cam( xndpd::ProjectionMatrix(1024, 768, 500, 500, 512, 389, 0.1, 1000), xndpd::ModelViewLookAt(0, -0.1, -1.8, 0, 0, 0, 0.0, -1.0, 0.0) ); xndpd::View &d_cam = xndpd::CreateDisplay() .SetBounds(0.0, 1.0, xndpd::Attach::Pix(175), 1.0, -1024.0f / 768.0f) .SetHandler(new xndpd::Handler3D(s_cam)); while (xndpd::ShouldQuit() == false) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); d_cam.Activate(s_cam); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glLineWidth(2); for (size_t i = 0; i < gt.size() - 1; i++) { glColor3f(0.0f, 0.0f, 1.0f); // blue for ground truth glBegin(GL_LINES); // 轨迹就是平移向量 auto p1 = gt[i], p2 = gt[i + 1]; glVertex3d(p1.translation()[0], p1.translation()[1], p1.translation()[2]); glVertex3d(p2.translation()[0], p2.translation()[1], p2.translation()[2]); glEnd(); } for (size_t i = 0; i < esti.size() - 1; i++) { glColor3f(1.0f, 0.0f, 0.0f); // red for estimated glBegin(GL_LINES); auto p1 = esti[i], p2 = esti[i + 1]; glVertex3d(p1.translation()[0], p1.translation()[1], p1.translation()[2]); glVertex3d(p2.translation()[0], p2.translation()[1], p2.translation()[2]); glEnd(); } xndpd::FinishFrame(); usleep(5000); // sleep 5 ms  }}

交流答疑微信群

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。