全流程点云机器学习(一)使用CloudCompare自制sharpNet数据集

前言

这不是高支模项目需要嘛,他们用传统算法切那个横杆竖杆流程复杂耗时很长,所以想能不能用机器学习完成这些工作,所以我就来整这个工作了。

工欲善其事,必先利其器,在正式开始之前,我们先要搞懂如何切分数据集。

本系列文章所用的核心骨干网络代码主要来自点云处理:实现PointNet点云分割

使用的数据集类型主要为SharpNet,这篇文章里主要是讲如何使用CC切出指定的对象,并将其转换成我们想要的SharpNet数据集。

之后可能写一个番外,简单说说如何使用semantic-segmentation-editor工具进行简单的点云分割和解析吧,最近也摸了一下,但是发现这个工具貌似没有CC好用。

如果有人问起再写吧,有点折腾,不过也还好。

什么是SharpNet数据集?

我们可以在 LARGE-SCALE 3D SHAPE RECONSTRUCTION AND SEGMENTATION
FROM SHAPENET CORE55网站上下载到SharpNet的数据集和标签,我们下载下来解压看看里面的结构
在这里插入图片描述
以下是训练集点云文件组
在这里插入图片描述
在这里插入图片描述

以下是训练集点云的标签组

也就是说实际上是一个pts文件对应一个.seg文件。

其中pts文件好理解,就是一个个的明文点云,内容如下:

在这里插入图片描述

打开seg文件,里面行数和同名的pts文件行数相同,

在这里插入图片描述

这个.seg文件中代表的意思就是对应行数的点所对应的label标签,通常以一个数字来表示,比如1是背景,2,3,4代表各种各样的对象,具体每个数字对应的对象是什么。

如何标注点云文件

上文中简单说了下SharpNet的规则,那么本章就简单说说如何标注点云文件

主要可以参考这篇文章,我这里仅展示简单的流程:

如何利用CloudCompare软件进行点云数据标注

比如我现在有一个这样的高支模点云,如果我想要做一个横杆的检测,那么我们就需要把横杆全部截出来

1.切割

在这里插入图片描述

先点击需要切片的点云文件,然后点这个剪刀进入剪切模式
在这里插入图片描述
先用左键划线工具框选住一个横杆,选完了之后单击右键确定选框,这个时候点击这个红色的多边形(选中框选内容)完成切割,再点击右边的这个绿色勾

在这里插入图片描述
在这里插入图片描述

这个时候切片就切出来了,可以看看效果

在这里插入图片描述

在这里插入图片描述

2. 分类

完成了切割工作之后,要给这个切出来的片加上一个名字,就点上面这个加号,然后给定一个对象的名称,再给定一个值

在这里插入图片描述
我们切分的是水平支撑,那么就给它起个名字叫Support

在这里插入图片描述

至于值的话随便声明就行,无所谓,这里声明的是1.00,这个和后面的处理有关,当然了你不懂也无所谓,如果你看懂了的话可以自己改这块的逻辑。

然后选中所有的点云,然后合并就行了
在这里插入图片描述
合并后可以看到被截取的这一块点云已经和原来的点云不一样了
在这里插入图片描述
在属性中找到Active可以找到被切分的点云分类

在这里插入图片描述
在这里插入图片描述
保存一下这个点云,保存成ASCII码的格式,以便我们对这个点云文件重新进行操作,以文本格式打开:
在这里插入图片描述
每个属性从上到下对应end_header后从左到右的一条条内容,比如第一行

7.099000 7.473000 4.869000 0 59 255 7.000000 1.000000 1.000000 0.000000

代表了一个点的
x坐标 y坐标 z坐标 r色 g色 b色 scalar_Intensity scalar_HSupport scalar_Support scalar_Original_cloud_index

我们在这里只需要判断Support的值就可以了,后面的几个scalar值就是标签的值,我们在这里只需要判断是不是Support对象,然后一行行地制作出.pts文件和.seg文件即可。

这里给出一段示例代码,需要注意的是,这个代码并不是自适应的识别所有标签,所以需要自己根据业务和自己的需要调整

CCSeperator.h

#pragma once#include <QtWidgets/QMainWindow>
#include "ui_CCSeperator.h"
#include "qpoint.h"
#include "qvector.h"
#include "qfile.h"
#include "qfileinfo.h"
#include "qtextstream.h"
#include "qdir.h"
#include "qdebug.h"
//CC数据清洗工具
enum class PointType {None = 0,Support = 1,VSupport = 2
};struct CCPoint {float x = 0.00;float y = 0.00;float z = 0.00;PointType type = PointType::None;
};class CCSeperator
{Q_OBJECTpublic:CCSeperator();~CCSeperator();/// <summary>/// 读取指定点云文件并尝试解析到指定目录下/// </summary>void ReadFile(const QString& filePath, const QString& outputPath);QVector<CCPoint> vec_points;
};

