高斯滤波C++实现

文章介绍了高斯滤波的基本原理和作用,它是图像处理中用于消除高斯噪声的线性平滑方法。在点云数据处理方面,利用PCL库的GaussianKernel和GaussianFilter类可以实现高斯滤波。同时,文章还提供了使用OpenCV的GaussianBlur函数对图像进行高斯模糊处理的示例代码。此外,给出了一个C++程序,直接对TXT文件中的点云数据进行高斯滤波操作。
摘要由CSDN通过智能技术生成

1.高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

2.高斯滤波的具体操作是:用一个用户指定的模板(或称卷积、掩膜)去扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

1.通过pcl库实现

1.创建一个点云数据对象,如pcl::PointCloudpcl::PointXYZRGB对象。

2.将需要进行平滑的点云数据添加到点云数据对象中。

3.创建高斯滤波器对象,如pcl::GaussianKernel类或pcl::GaussianFilter类。

4.设置高斯滤波器的参数,如标准差、核大小等。

5.执行高斯滤波。

1.pcl::PointCloudpcl::PointXYZRGB::Ptr cloud(new pcl::PointCloudpcl::PointXYZRGB);     pcl::PointCloudpcl::PointXYZRGB::Ptr cloud_filtered(new pcl::PointCloudpcl::PointXYZRGB);

2.// 加载点云数据

pcl::io::loadPCDFilepcl::PointXYZRGB("cloud.pcd", cloud);

3.// 创建高斯滤波器

pcl::GaussianKernel<pcl::PointXYZRGB, pcl::PointXYZRGB> kernel; kernel.setInputCloud(cloud); kernel.setSigma(0.01);

4.// 创建高斯滤波对象

pcl::GaussianFilter<pcl::PointXYZRGB, pcl::PointXYZRGB> filter; filter.setKernel(kernel);

5.// 执行高斯滤波

filter.filter(cloud_filtered);

// 保存滤波后的点云数据

pcl::io::savePCDFilepcl::PointXYZRGB("cloud_gaussian_filtered.pcd", *cloud_filtered);

void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, intborderType=BORDER_DEFAULT)
    
int main() {
    Mat srcImage = imread("/Users/dwz/Desktop/cpp/1.jpg");
    Mat dstImage;
    GaussianBlur(srcImage, dstImage, Size(5, 5), 0, 0);
    imwrite("gaussianblured.jpg", dstImage);
    return 0;
}
  • 第一个参数:InputArray类型的src,输入图像,Mat类的对象。该函数对通道是独立处理的,且可以处理任意通道数的图像,但是待处理的图像深度应该是CV_8U,CV_16U,CV_16S,CV_32F,CV_64F。

  • 第二个参数:OutputArray类型的dst,目标图像,需要和输入图像有相同的尺寸和类型。

  • 第三个参数:Size类型的lsize,内核的大小。一般用Size(w,h)的写法表示,w和h可以不同,但是必须是正数和奇数,例如Size(3,3),Size(5,5)。

  • 第四个参数:double类型的sigmaX,表示高斯核函数在X方向上的标准偏差。

  • 第五个参数:double类型的sigmaY,表示高斯核函数在Y方向上的标准偏差。如果sigmaY是0,就将它设为sigmaX。如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。为了结果的正确性,最好是将Size、sigmaX、sigmaY全部指定到。

  • 第六个参数:int类型的borderType,用于推断图像外部像素的某种边界模式,默认值 BORDER_DEFAULT,我们一般不管它。

2.通过函数实现(可直接运行,处理的是txt文件,文件包含xyz坐标和rgb信息) 

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cmath>
#include <iomanip>

// 定义点云的数据结构,包含坐标和颜色信息
struct PointXYZRGB
{
    double x;
    double y;
    double z;
    int r;
    int g;
    int b;
};

