点云处理部分程序
这是pointcloudprocess.cpp程序中的pointfilter函数
用于对输入的一组点云数据进行处理,其中包括阈值分割(使用Otsu方法)和统计异常值移除(SOR)。
功能描述
源码解释
1. 函数参数:
const vector
vector
int N:用于Otsu方法的参数,表示直方图的分段数。
int MeanK:SOR滤波的参数,表示考虑邻域内点的数量。
double std:SOR滤波的参数,表示标准差。
2. 初始化输出向量:
创建了一个名为outclouds的局部向量,用于存储Otsu方法阈值分割后的点云数据。
调整了outclouds和outSORclouds的大小以匹配输入点云数据的数量。
3. 使用Otsu方法进行阈值分割:
对输入点云中的每个点云数据进行循环(使用OpenMP进行多线程并行处理)。
为每个点云数据提取强度值,并计算最大强度值(intensitymax)。
创建直方图并计算直方图中的每个分段的频率。
使用Otsu方法来找到一个阈值,以便将点分为两个组。
根据阈值将点分为两组:大于阈值的点存储在outclouds[i]中。
4. 使用SOR(统计异常值移除):
对通过Otsu方法分割的点云数据(outclouds[i])应用SOR滤波。
SOR滤波的结果存储在outSORclouds[i]中。
5. 输出
最后,函数循环结束后,outSORclouds中将包含经过Otsu方法和SOR滤波处理的点云数据,这些数据不包含强度值超过阈值或者被认为是异常值的点。
总结:这段代码通过Otsu方法将输入点云分割为两组,并使用SOR滤波方法进一步处理,以去除异常值。这是一个在计算机视觉和点云处理中常见的预处理步骤,用于提取感兴趣的点云部分并去除噪声。
源码
void Csegmentation::cloudFilter(const vector
{
int cloudnumber = inclouds.size();
cout<< “Candidate segement number: “<< cloudnumber<<endl;
vector<pcXYZI> outclouds;
outclouds.resize(cloudnumber);
outSORclouds.resize(cloudnumber);
//Otsu method thresholding
int i;
//#pragma omp parallel for private(i) //Multi-thread
for (i = 0; i < cloudnumber; i++)
{
//store intensity [integer]
//存储每个点的intensity数据
vector<int> intensitylist;
int pointnumber = inclouds[i].size();
intensitylist.resize(pointnumber);
for (int j = 0; j < pointnumber; j++)
{
intensitylist[j] = inclouds[i].points[j].intensity;
}
int intensitymax, intensitymin;
intensitymax = *(max_element(intensitylist.begin(), intensitylist.end()));
//intensitymin = *(min_element(intensitylist.begin(), intensitylist.end()));
//OTSU Method
//Define Histogram
vector<int> h0;
vector<float> h;
h0.resize(N);
h.resize(N);
for (int k = 0; k < N; k++) h0[k] = 0;
//generate histogram
for (int j = 0; j < pointnumber; j++)
{
int bin = (N - 1) * intensitylist[j] / intensitymax;
h0[bin]++;
}
for (int k = 0; k < N; k++)
{
h[k] = (float)h0[k] / pointnumber;
}
int threshold = 0;
float w0, w1, u0tmp, u1tmp, u0, u1, u, deltaTmp, deltaMax = 0;
for (int k = 0; k < N; k++)
{
w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;
for (int t = 0; t < N; t++)
{
if (t <= k)
{
w0 += h[t];
u0tmp += t * h[t];
}
else
{
w1 += h[t];
u1tmp += t * h[t];
}
}
u0 = u0tmp / w0;
u1 = u1tmp / w1;
u = u0tmp + u1tmp;
deltaTmp = w0 * (u0 - u)*(u0 - u) + w1 * (u1 - u)*(u1 - u);
if (deltaTmp > deltaMax)
{
deltaMax = deltaTmp;
threshold = k;
}
}
//cout << "Threshold : "<<threshold<< endl;
for (int j = 0; j < pointnumber; j++)
{
int bin = (N - 1) * intensitylist[j] / intensitymax;
if (bin > threshold)
{
outclouds[i].push_back(inclouds[i].points[j]);
}
}
//cout << "Cloud " << i << " 's number after Otsu Thresholding is: " <<outclouds[i].size()<< endl;
//SOR: Statistics Outlier Remover
SORFilter(outclouds[i], outSORclouds[i], MeanK, std);
//cout << "Cloud " << i << " 's number after SOR is: " <<outclouds[i].size()<< endl;
}
}