三维视觉——使用PCL对点云进行条件分离(C++版)

在我们平时对点云的处理中,常常需要将整体点云中满足不同条件或要求的点云进行分离,再分别做不同的操作。所以,今天分享一下点云的条件分离。因为大家的需求不一,所以,这里我就用XYZRGB的格式去介绍了(这种格式的点云更加直观),类似的XYZ、XYZRGBA等等原理都是相通的,没什么区别。

使用颜色信息,我们就可以根据颜色值的不同,根据色彩值对点云进行分离。类似的,XYZ格式的可以通过坐标范围,对点云进行分离,以此联想类推。

这里使用三种不同的方式来对点云进行分离操作,就是想法思路的不同,就是可以多多发散思路,完成目标。

方式一:根据色彩值筛选,分离点云

#include <iostream>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/extract_indices.h>

int main() {
    // 读取点云文件
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    if (pcl::io::loadPLYFile<pcl::PointXYZRGB>("input.ply", *cloud) == -1) {
        std::cerr << "Failed to open input.ply" << std::endl;
        return -1;
    }

    // 创建提取器和索引容器
    pcl::PointIndices::Ptr redIndices(new pcl::PointIndices);
    pcl::PointIndices::Ptr blueIndices(new pcl::PointIndices);

    // 分离不同颜色的点云
    for (size_t i = 0; i < cloud->size(); ++i) {
        pcl::PointXYZRGB& point = cloud->at(i);
        if (point.r == 255 && point.g == 0 && point.b == 0)
            redIndices->indices.push_back(i);
        else if (point.r == 0 && point.g == 0 && point.b == 255)
            blueIndices->indices.push_back(i);
    }

    // 创建红色点云并保存为新的ply文件
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr redCloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    pcl::ExtractIndices<pcl::PointXYZRGB> extractRed;
    extractRed.setInputCloud(cloud);
    extractRed.setIndices(redIndices);
    extractRed.filter(*redCloud);
    pcl::io::savePLYFileBinary("red_points.ply", *redCloud);

    // 创建蓝色点云并保存为新的ply文件
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr blueCloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    pcl::ExtractIndices<pcl::PointXYZRGB> extractBlue;
    extractBlue.setInputCloud(cloud);
    extractBlue.setIndices(blueIndices);
    extractBlue.filter(*blueCloud);
    pcl::io::savePLYFileBinary("blue_points.ply", *blueCloud);

    std::cout << "Red points saved as red_points.ply" << std::endl;
    std::cout << "Blue points saved as blue_points.ply" << std::endl;

    return 0;
}

方式二:创建滤波器分离点云

#include <iostream>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>

int main() {
    // 读取ply文件
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    if (pcl::io::loadPLYFile<pcl::PointXYZRGB>("input.ply", *cloud) == -1) {
        std::cerr << "Failed to open input.ply" << std::endl;
        return -1;
    }

    // 创建红色和蓝色滤波器
    pcl::PassThrough<pcl::PointXYZRGB> redFilter;
    pcl::PassThrough<pcl::PointXYZRGB> blueFilter;

    // 设置滤波器参数
    redFilter.setInputCloud(cloud);
    redFilter.setFilterFieldName("r");
    redFilter.setFilterLimits(1, 255);
    redFilter.setNegative(true); // 保留非红色点云

    blueFilter.setInputCloud(cloud);
    blueFilter.setFilterFieldName("b");
    blueFilter.setFilterLimits(1, 255);
    blueFilter.setNegative(true); // 保留非蓝色点云

    // 执行滤波操作
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr filteredCloud(new                     
    pcl::PointCloud<pcl::PointXYZRGB>);
    redFilter.filter(*filteredCloud);
    blueFilter.filter(*filteredCloud);

    // 保存滤波后的点云到新的ply文件
    pcl::io::savePLYFileBinary("filtered_points.ply", *filteredCloud);

    std::cout << "Filtered points saved as filtered_points.ply" << std::endl;

    return 0;
}

方式三:反向分离

#include <iostream>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>

int main() {
    // 读取ply文件
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    if (pcl::io::loadPLYFile<pcl::PointXYZRGB>("input.ply", *cloud) == -1) {
        std::cerr << "Failed to open input.ply" << std::endl;
        return -1;
    }

    // 创建滤波器
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr filteredCloud(new 
    pcl::PointCloud<pcl::PointXYZRGB>);

    // 遍历点云,将非红色和非蓝色点云加入到滤波器输出
    for (size_t i = 0; i < cloud->size(); ++i) {
        pcl::PointXYZRGB& point = cloud->at(i);
        if (!(point.r == 0 && point.g == 0 && point.b == 255) && !(point.r == 255 && point.g == 0 && point.b == 0)) {
            filteredCloud->push_back(point);
        }
    }

    // 保存滤波后的点云到新的ply文件
    pcl::io::savePLYFileBinary("filtered_points.ply", *filteredCloud);

    std::cout << "Filtered points saved as filtered_points.ply" << std::endl;

    return 0;
}

以上就是在XYZRGB格式下的点云分离(其他格式下的点云也是一样的),希望可以给到大家一点帮助。

草稿代码可能不是那么严谨,但运行起来问题不大。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值