// 高斯滤波函数,输入点云和标准差,输出滤波后的点云
std::vector<PointXYZRGB> applyGaussianFilter(const std::vector<PointXYZRGB>& inputCloud, double sigma)
{
    std::vector<PointXYZRGB> filteredCloud;

    int size = static_cast<int>(inputCloud.size());

    // 遍历每个点云
    for (int i = 0; i < size; ++i)
    {
        double sumX = 0.0;
        double sumY = 0.0;
        double sumZ = 0.0;
        int sumR = 0;
        int sumG = 0;
        int sumB = 0;
        double weightSum = 0.0;

        // 在窗口内计算加权平均值
        for (int j = -3; j <= 3; ++j)
        {
            int neighborIndex = i + j;
            if (neighborIndex < 0 || neighborIndex >= size)
                continue;

            double distance = static_cast<double>(j);
            double weight = exp(-distance * distance / (2 * sigma * sigma));

            sumX += inputCloud[neighborIndex].x * weight;
            sumY += inputCloud[neighborIndex].y * weight;
            sumZ += inputCloud[neighborIndex].z * weight;
            sumR += inputCloud[neighborIndex].r * weight;
            sumG += inputCloud[neighborIndex].g * weight;
            sumB += inputCloud[neighborIndex].b * weight;
            weightSum += weight;
        }

        // 计算滤波后的点的坐标和颜色值
        PointXYZRGB filteredPoint;
        filteredPoint.x = sumX / weightSum;
        filteredPoint.y = sumY / weightSum;
        filteredPoint.z = sumZ / weightSum;
        filteredPoint.r = sumR / weightSum;
        filteredPoint.g = sumG / weightSum;
        filteredPoint.b = sumB / weightSum;

        // 将滤波后的点添加到输出点云中
        filteredCloud.push_back(filteredPoint);
    }

    return filteredCloud;
}

int main()
{
    // 读取输入数据文件
    std::ifstream inputFile("input.txt");
    if (!inputFile.is_open())
    {
        std::cout << "无法打开输入文件!" << std::endl;
        return -1;
    }

    // 读取输入数据并存储为点云格式
    std::vector<PointXYZRGB> inputCloud;
    std::string line;
    while (std::getline(inputFile, line))
    {
        std::istringstream iss(line);
        PointXYZRGB point;
        // 从每行数据中解析出点的坐标和颜色信息
        if (!(iss >> std::setprecision(8) >> point.x >> point.y >> point.z >> point.r >> point.g >> point.b))
            break;

        // 将点添加到输入点云中
        inputCloud.push_back(point);
    }

    // 应用高斯滤波
    double sigma = 0.01; // 设置高斯滤波的标准差
    std::vector<PointXYZRGB> filteredCloud = applyGaussianFilter(inputCloud, sigma);

    // 保存滤波后的点云数据到文本文件
    std::ofstream outputFile("filtered.txt");
    if (!outputFile.is_open())
    {
        std::cout << "无法创建输出文件!" << std::endl;
        return -1;
    }

    // 将滤波后的点云数据写入输出文件
    for (const auto& point : filteredCloud)
    {
        // 设置输出流的精度为小数点后8位,并写入文件
        outputFile << std::fixed << std::setprecision(8) << point.x << " " << point.y << " " << point.z << " "
                   << point.r << " " << point.g << " " << point.b << std::endl;
    }
    outputFile.close();

    std::cout << "高斯滤波完成!" << std::endl;

    return 0;
}

/*
1.`std::fixed`和`std::setprecision(8)`是C++中用于控制输出流格式的操作符和函数。
2.`std::fixed`是一个输出流的格式标志,它指示浮点数以固定的小数位数格式输出。通常,浮点数默认使用科学计数法或自动切换为固定小数位数和科学计数法之间的格式,而使用`std::fixed`可以确保浮点数始终以固定的小数位数格式输出。
3.`std::setprecision(8)`是一个函数,它设置输出流的小数位数精度。在这里,`8`表示希望保留的小数位数。
4.在代码中,`std::fixed`和`std::setprecision(8)`被连续使用,表示将输出流的格式设置为固定的小数位数格式,并将小数位数精度设置为8位。这样做可以确保输出的浮点数保持固定的小数位数,并且保留了原始数据的精度。
*/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值