基于Rangenet Lib的自动驾驶LiDAR点云语义分割与可视化

news2024/10/2 18:18:38

这段代码是一个C++程序,用于处理来自KITTI数据集的激光雷达(LiDAR)扫描数据。程序主要实现以下功能:

1. **读取和解析命令行参数**:使用Boost库中的`program_options`模块来定义和解析命令行参数。这包括扫描文件路径、模型路径以及是否启用详细模式(verbose)。

2. **处理KITTI数据集中的LiDAR扫描数据**:程序遍历指定KITTI数据集目录中的LiDAR扫描数据(`.bin`格式)。这些数据包含了LiDAR扫描的点云信息。

3. **LiDAR数据的语义分割**:使用`rangenet_lib`库创建一个网络模型来进行语义分割。这个库用于为LiDAR点云数据提供语义标签,例如将点分类为车辆、行人、道路等。

4. **读取和处理每个扫描文件**:对每个扫描文件,程序读取点云数据,并使用创建的网络模型进行推理(infer),得到每个点的语义标签。

5. **转换点云数据**:获取转换后的点云数据和颜色掩膜(color mask),这些颜色表示不同的语义类别。

6. **保存语义分割结果**:将每个点的坐标和对应的颜色标签保存到文本文件中。这些文件用于可视化或进一步分析处理。

7. **可视化(可选)**:如果启用了详细模式(verbose),则使用OpenCV的可视化工具(`cv::viz`)来显示语义分割后的点云。

总的来说,这个程序的主要作用是处理KITTI数据集中的LiDAR点云数据,通过使用语义分割网络对每个点进行分类,然后将分类结果保存并(可选地)进行可视化展示。这对于自动驾驶、机器人导航等领域的研究和应用是非常有用的。

1. infer中的内容 

/* Copyright (c) 2019 lifeiya, Chongqing University.
 *
 *  This file is part of advanced rangenet_lib.
 *
 */


// opencv stuff
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/viz.hpp>

// c++ stuff
#include <chrono>
#include <iomanip>  
#include <iostream>
#include <string>
#include <sstream>

// net stuff
#include <selector.hpp>
namespace cl = rangenet::segmentation;

// boost
#include <boost/program_options.hpp>
namespace po = boost::program_options;
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;

typedef std::tuple< u_char, u_char, u_char> color;


