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

这段代码是一个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. 编译通过后运行

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

4. 完整代码的github 连接

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

李沐机器学习系列2--- mlp

1 Introduction LP中有一个很强的假设&#xff0c;输入和输出是线性关系&#xff0c;这一般是不符合事实的。 通过几何的方式去对信息进行理解和压缩是比较高效的&#xff0c;MLP可以表示成下面的形式。 1.1 从线性到非线性 X ∈ R n d X \in R^{n \times d} X∈Rnd表示输入…

深信服技术认证“SCCA-C”划重点:云计算关键技术

为帮助大家更加系统化地学习云计算知识&#xff0c;高效通过云计算工程师认证&#xff0c;深信服特推出“SCCA-C认证备考秘笈”&#xff0c;共十期内容。“考试重点”内容框架&#xff0c;帮助大家快速get重点知识。 划重点来啦 *点击图片放大展示 深信服云计算认证&#xff08…

神经网络:经典模型热门模型

在这里插入代码片【一】目标检测中IOU的相关概念与计算 IoU&#xff08;Intersection over Union&#xff09;即交并比&#xff0c;是目标检测任务中一个重要的模块&#xff0c;其是GT bbox与pred bbox交集的面积 / 二者并集的面积。 下面我们用坐标&#xff08;top&#xff0…

电动汽车BMS PCB制板的技术分析与可制造性设计

随着电动汽车行业的迅猛发展&#xff0c;各大厂商纷纷投入巨资进行技术研发和创新。电动汽车的核心之一在于其电池管理系统&#xff08;Battery Management System, BMS&#xff09;&#xff0c;而BMS的心脏则是其印刷电路板&#xff08;PCB&#xff09;。通过这篇文章探讨电动…

Application layer

title: 应用层 date: 2023-12-20 21:03:48 tags: 知识总结 categories: 计算机网络 应用层&#xff1a;负责最直观的应用请求的封装、发起 一、域名系统DNS 连接在互联网上的主机不仅有IP地址&#xff0c;还有便于用户记忆的主机名字。域名系统DNS能够把互联网上的主机的名字…

Idea启动运行“错误:java: 无效的源发行版: 13”,如何解决?

以上是以JDK1.8的项目作为举例&#xff0c;如果您用的是其他版本请选择对应的language level idea中项目的language level的含义 language level指的是编译项目代码所用的jdk版本。那么&#xff0c;从这个定义出发会有两个小问题。 ❶ 如果project sdk是jdk8&#xff0c;那么la…

卡尔曼滤波算法

卡尔曼滤波算法是一种经典的状态估计算法&#xff0c;它广泛应用于控制领域和信号处理领域。在电动汽车领域中&#xff0c;卡尔曼滤波算法也被广泛应用于电池管理系统中的电池状态估计。其中&#xff0c;电池的状态包括电池的剩余容量&#xff08;SOC&#xff09;、内阻、温度等…

openGauss学习笔记-185 openGauss 数据库运维-升级-提交升级/升级版本回退/异常处理

文章目录 openGauss学习笔记-185 openGauss 数据库运维-升级-提交升级/升级版本回退/异常处理185.1 提交升级操作步骤 185.2 升级版本回滚操作步骤 185.3 异常处理升级问题FAQ openGauss学习笔记-185 openGauss 数据库运维-升级-提交升级/升级版本回退/异常处理 185.1 提交升级…

Swift并发的结构化编程

并发&#xff08;concurrency&#xff09; 早期的计算机 CPU 都是单核的&#xff0c;操作系统为了达到同时完成多个任务的效果&#xff0c;会将 CPU 的执行时间分片&#xff0c;多个任务在同一个 CPU 核上按时间先后交替执行。由于 CPU 执行速度足够地快&#xff0c;给人的错觉…

基于Java+SpringBoot+vue+elementUI私人健身教练预约管理系统设计实现

基于JavaSpringBootvueelementUI私人健身教练预约管理系统设计实现 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文章目录 基于JavaSpringBootvueelementUI私人健身教练预约管理系统设计实现一、前言介绍&#xff1a;二、系统设计&#xff1a;2.1 性能需求分析2.2 B/S架构&…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机掉线自动重连(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机掉线自动重连&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的掉线自动重连的技术背景通过PnP事件函数检查Baumer工业相机是否掉线在NEOAPI SDK里实现相机掉线重连方法&#xff1a;工业相机掉线重连测试演示图…