CCSeperator.cpp

#include "CCSeperator.h"CCSeperator::CCSeperator()
{this->ReadFile("J:\\output\\GF3_7.ply", "J:\\output");
}CCSeperator::~CCSeperator()
{}void CCSeperator::ReadFile(const QString& filePath, const QString& outputPath)
{//尝试读取指定目录下的文件QFile file(filePath);QString fileName = QFileInfo(file).baseName();if (!file.exists()) {qDebug() << " file not exist";return;}this->vec_points.clear();qDebug() << file.open(QIODevice::ReadWrite | QIODevice::Text);QTextStream in(&file);bool blnEndHead = false;while (!in.atEnd()) {QString line = in.readLine();if (line.contains("end_header")) {blnEndHead = true;continue;}if (!blnEndHead) continue;QStringList list = line.split(" ");CCPoint point;point.x = list[0].toFloat();point.y = list[1].toFloat();point.z = list[2].toFloat();//这个对应的是识别的列,这里是第七行if (list[6].toFloat() == 1.0000) {point.type = PointType::Support;}else {point.type = PointType::None;}this->vec_points.append(point);}//注入点完成后,需要将其导出到指定目录下QDir dir(outputPath);if (!dir.exists()) {dir.mkpath(dir.absolutePath());}QFile file_out_data(outputPath + QString("/Data/%1.pts").arg(fileName));QTextStream out(&file_out_data);QFile file_out_label(outputPath + QString("/Label/%1.seg").arg(fileName));QTextStream out_label(&file_out_label);file_out_data.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);file_out_label.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);for (auto item : this->vec_points) {//将所有的点写入到指定目录下//无论如何,正常的点都需要写入QString fileContent = QString("%1 %2 %3").arg(item.x).arg(item.y).arg(item.z);out << fileContent << endl;QString label = QString("%1").arg(static_cast<qint32>(item.type));out_label << label << endl;}file_out_data.close();file_out_label.close();
}

这样洗出来的数据就是这样的:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样我们就完成了自制SharpNet数据集的过程

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

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

相关文章

旅游分享系列之:福建旅游攻略

旅游分享系列之&#xff1a;福建旅游攻略 一、漳州1.福建土楼2.云水谣3.四菜一汤景点 二、厦门1.园林博览苑2.海上自行车道3.山海步道4.海滩5.闽南菜6.落日 三、泉州1.衙口沙滩2.海上日出3.珞珈寺4.海滩烟花 一、漳州 游玩2个景点&#xff1a;云水谣&#xff0c;四菜一汤可以住…

基于Java+SpringBoot+Vue前后端分离仓库管理系统设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

QT常用类

五、常用类 QString 字符串类&#xff08;掌握&#xff09; QString是Qt的字符串类&#xff0c;与C的std::string相比&#xff0c; 不再使用ASCII编码。QString使用的是Unicode编码。 QString中每个字符都是一个16位的QChar&#xff0c;而不是8位的char。 QString完全支持中文&…

深入探究node搭建socket服务器

自从上篇中sokect实现了视频通话&#xff0c;但是是使用ws依赖库实现的服务端&#xff0c;所以最近再看ws源码&#xff0c;不看不知道&#xff0c;一看很惊讶。 接下来一点点记录一下&#xff0c;如何搭建一个简易的服务端socket&#xff0c;来实现上次的视频通讯。 搭建一个…

详解AP3216C(三合一sensor: 光照、距离、照射强度)驱动开发

目录 概述 1 认识AP3216C 1.1 AP3216C特性 1.2 AP3216C内部结构 1.3 AP3216C 硬件电路 1.4 AP3216C工作时序 1.4.1 I2C 写数据协议 1.4.2 I2C 读数据协议 1.5 重要的寄存器 1.5.1 系统配置寄存器 1.5.2 和中断相关寄存器 1.5.3 IR数据寄存器 1.5.4 ALS 数据寄存器 …

代码随想录算法训练营第59天 | 583.两个字符串的删除操作 + 72.编辑距离 + 编辑距离总结篇

今日任务 583. 两个字符串的删除操作 72. 编辑距离 编辑距离总结篇 583.两个字符串的删除操作 - Medium 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以…

【数学建模规则】2024年第九届数维杯大学生数学建模挑战赛参赛指南

一、竞赛介绍 数维杯大学生数学建模挑战赛每年分为两场&#xff0c;每年上半年为数维杯国赛&#xff08;5月&#xff0c;俗称小国赛&#xff09;&#xff0c;下半年为数维杯国际赛(11月)&#xff0c;2023年第八届数维杯大学生数学建模挑战赛共有近1.4万名学生参赛&#xff0c;…

Unity之PUN2插件实现多人联机射击游戏