int main(int argc, const char *argv[]) {
  // define options
  std::string scan;
  std::string path;
  std::string backend = "tensorrt";
 // 如果verbose为true,则程序会输出更多的运行过程信息,如果为false,则只输出最基本的信息。
  bool verbose = false;
  std::ostringstream scanStream;

  std::string kitti_num = "10"; // Replace "01" with the actual value you want
  std::string base_path = "/home/fairlee/dataset/KITTI/sequences_kitti_00_21/" + kitti_num + "/velodyne/";
  std::string file_extension = ".bin";

 // Calculate the number of files in the directory
  int N = std::distance(fs::directory_iterator(base_path), fs::directory_iterator{});

for(int file_num = 1000; file_num < N; ++file_num) {



// cout<<"正在处理-----"<<file_num<<"/"<< N <<"数据"<<endl;

std::cout << std::left << "正在处理 " <<kitti_num<< " 数据集中的第: "<< file_num << " / "  << N << " 帧数据" << std::endl;


  // Parse options
  try {
    po::options_description desc{"Options"};
    desc.add_options()("help,h", "Help screen")(
        "scan,s", po::value<std::string>(&scan),
        "LiDAR scan to infer. No Default")(
        "path,p", po::value<std::string>(),
        "Directory to get the inference model from. No default")(
        "verbose,v", po::bool_switch(),
        "Verbose mode. Calculates profile (time to run)");

    po::variables_map vm;
    po::store(parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    std::cout << std::setfill('=') << std::setw(80) << "" << std::endl;

    if (vm.count("help")) {
      std::cout << desc << std::endl;
      return 0;
    }


 std::ostringstream scanStream;
    scanStream << base_path << std::setfill('0') << std::setw(6) << file_num << file_extension;
    scan = scanStream.str();

    // make defaults count, parameter check, and print
      path = "/home/fairlee/darknet53/";

    if (vm.count("verbose")) {
      verbose = vm["verbose"].as<bool>();
      std::cout << "verbose: " << verbose << std::endl;
    } else {
      std::cout << "verbose: " << verbose << ". Using default!" << std::endl;
    }

    std::cout << std::setfill('=') << std::setw(80) << "" << std::endl;
  } catch (const po::error &ex) {
    std::cerr << ex.what() << std::endl;
    return 1;
  }

  // create a network
  std::unique_ptr<cl::Net> net = cl::make_net(path, backend);

  // set verbosity
  net->verbosity(verbose);

  // predict each image
  std::cout << std::setfill('=') << std::setw(80) << "" << std::endl;
  std::cout << "Predicting image: " << scan << std::endl;

  // Open a scan
  std::ifstream in(scan.c_str(), std::ios::binary);
  if (!in.is_open()) {
      std::cerr << "Could not open the scan!" << std::endl;
      return 1;
  }

  in.seekg(0, std::ios::end);
  uint32_t num_points = in.tellg() / (4 * sizeof(float));
  in.seekg(0, std::ios::beg);

  std::vector<float> values(4 * num_points);
  in.read((char*)&values[0], 4 * num_points * sizeof(float));

  // predict
  std::vector<std::vector<float>> semantic_scan = net->infer(values, num_points);

  // get point cloud
  std::vector<cv::Vec3f> points = net->getPoints(values, num_points);

  // get color mask
  std::vector<cv::Vec3b> color_mask = net->getLabels(semantic_scan, num_points);


   // Create output filename
    std::ostringstream outfileNameStream;
    outfileNameStream << "/home/fairlee/dataset/KITTI/sequences_kitti_00_21/" << kitti_num << "/RangeNet_point/" << std::setfill('0') << std::setw(6) << file_num << ".txt";
    std::string outfileName = outfileNameStream.str();

    // Create an ofstream object
    std::ofstream outfile(outfileName);

    if (!outfile) {
        std::cerr << "Unable to open output file: " << outfileName << std::endl;
        return 1;
    }

    // Iterate through each point and corresponding color
    for (size_t i = 0; i < points.size(); ++i) {
        // Write the point coordinates and color to the file
        outfile << points[i][0] << " " << points[i][1] << " " << points[i][2];
        outfile << " " << static_cast<int>(color_mask[i][0]) << " " << static_cast<int>(color_mask[i][1]) << " " << static_cast<int>(color_mask[i][2]) << "\n";
    }

    // Close the file
    outfile.close();

 Create an ofstream object
//std::ofstream outfile("output.txt");
 Iterate through each point and corresponding color
//for (size_t i = 0; i < points.size(); ++i) {
//  // Write the point coordinates and color to the file
//  outfile << points[i][0] << " " << points[i][1] << " " << points[i][2];
//  outfile << " " << static_cast<int>(color_mask[i][0]) << " " << static_cast<int>(color_mask[i][1]) << " " << static_cast<int>(color_mask[i][2]) << "\n";
//}
 Close the file
//outfile.close();


  // print the output
  if (verbose) {
    cv::viz::Viz3d window("semantic scan");
    cv::viz::WCloud cloudWidget(points, color_mask);
    while (!window.wasStopped()) {
      window.showWidget("cloud", cloudWidget);
      window.spinOnce(30, true);
    }
  }
  std::cout << std::setfill('=') << std::setw(80) << "" << std::endl;

  std::cout << "Example finished! "<< std::endl;


}

  return 0;
}

2. 编译通过后运行

b46410bb5ee14d8aaaf35084b2ffcdb9.png

3. 运行结果(也可以保存为pcd)

1067427719ee40ff88e65a7a6de18a10.png

4. 完整代码的github 连接

https://github.com/RobotsRuning/RangeNet_ws/tree/main

9abadf6929094d108c5c8e7c99c34d43.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1362256.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

程序员副业之无人直播助眠

介绍和概览 大家好&#xff0c;我是小黑&#xff0c;本文给大家介绍一个比较轻松简单的副业&#xff0c;无人直播助眠副业。 这个项目的核心就是通过直播一些助眠素材来赚钱。比如你可以放一些舒缓的雨声之类的&#xff0c;吸引观众进来。然后&#xff0c;咱们可以挂个小程序…

K8Spod组件

一个pod能包含几个容器 一个pause容器(基础容器/父容器/根容器&#xff09; 一个或者多个应用容器(业务容器) 通常一个Pod最好只包含一个应用容器&#xff0c;一个应用容器最好也只运行一个业务进程。 同一个Pod里的容器都是运行在同一个node节点上的&#xff0c;并且共享 net、…

深度学习中的知识蒸馏

一.概念 知识蒸馏&#xff08;Knowledge Distillation&#xff09;是一种深度学习中的模型压缩技术&#xff0c;旨在通过从一个教师模型&#xff08;teacher model&#xff09;向一个学生模型&#xff08;student model&#xff09;传递知识来减小模型的规模&#xff0c;同时保…

了解Web 基础与 HTTP 协议

本章内容 了解静态网页与动态网页 理解 HTTP 协议的 GET 和 POST 方法 理解 HTTP 协议请求流程 随着互联网的高速发展&#xff0c;企业信息化应用大部分已采用网页的形式构建&#xff0c;掌握网页 的相关知识和 HTTP 的请求流程&#xff0c;是掌握互联网技术的第一步&#x…

分析C++软件问题的常用分析工具及案例集锦详解

目录 1、库依赖关系查看工具Dependency Walker 2、GDI对象查看工具GDIview 3、PE信息查看工具PeViewer/MiTeC EXE Explorer 4、进程信息查看工具Process Explorer 5、进程监控工具Process Monitor 6、API函数调用监测工具API Monitor C软件异常排查从入门到精通系列教程&…

聚道云软件连接器助力某半导体行业公司实现访客管理自动化

客户介绍&#xff1a; 某半导体行业公司是一家全球领先的半导体公司&#xff0c;在全球拥有众多研发中心和生产基地。该公司每天都有大量的访客来访&#xff0c;需要严格的访客管理制度。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 客户痛点&#…

报错处理:java.io.IOException: Could not find resource mybatis-config.xml

运行mybatis文件时出现了以下的情况 java.io.IOException: Could not find resource mybatis-config.xmlat org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:114)at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:100)at org.apach…

