基于异常点检测算法(一)概率统计的原理地址是https://blog.csdn.net/yangziluomu/article/details/73528080
下面是用C++实现了基于正态分布的多元离群点的检测方法
/*-------------------------------------
1.基于正态分布的点云离群点检测算法
2.作者:pcb
3.日期:2018.10.3
--------------------------------------*/
//定义3D点的结构体
struct Point3D
{
float x;
float y;
float z;
};
/*----------------------------
*功能:采用高斯分布的方法进行离群点的判别
*-----------------------------
*输入:InputPointCloud(Piont3D的原始点云数据)
*输出:OutPointCloud(除去离群点之后的Point3D结构的点云数据)
*/
void GaussianDistribution_OutlierDetection(vector<Point3D> &InputPointCloud, vector<Point3D>&OutPointCloud)
{
//均值
double X_Ave = 0;
double Y_Ave = 0;
double Z_Ave = 0;
//方差
double X_Var = 0;
double Y_Var = 0;
double Z_Var = 0;
//求均值
for (int i = 0; i <InputPointCloud.size(); i++)
{
X_Ave +=InputPointCloud[i].x;
Y_Ave +=InputPointCloud[i].y;
Z_Ave +=InputPointCloud[i].z;
}
X_Ave = X_Ave /InputPointCloud.size();
Y_Ave = Y_Ave /InputPointCloud.size();
Z_Ave = Z_Ave /InputPointCloud.size();
//求方差
for (int j = 0; j <InputPointCloud.size(); j++)
{
X_Var += (InputPointCloud[j].x - X_Ave)*(InputPointCloud[j].x - X_Ave);
Y_Var += (InputPointCloud[j].y - Y_Ave)*(InputPointCloud[j].y - Y_Ave);
Z_Var += (InputPointCloud[j].z - Z_Ave)*(InputPointCloud[j].z - Z_Ave);
}
X_Var = X_Var /InputPointCloud.size();
Y_Var = Y_Var /InputPointCloud.size();
Z_Var = Z_Var /InputPointCloud.size();
//开始判断是是否是离群点,中间的阈值可以针对实际情况调整
for (int k = 0; k <InputPointCloud.size(); k++)
{
if (((abs(InputPointCloud[k].z - Z_Ave) / sqrt(Z_Var))<1.5 || (abs(InputPointCloud[k].z + Z_Ave) / sqrt(Z_Var))<1.5)
&& ((abs(InputPointCloud[k].y - Y_Ave) / sqrt(Y_Var))<1.8 || (abs(InputPointCloud[k].y + Y_Ave) / sqrt(Y_Var))<1.8)
&& ((abs(InputPointCloud[k].x - X_Ave) / sqrt(X_Var))<1.8 || (abs(InputPointCloud[k].x + X_Ave) / sqrt(X_Var))<1.))
{
OutPointCloud.push_back(InputPointCloud[k]); //如果不是离群点,则把该点放入CloudPoint中
}
}
return;
}