前言
这不是高支模项目需要嘛,他们用传统算法切那个横杆竖杆流程复杂耗时很长,所以想能不能用机器学习完成这些工作,所以我就来整这个工作了。
工欲善其事,必先利其器,在正式开始之前,我们先要搞懂如何切分数据集。
本系列文章所用的核心骨干网络代码主要来自点云处理:实现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
#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_OBJECT
public:
CCSeperator();
~CCSeperator();
///
/// 读取指定点云文件并尝试解析到指定目录下
///
void ReadFile(const QString& filePath, const QString& outputPath);
QVector vec_points;
};
CCSeperator.cpp
#include "CCSeperator.h"
CCSeperator::CCSeperator()
{
this->ReadFile("J:outputGF3_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() vec_points.clear();
qDebug() 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(fileN服务器托管网ame));
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 (item.type));
out_label
这样洗出来的数据就是这样的:
这样我们就完成了自制SharpNet数据集的过程
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 【Windows】windows11右键默认显示更多选项的办法
Windows11系统的右键菜单显示,需要多点一次“显示更多选项”才能看到所有菜单内容,按下面步骤简单设置一下就能恢复成Windows经典的右键菜单显示。 1. 2.输入命令【reg.exe add “HKCUSoftwareClassesCLSID{86ca…