【数据库系统概念】第7-14章集合

文章目录 第七章 数据库设计和E-R模型&#xff08;重点&#xff01;&#xff01;&#xff01;&#xff09;~~7.1 设计过程概览&#xff08;了解&#xff09;~~7.1.1 设计阶段7.1.2 设计选择 7.2 实体-联系模型&#xff08;重点掌握&#xff09;7.2.1 实体集7.2.2 联系集联系集的…

Spring配置提示: File is included in 4 contexts

问题描述&#xff1a; spring配置文件上面提示&#xff1a; mvc application context in module studyDemo file is included in 4 contexts 导致原因&#xff1a;因为所有的配置文件都没有放在同一个上下文中 所谓File is included in 4 contexts是因为spring的配置文件放…

从vue小白到高手,从一个内容管理网站开始实战开发第六天,登录功能后台功能设计--API项目中的登录实现(二),工厂模式创建数据库连接

一、回顾 在第五天的时候我们开始创建后台所以需项目,并创建项目所需要的相关实体类,具体内容没有掌握的小伙伴可以看点击下面的链接去学习。 从vue小白到高手,从一个内容管理网站开始实战开发第六天,登录功能后台功能设计--API项目中的登录实现(一)-CSDN博客文章浏览阅读…

首次引入大模型!Bert-vits2-Extra中文特化版40秒素材复刻巫师3叶奈法

