点云各向异性扩散滤波

参考论文:各向异性扩散滤波的三维散乱点云平滑去噪算法

博主学识尚浅,针对该算法实现了一半,现将已完成的算法(半成品)分享给大家,希望可以得到大家的帮助,其中对于I对x,y,z求偏导不知道如何进行编程。

公式已贴图给出。

点云各向异性扩散滤波_第1张图片

 

点云各向异性扩散滤波_第2张图片

点云各向异性扩散滤波_第3张图片 

#include 
#include 
#include 
#include 
#include 
#include //eigen矩阵运算库
#include 

using namespace std;
using pointT = pcl::PointXYZ;

int main()
{
    //定义超参数
    int m = 16, k = 10, tao = 1;//k近邻个数,迭代次数,时间间隔
    float alpha = 0.005;//扩散因子

    pcl::PointCloud::Ptr cloud_in(new pcl::PointCloud);
    //加载点云
    pcl::io::loadPCDFile("", *cloud_in);

    if (!cloud_in->size())
        return 0;

    //创建kdtree
    pcl::KdTreeFLANN kdtree;//定义kdtree
    kdtree.setInputCloud(cloud_in);

    //循环处理每一个点
    for(size_t i=0;isize();i++)
    {
        vector indices(0,0);//初始化索引
        indices.reserve(m);
        vector dist(0,0.0);//初始化距离
        dist.reserve(m);
        pcl::PointCloud::Ptr neigh_cloud(new pcl::PointCloud);

        if(kdtree.nearestKSearch(cloud_in->points[i],m,indices,dist)>0)
        {
            //将原点云按照索引值复制到近邻点云
            pcl::copyPointCloud(*cloud_in,indices,*neigh_cloud);
            
            //计算sigma
            float sigma = 0.0;
            vector sm(0,0.0);
            for(int i=0;isize();i++)
            {
                sm.push_back(dist[i]);
                sigma += dist[i];
            }
            sigma =sigma / m;

            //计算张量投票矩阵
            Eigen::Matrix3f T;
            //创建单位矩阵
            Eigen::Matrix3f T3 = Eigen::Matrix3f::Identity();
            for(int j=0;jsize();j++)
            {
                float temp = - (pow(sm[i],2) / pow(sigma,2));
                float um = exp(temp); 
                Eigen::Vector3f vm;
                vm(0) = cloud_in->points[i].x - neigh_cloud->points[j].x;
                vm(1) = cloud_in->points[i].y - neigh_cloud->points[j].y;
                vm(2) = cloud_in->points[i].z - neigh_cloud->points[j].z;
                
                T += um * (T3 - (vm * vm.transpose()) / (vm * vm.transpose()).squaredNorm());
            }

            //计算T的特征值和特征向量
            Eigen::SelfAdjointEigenSolver es(T);
            Eigen::Vector3f lambda = es.eigenvalues();
            Eigen::Matrix3f E = es.eigenvectors();

            //计算扩散张量
            float u1,u2,u3;
            float k12,k13,k23;

            k12 = pow((lambda(0)-lambda(1)),2);
            k13 = pow((lambda(0)-lambda(2)),2);
            k12 = pow((lambda(1)-lambda(2)),2);

            u1 = alpha;
            if(k12 == 0)
            {
                u2 = alpha;
            }
            else
            {
                u2 = alpha + (1-alpha) * exp(-(1/k12));
            }

            if(k23 == 0)
            {
                u3 = u2;
            }
            else
            {
                u3 = u2 + (1-u2) * exp(-(1/k23));
            }

            Eigen::Vector3f e1 = E.col(0);//第一个特征向量
            Eigen::Vector3f e2 = E.col(1);//第二个特征向量
            Eigen::Vector3f e3 = E.col(2);//第三个特征向量

            //计算扩散张量D的系数
            float d11 = u1 * pow(e1(0),2) + u2 * pow(e1(1),2) + u3 * (e1(2),2);
            float d22 = u1 * pow(e2(0),2) + u2 * pow(e2(1),2) + u3 * (e2(2),2);
            float d33 = u1 * pow(e3(0),2) + u2 * pow(e3(1),2) + u3 * (e3(2),2);
            float d12 = u1 * e1(0) * e2(0) + u2 * e1(1) * e2(1) + u3 * e1(2) * e2(2);
            float d13 = u1 * e1(0) * e3(0) + u2 * e1(1) * e3(1) + u3 * e1(2) * e3(2);
            float d23 = u1 * e2(0) * e3(0) + u2 * e2(1) * e3(1) + u3 * e2(2) * e3(2);

            Eigen::Matrix3f D;
            D << d11,d12,d13,
                 d12,d22,d23,
                 d13,d23,d33;
            
            //计算I的导数
            

        }

    }


    return 0;
}

 

 

 

你可能感兴趣的:(点云,PCL,图像处理)