Python武器库开发-武器库篇之代理池配置(四十)

武器库篇之代理池配置(四十) 我们在渗透的过程中&#xff0c;是必须要挂代理的&#xff0c;相信为何要挂代理的原因&#xff0c;各位也是非常的明白的&#xff0c;这里就不多讲了。关于如何挂代理和购买代理大家可以去看内网隧道代理技术&#xff08;十&#xff09;之公网资产…

优雅地展示20w单细胞热图|非Doheatmap 超大数据集 细胞数太多

单细胞超大数据集的热图怎么画&#xff1f;昨天刚做完展示20万单细胞的热图要这么画吗&#xff1f; 今天就有人发消息问我为啥他画出来的热图有问题。 问题起源 昨天分享完 20万单细胞的热图要这么画吗&#xff1f;&#xff0c;就有人问为啥他的数据会出错。我们先来看下他的…

CMU15-445-Spring-2023-Project #0 - C++ Primer

前置任务。 Task #1 - Copy-On-Write Trie Copy-on-write (COW) Trie 在进行修改时&#xff0c;不会立即复制整个数据结构。相反&#xff0c;它会在需要修改的节点被多个引用的时候才进行复制。当要对某个节点进行写操作&#xff08;添加子节点或者继续向下insert&#xff09…

FLASH 闪存-stm32入门

本节我们学习的内容是 STM32 的 FLASH&#xff0c;闪存。 当然闪存是一个通用的名词&#xff0c;表示的是一种非易失性&#xff0c;也就是掉电不丢失的存储器。比如&#xff0c;我们之前学习 SPI 的时候&#xff0c;用的 W25Q64 芯片&#xff0c;就是一种闪存存储器芯片。 而…

【QML】与 C++ 混合编程:互相调用函数

文章目录 qml 调用 C 函数案例 a&#xff1a;Q_INVOKABLE 标记 C 函数 视图设置进 qml 属性案例 b&#xff1a;qml 通过发送信号的方式&#xff0c;调用 Qt 槽函数 C调用qml函数 qml 调用 C 函数 qml 要使用 C 的函数有两个方法&#xff1a; 一种是&#xff0c;用 Q_INVOKABLE…

守护进程“独辟蹊径”

守护进程“独辟蹊径” 一、前言二、实际运用2.1 知识介绍2.2 单机库场景应用2.2.1 配置dmwatcher.ini2.2.2 注册后台守护服务2.2.3 配置dmmal.ini2.2.4 配置归档和守护OGUID2.2.5 开启mal2.2.6 启动守护2.2.7 测试dmserver异常退出 三、总结 DM技术交流QQ群&#xff1a;9401242…

数据结构—环形缓冲区

写在前面&#xff0c;2023年11月开始进入岗位&#xff0c;工作岗位是嵌入式软件工程师。2024年是上班的第一年的&#xff0c;希望今年收获满满&#xff0c;增长见闻。 数据结构—环形缓冲区 为什么要使用环形数组&#xff0c;环形数组比起原来的常规数组的优势是什么&#xf…

Windows 10系统用Xlight FTP搭建SFTP服务器

步骤&#xff1a; 1.安装SFTP服务器 刚开始我使用的是freeSSHd&#xff0c;后面发现由于公司网络原因&#xff0c;打不开这个软件&#xff0c;改成了使用Xlight FTP&#xff0c; 官网下载链接&#xff1a;Xlight FTP 服务器 - 下载免费的windows FTP 服务器 Xlight FTP有30…

LocalSend 开源跨平台的局域网文件互传工具

如果您需要在多平台设备之间进行文件传输&#xff0c;例如从Windows电脑到安卓手机&#xff0c;或者从安卓手机到macOS&#xff0c;通常会使用聊天工具或者U盘进行传输。为了简化这一过程&#xff0c;推荐使用一款全平台支持的文件共享传输工具&#xff1a;LocalSend。 LocalS…