Bert-vits2项目又更新了&#xff0c;更新了一个新的分支&#xff1a;中文特化&#xff0c;所谓中文特化&#xff0c;即针对中文音色的特殊优化版本&#xff0c;纯中文底模效果百尺竿头更进一步&#xff0c;同时首次引入了大模型&#xff0c;使用国产IDEA-CCNL/Erlangshen-Megat…

H5通过getUserMedia拍照黑屏原因

项目需求背景&#xff1a;如同我上篇文章&#xff0c;https://blog.csdn.net/carfge/article/details/135417741 问题场景&#xff1a; 小米手机中访问H5&#xff0c;网页已获得摄像头授权&#xff08;左上角相机出现图标&#xff09;&#xff0c;但页面黑屏。 原因排查&#x…

docker 完成MySQL的主从复制

文章目录 搭建步骤 搭建步骤 拉取镜像 docker pull mysql:5.7运行主从 docker run -p 3307:3306 --name mysql-master -v /mydata/mysql-master/log:/var/log/mysql -v /mydata/mysql-master/data:/var/lib/mysql -v /mydata/mysql-master/conf:/etc/mysql -e MYSQL_ROOT_P…

【Spring Cloud】Nacos及Ribbon组件的使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Spring Cloud》。&#x1f3af;&#x1f3af; &am…

SQL Server 权限管理

CSDN 成就一亿技术人&#xff01; 2024年 第一篇 难度指数&#xff1a;* * CSDN 成就一亿技术人&#xff01; 目录 1. 权限管理 什么是权限管理&#xff1f; SQL server的安全机制 服务器级角色 数据库级角色 对象级角色 2. 创建用户 赋予权限 最重要的一步骤 1. 权限…

【信号处理:小波包转换(WPT)/小波包分解(WPD) 】

【信号处理&#xff1a;小波包转换&#xff08;WPT&#xff09;/小波包分解&#xff08;WPD&#xff09; 】 小波包变换简介WPT/WPD的基础知识WPT/WPD的主要特点The Wavelet Packet Transform 小波包变换前向小波数据包变换最佳基础和成本函数数学中波纹的最佳基础其他成本函数…

计算机中的数据运算

放上计算机中的数据的表示方法 计算机中的数据表示方法-CSDN博客 补码的运算&#xff1a; 连同符号位一起相加&#xff0c;符号位产生的进位自然丢掉&#xff0c;这里要特别注意机器数的位数&#xff0c;计算数的位数决定了可以存放的数据的大小&#xff0c;加减产生的数据的…

软件测试|Docker Kill/Pause/Unpause命令详细使用指南

简介 Docker是一种流行的容器化平台&#xff0c;提供了各种命令和功能来管理和操作容器。本文将详细介绍Docker中的三个重要命令&#xff1a;kill、pause和unpause。我们将深入了解它们的作用、用法和示例&#xff0c;帮助您更好地理解和使用这些命令。 什么是Docker Kill/Pa…

解决 Postman 报错问题:一份综合指南

Postman 是一个流行的 API 测试工具&#xff0c;它可以帮助开发者和测试人员快速地创建和发送各种 HTTP 请求&#xff0c;并查看响应结果。但是&#xff0c;在使用 Postman 的过程中&#xff0c;有时候会遇到一些报错或异常情况&#xff0c;影响了正常的测试流程。本文将介绍一…

MongoDB索引详解

概述 索引是一种用来快速查询数据的数据结构。BTree 就是一种常用的数据库索引数据结构&#xff0c;MongoDB 采用 BTree 做索引&#xff0c;索引创建 colletions 上。MongoDB 不使用索引的查询&#xff0c;先扫描所有的文档&#xff0c;再匹配符合条件的文档。使用索引的查询&…