目录 &#x1f4d6;一、准备工作 &#x1f4fa;二、UI界面处理 &#x1f4f1;2.1 登录UI并连接PUN2服务器 &#x1f4f1;2.2 游戏大厅界面UI &#x1f4f1;2.3 创建房间UI &#x1f4f1;2.4 进入房间UI &#x1f4f1;2.5 玩家准备状态 &#x1f4f1;2.6 加载战斗场景…

vue proxy解决跨域问题

https://blog.csdn.net/tttttrrrhh/article/details/127685318 cims系统ui

java 面向对象-上:类的结构之二

类的设计中&#xff0c;两个重要结构之二&#xff1a;方法 方法 描述类应该具的功能。 比如&#xff1a;Math类&#xff1a;sqrt()\random() \... Scanner类&#xff1a;nextXxx() ... Arrays类&#xff1a;sort() \ binarySearch() \ toString() \ equals() \ ... 1.举例 p…

[Java 项目亮点] 三层限流设计

思路来源&#xff1a;bilibili 河北王校长 文章目录 面试官可能会问你能详细介绍一下Nginx的http_limit_req_module模块吗&#xff1f;你能解释一下如何在Nginx中配置http_limit_req_module模块吗&#xff1f;你知道如何调整Nginx的http_limit_req_module模块以适应不同的业务需…

【服务器数据恢复】通过reed-solomon算法恢复raid6数据的案例

服务器数据恢复环境&#xff1a; 一台网站服务器中有一组由6块磁盘组建的RAID6磁盘阵列&#xff0c;操作系统层面运行MySQL数据库和存放一些其他类型文件。 服务器故障&#xff1a; 该服务器在工作过程中&#xff0c;raid6磁盘阵列中有两块磁盘先后离线&#xff0c;不知道是管理…

Linux--自定义shell

shell shell就是操作系统提供给用户与操作系统进行交互的命令行界面。它可以理解为一个用户与操作系统之间的接口&#xff0c;用户可以通过输入命令来执行各种操作&#xff0c;如文件管理、进程控制、软件安装等。Shell还可以通过脚本编程实现自动化任务。 常见的Unix系统中使…

创新性3D数据合成模型,微软推出EgoGen

随着AR、VR等设备的广泛应用,第一人称的应用开始增多。但在研发方面面临不同的挑战,例如&#xff0c;图像模糊、视觉混乱、遮挡更严重等&#xff0c;给视觉模型的训练带来重大挑战。 一方面,人工标注真实第一视角数据集&#xff0c;来培训深度学习模型的成本和难度都很高。另一…

Java 泛型

优质博文&#xff1a;IT-BLOG-CN 一、为什么要有泛型 【1】解决元素存储的安全性问题。 【2】解决获取数据元素时&#xff0c;需要类型强转的问题。 【3】可以统一数据类型&#xff0c;便于操作。 【4】将运行时的异常提前到了编译时&#xff0c;提高了效率。 【5】实现代码的…

Day20_网络编程(软件结构,网络编程三要素,UDP网络编程,TCP网络编程)

文章目录 Day20 网络编程学习目标1 软件结构2 网络编程三要素2.1 IP地址和域名1、IP地址2、域名3、InetAddress类 2.2 端口号2.3 网络通信协议1、OSI参考模型和TCP/IP参考模型2、UDP协议3、TCP协议 2.4 Socket编程 3 UDP网络编程3.1 DatagramSocket和DatagramPacket1、Datagram…

小世界网络:直径、分形、同配性

1.小世界网络特点 —— 网络直径接近于网络中节点数量的自然对数 2.小世界分形网络 —— 移除弱链接的小世界网络 3.同配性分析 —— Pearson相关系数、邻居相关度 在宏观层面上&#xff0c;关注平均度、度分布和聚类等全局结构特征的影响。更高的平均度被认为会导致更…

Zookeeper简介及选举机制

1.概述 Zookeeper是一个开源的&#xff0c;分布式的&#xff0c;为分布式框架&#xff08;如下图中的Hadoop和Hive&#xff09;提供协调服务的Apache项目。 工作机制&#xff1a;基于观察者设计模式的分布式服务管理框架&#xff0c;负责存储和管理数据&#xff0c;接受观察者…

[算法沉淀记录] 排序算法 —— 归并排序

排序算法 —— 归并排序 算法介绍 归并排序是一种分治算法&#xff0c;由约翰冯诺伊曼在1945年发明。它的工作原理是将未排序的列表划分为n个子列表&#xff0c;每个子列表包含一个元素(包含一个元素的列表被认为是有序的)&#xff0c;然后重复合并子列表以生成新的有序子列表…

ClickHouse 指南(三)最佳实践 -- 稀疏主索引

在ClickHouse主索引的实用介绍 ClickHouse release 24.1, 2024-01-30 1、简介 在本指南中&#xff0c;我们将深入研究ClickHouse索引。我们将详细说明和讨论: ClickHouse中的索引与传统的关系数据库管理系统有何不同ClickHouse是如何构建和使用表的稀疏主索引的什么是在Clic…