(编程)点云地面分割——点云格网化

1.介绍

将点云格网化

读取每个格网内点云高程方向的统计特征,极值、均值、方差

判断与邻域内其他格网的相关性

例如均值之差<2cm等

2.代码

#include <string>
#include<iostream>
#include <cstdlib>
#include<fstream>
#include <sstream>	
#include <Eigen/Core>
#include <opencv2/opencv.hpp>
#include <pcl/io/ply_io.h>
#include<pcl/io/pcd_io.h>
#include<pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/console/parse.h>
#include <pcl/registration/icp.h>
#include <pcl/common/common.h> 
#include <pcl/filters/passthrough.h> 
#include <boost/thread/thread.hpp>
#include <pcl/filters/extract_indices.h>
#include <pcl/sample_consensus/ransac.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/segmentation/progressive_morphological_filter.h>

int main()
{
    /*读取点云文件*/
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    if (pcl::io::loadPCDFile<pcl::PointXYZ>("../data/subway.pcd", *cloud) == -1) 
    {
        PCL_ERROR("Couldn't read file\n");
        return(-1);
    }
    /*读取点云范围*/
    double x_min = 10000; double y_min = 10000;
    double x_max = 0; double y_max = 0;
    for (size_t i = 0; i < cloud->points.size(); ++i) 
    {
        if(cloud->points[i].x <= x_min) x_min = cloud->points[i].x;
        if(cloud->points[i].y <= y_min) y_min = cloud->points[i].y;
        if(cloud->points[i].x >= x_max) x_max = cloud->points[i].x;
        if(cloud->points[i].y >= y_max) y_max = cloud->points[i].y;
    }
    // cout << (int)x_min << "  ,  " << (int)y_min << endl;
    // cout << (int)x_max + 1 << "  ,  " << (int)y_max + 1 << endl;
    /*设置格网参数*/
    double pt0_x = (int)x_min; double pt0_y = (int)y_min;
    double pt1_x = (int)x_max + 1; double pt1_y = (int)y_max + 1;
    double grid_width = 0.05;
    int grid_num = (int) (pt1_x - pt0_x) / grid_width * (pt1_y - pt0_y) / grid_width;
    /*生成格网*/
    double grid[grid_num][5];
    for(int i = 0; i < grid_num; ++i)
    {
        int grid_num_y = (int) (pt1_y - pt0_y) / grid_width;
        int grid_num_x_i = (int) (i / grid_num_y);
        int grid_num_y_i = (int) (i - grid_num_x_i * grid_num_y);
        double i_y_start = grid_num_y_i * grid_width + pt0_y;
        double i_x_start = grid_num_x_i * grid_width + pt0_x;
        std::vector<double> grid_pt_z;
        int num_grid_pt_z = 0;
        for (size_t j = 0; j < cloud->points.size(); ++j) 
        {
           if(cloud->points[j].x <= i_x_start + grid_width && cloud->points[j].x >= i_x_start && cloud->points[j].y <= i_y_start + grid_width && cloud->points[j].y >= i_y_start)
           {
               grid_pt_z.push_back(cloud->points[j].z);
               num_grid_pt_z ++;
           }
        }
        if(num_grid_pt_z <= 1) continue;
        double z_sum = 0; double z_min = 10000; double z_max = 0;
        for(int k = 0; k < num_grid_pt_z; ++k)
        {
            z_sum = z_sum + grid_pt_z[k];
            if(grid_pt_z[k] > z_max) z_max = grid_pt_z[k];
            if(grid_pt_z[k] < z_min) z_min = grid_pt_z[k];
        }
        double z_avg = z_sum / num_grid_pt_z;
        double z_sig_sum = 0;
        for(int k2 = 0; k2 < num_grid_pt_z; ++k2) z_sig_sum = z_sig_sum + (grid_pt_z[k2] - z_avg) * (grid_pt_z[k2] - z_avg);
        double z_sig = z_sig_sum / num_grid_pt_z;
        grid[i][0] = num_grid_pt_z;
        grid[i][1] = z_max;
        grid[i][2] = z_min;
        grid[i][3] = z_avg;
        grid[i][4] = z_sig;
        grid_pt_z.clear();
    }
    /*判断地面*/
    pcl::PointCloud<pcl::PointXYZ> ground_cloud;
    for(int i = 0; i < grid_num; ++i)
    {
        int grid_num_y = (int) (pt1_y - pt0_y) / grid_width;
        if(i < grid_num_y) continue;
        if(i > grid_num - grid_num_y) continue;
        int mod_x = i - ((int) (i / grid_num_y)) * grid_num_y;
        if(mod_x == 0 || mod_x == grid_num_y - 1) continue;
        double z_avg_1 = grid[i][3];
        double z_avg_2 = grid[i - 1][3];
        double z_avg_3 = grid[i + 1][3];
        double z_avg_4 = grid[i - grid_num_y][3];
        double z_avg_5 = grid[i + grid_num_y][3];
        if(abs(z_avg_1 - z_avg_2) <= 0.02 && abs(z_avg_1 - z_avg_3) <= 0.02 && abs(z_avg_1 - z_avg_4) <= 0.02 && abs(z_avg_1 - z_avg_5) <= 0.02)
        {
            int x_num_i = (int) i / grid_num_y;
            int y_num_i = i -  (int) i / grid_num_y * grid_num_y;
            double x_start = x_num_i * grid_width + pt0_x;
            double y_start = y_num_i * grid_width + pt0_y;
            for (size_t j = 0; j < cloud->points.size(); ++j) 
            {
                if(cloud->points[j].x <= x_start + grid_width && cloud->points[j].x >= x_start && cloud->points[j].y <= y_start + grid_width && cloud->points[j].y >= y_start) ground_cloud.push_back(cloud->points[j]);
            }
        }
    }
    /*存储与显示*/
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("cloud show"));
    int v1 = 0;
    viewer->createViewPort(0, 0, 1.0, 1.0, v1);
    viewer->setBackgroundColor(255,255, 255, v1);
    viewer->setBackgroundColor(255,255, 255);
    pcl::PointCloud<pcl::PointXYZ>::Ptr g_cloud = ground_cloud.makeShared();
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> raw(cloud, 0, 0, 0);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> g_pt(g_cloud, 255,0, 0);
    viewer->addPointCloud(cloud, raw, "source cloud", v1);
    viewer->addPointCloud(g_cloud, g_pt, "select ground point", v1);
    // std::string path = "../ground.pcd";
    // pcl::io::savePCDFile(path, *g_cloud);
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(10000));
    }
    system("pause");
    return 0;
}

3.示例

(图中红色为地面点云)

  • 1
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
智慧校园整体解决方案是响应国家教育信息政策,结合教育改革和技术创新的产物。该方案以物联、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能络管理,促进个性学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息水平,而且优了教学和管理流程,为学生、教师和家长提供了更加便捷、个性的教育体验。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值