点云处理部分程序

这是pointcloudprocess.cpp程序中的pointfilter函数
用于对输入的一组点云数据进行处理,其中包括阈值分割(使用Otsu方法)和统计异常值移除(SOR)。

功能描述

源码解释

1. 函数参数:

const vector &inclouds:输入点云数据,其中pcXYZI似乎是一个自定义的结构,包含了XYZ坐标和强度信息。
vector &outSORclouds:用于存储SOR过滤后的点云数据的输出向量。
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 &inclouds, vector &outSORclouds, int N, int MeanK, double std)
{
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;

    }

}