点云各向异性扩散滤波

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

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

公式已贴图给出。

 

 

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/common/eigen.h>//eigen矩阵运算库
#include <math.h>

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

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

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

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

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

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

        if(kdtree.nearestKSearch(cloud_in->points[i],m,indices,dist)>0)
        {
            //将原点云按照索引值复制到近邻点云
            pcl::copyPointCloud(*cloud_in,indices,*neigh_cloud);
            
            //计算sigma
            float sigma = 0.0;
            vector<float> sm(0,0.0);
            for(int i=0;i<neigh_cloud->size();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;j<neigh_cloud->size();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<Eigen::Matrix3f> 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;
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
各向异性扩散滤波是一种常用于图像处理的算法,主要用于平滑图像和抑制噪声。这种滤波器会根据像素邻域内的信息(而不是简单地基于单个像素的值)来决定如何修改图像的每个像素。这允许滤波器更倾向于在空间中的某些方向(即所谓的“各向异性”)移动,而不仅仅是沿着像素边界。 在Python中,可以使用各种库来实现各向异性扩散滤波,例如OpenCV和scikit-image。以下是一个使用scikit-image库实现各向异性扩散滤波的基本示例: ```python from skimage import io, img_as_float from skimage.filters import gaussian from skimage.morphology import disk from skimage.util import random_checkerboard import numpy as np # 加载图像 image = img_as_float(io.imread('your_image_path.png')) # 设置扩散系数 sigma = 1.0 radius = int(sigma * 255) kernel = gaussian(radius=radius, sigma=sigma) # 创建一个随机混合的掩模,使其具有随机性,以避免模式识别问题 random_mask = random_checkerboard(size=(image.shape, image.shape), pattern_size=radius) # 使用滤波器对图像进行扩散处理 filtered_image = np.copy(image) filtered_image[random_mask != 0] = img_as_float(filter(kernel, image[random_mask != 0])) # 显示原始和滤波后的图像 fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 5)) ax.imshow(image, cmap='gray') ax[0].set_title('Original Image') ax.imshow(filtered_image, cmap='gray') ax.set_title('Filtered Image') plt.show() ``` 这段代码首先加载一张图像,然后使用一个高斯核作为扩散滤波器。这个滤波器会根据随机混合的掩模对图像进行扩散处理。掩模是一个大小与图像相同的数组,其中某些位置被设置为非零值(对应于需要扩散的像素)。然后,这些像素会被滤波器处理,而其他像素则保持不变。最后,原始和滤波后的图像都会显示出来。 请注意,这只是一种实现各向异性扩散滤波的方法,具体实现可能会因库和具体需求而异。此外,你可能需要根据你的具体应用调整扩散系数和其他参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值