scannet数据集简介和下载

近期打算复现pointcontrast这个模型做语义分割,一直卡在数据集的下载上,觉得有必要搞明白这个数据集是怎么回事。这里要非常感谢两个博主,下面有他们博文的连接,写的很好,我这里整理一下思路。

数据集简介

数据集的github地址

ScanNet 是一个 RGB-D 视频数据集,包含 1500 多次扫描中的 250 万个视图,并使用 3D 相机姿势、表面重建和实例级语义分割进行注释 。 ScanNet V2数据集一共1.2T 。(但其实不用全下载,按照对应的任务有选择的下载)

RGB-D 传感器是一种特定类型的深度感应设备,与RGB(红色、绿色和蓝色)传感器相机配合使用。 它通过在每个像素的基础上使用深度信息(与传感器的距离相关)来增强传统图像,即RGBD = RGB + Depth Map。

  1. 数据集怎么制作的呢?

    斯坦福的博士团队收集3D重建数据,用有效的方式对数据进行标注,来收集更多数据。团队通过收集RGB-D的视频序列,通过ipad应用加深传感器收集,然后视频会被上传到服务器,并被自动重建。 然后,视频会被给到亚马逊 Mechanical Turk,将标注工作众包出去。

2.数据怎么标注的呢?

​ 在一个给定的3D场景中,绘制出物体,可以是椅子、桌子或者计算机,从而了解每个物体,以及对应的 所在位置。每个图像通常需要5个人来标注。所得数据可以在做物体分类这样的训练任务。主要的任务就是 给3D数据赋予语义解释,这样有利于机器人更好的理解世界。

数据集介绍

一共1513个采集场景数据(每个场景中点云数量都不一样,如果要用到端到端可能需要采样,使每一个场景的点都相同),共21个类别的对象,其中,1201个场景用于训练,312个场景用于测试 。

ScanNet 中的数据按 RGB-D 序列组织。每个序列都存储在名为 scene < spaceId > < scanId > 或 scene%04d_%02d 的目录下,其中每个空间对应一个唯一位置(从 0 开始索引)。扫描期间捕获的原始数据、相机姿势和表面网格重建以及注释元数据都针对给定序列存储在一起。该目录具有以下结构:

数据集目录结构:虽然解释了但还是没太看懂。。。。。但大概知道里面是2D和3D数据,如果点云的话不需要2D的数据。

<scanId>
|-- <scanId>.sens
    包含颜色帧、深度帧、相机姿势和其他数据的 RGB-D 传感器流
    RGB-D传感器流(*sens):压缩二进制格式,
    包含每帧的颜色、深度、相机姿势和其他数据。
    其中RGB图像大小为1296×968,深度图像大小为640×480
|-- <scanId>_vh_clean.ply
    High quality reconstructed mesh
    高质量重建网格
|-- <scanId>_vh_clean_2.ply
    Cleaned and decimated mesh for semantic annotations
    清理和抽取语义注释的网格
|-- <scanId>_vh_clean_2.0.010000.segs.json
    Over-segmentation of annotation mesh
    注释网格的过分割
|-- <scanId>.aggregation.json, <scanId>_vh_clean.aggregation.json
    Aggregated instance-level semantic annotations on lo-res, hi-res meshes, respectively
    分别在低分辨率、高分辨率网格上聚合实例级语义注释
|-- <scanId>_vh_clean_2.0.010000.segs.json, <scanId>_vh_clean.segs.json
    Over-segmentation of lo-res, hi-res meshes, respectively (referenced by aggregated semantic annotations)
    分别对低分辨率、高分辨率网格进行过分割(由聚合语义注释引用)
|-- <scanId>_vh_clean_2.labels.ply
    Visualization of aggregated semantic segmentation; colored by nyu40 labels (see img/legend; ply property 'label' denotes the nyu40 label id)
    聚合语义分割的可视化;由 nyu40 标签着色(参见 img/图例;ply 属性“label”表示 nyu40 标签 id)
|-- <scanId>_2d-label.zip
    Raw 2d projections of aggregated annotation labels as 16-bit pngs with ScanNet label ids
    聚合注释标签的原始 2d 投影为具有 ScanNet 标签 id16 位 png
|-- <scanId>_2d-instance.zip
    Raw 2d projections of aggregated annotation instances as 8-bit pngs
    聚合注释实例的原始二维投影为 8 位 png
|-- <scanId>_2d-label-filt.zip
    Filtered 2d projections of aggregated annotation labels as 16-bit pngs with ScanNet label ids
    将聚合注释标签的 2d 投影过滤为具有 ScanNet 标签 id16 位 png
|-- <scanId>_2d-instance-filt.zip
    Filtered 2d projections of aggregated annotation instances as 8-bit pngs
    将聚合注释实例的 2d 投影过滤为 8 位 png

数据格式和可视化代码

例如这种Surface mesh segmentation file文件*.segs.json

./ContrastiveSceneContexts-main/downstream/semseg/datasets/preprocessing/scannet/SCANNET_DATA/scans/scene0000_00/scene0000_00_vh_clean_2.0.010000.segs.json

{
"params": {//分割参数
	"kThresh": "0.0001",
	"segMinVerts": "20",
	"minPoints": "750",
	"maxPoints": "30000",
	"thinThresh": "0.05",
	"flatThresh": "0.001",
	"minLength": "0.02",
	"maxLength": "1"
}
,
"sceneId": "scene0000_00",
"segIndices":[....]//网格段的每顶点索引
}

语义标注文件*.aggregation.json

ContrastiveSceneContexts-main/downstream/semseg/datasets/preprocessing/scannet/SCANNET_DATA/scans/scene0000_00/scene0000_00.aggregation.json

{
"sceneId": "scannet.scene0000_00",//标注场景的ID
"appId": "Aggregator.v2",// 用于创建注释的工具的版本
"segGroups": [
	{
	"id": 0,
	"objectId": 0,
	"segments": [43652,43832,43632,53294,44062,44013,44158,53070,53173,53253],
	"label": "window"
	},{},{}....
    ],
"segmentsFile": "scannet.scene0000_00_vh_clean_2.0.010000.segs.json"}//引用的 *.segs.json 分割文件的id

BenchmarkScripts/util_3d.py gives examples to parsing the semantic instance information from the *.segs.json, *.aggregation.json, and *_vh_clean_2.ply mesh file, with example semantic segmentation visualization(语义分割可视化后续可以尝试) in BenchmarkScripts/3d_helpers/visualize_labels_on_mesh.py.

数据集下载方式

https://blog.csdn.net/qq_25763027/article/details/126112421

https://blog.csdn.net/qq_35781447/article/details/115078283#comments_24548052

这两篇文章的博主把下载过程讲的很详细,我也是参考他的下载方式进行下载的,超级推荐。当然如果都不行的话就只能给官方写邮件获取下载数据的python代码(这条路我没试过)

有了下载的代码就可以使用命令, -o为文件下载路径,-type为下载哪种文件类型。

python download_scannet.py -o path(存放数据集的路径) --type _vh_clean_2.ply
python download_scannet.py -o path(存放数据集的) --type _vh_clean_2.label.ply
#python3 download-scannet.py -o scannet/ --type  _vh_clean_2.labels.ply
python download_scannet.py -o path(存放数据集的) --type _vh_clean_2.0.010000.segs.json
python download_scannet.py -o path(存放数据集的) --type .aggregation.json

下载后的文件目录结构

├── scannet
│   ├── scans
│   │   ├── [scene_id]									
│   │   │   ├── [scene_id].aggregation.json
│   │   │   ├── [scene_id]_vh_clean_2.0.010000.segs.json
│   │   │   ├── [scene_id]_vh_clean_2.labels.ply
│   │   │   ├── [scene_id]_vh_clean_2.ply
│   ├── scans_test
│   │   ├── [scene_id]								
│   │   │   ├── [scene_id]_vh_clean_2.ply
│   ├── scannetv2-labels.combined.tsv
  • 10
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,我了解您的要求。以下是一个简单的Java代码示例,用于监听USB扫描枪数据: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.TooManyListenersException; import javax.usb.UsbConfiguration; import javax.usb.UsbDevice; import javax.usb.UsbDeviceDescriptor; import javax.usb.UsbEndpoint; import javax.usb.UsbException; import javax.usb.UsbHostManager; import javax.usb.UsbHub; import javax.usb.UsbInterface; import javax.usb.UsbPipe; import jssc.SerialPort; import jssc.SerialPortEvent; import jssc.SerialPortEventListener; import jssc.SerialPortException; public class USBScannerListener implements SerialPortEventListener { private static final int VENDOR_ID = 0x067B; private static final int PRODUCT_ID = 0x2303; private static final int DATA_BITS = 8; private static final int STOP_BITS = 1; private static final int PARITY = 0; private static final int BAUD_RATE = 9600; private SerialPort serialPort; public USBScannerListener() { // 查找特定的 USB 设备 UsbDevice device = findDevice(VENDOR_ID, PRODUCT_ID); if (device == null) { System.err.println("USB Scanner not found."); return; } // 在USB设备上找到输入端点 UsbInterface iface = findInterface(device); UsbEndpoint endpoint = (UsbEndpoint) iface.getUsbEndpoints().get(0); try { // 打开 USB 传输管道 UsbPipe pipe = endpoint.getUsbPipe(); pipe.open(); // 设置串口参数 serialPort = new SerialPort("COM1"); serialPort.openPort(); serialPort.setParams(BAUD_RATE, DATA_BITS, STOP_BITS, PARITY); // 注册串口数据监听事件 serialPort.addEventListener(this); serialPort.setEventsMask(SerialPort.MASK_RXCHAR); } catch (UsbException | TooManyListenersException | SerialPortException ex) { System.err.println("Error initializing USB scanner listener: " + ex.getMessage()); } } private UsbDevice findDevice(int vendorId, int productId) { UsbDevice device = null; try { // 获取 USB 根集线器 UsbHub rootHub = UsbHostManager.getUsbServices().getRootUsbHub(); // 递归遍历 USB 树来查找设备 device = findDevice(rootHub, vendorId, productId); } catch (SecurityException | UsbException ex) { System.err.println("Error finding USB device: " + ex.getMessage()); } return device; } private UsbDevice findDevice(UsbHub hub, int vendorId, int productId) throws SecurityException, UsbException { UsbDevice device = null; // 遍历每个 USB 设备 for (UsbDevice d : (Iterable<UsbDevice>) hub.getAttachedUsbDevices()) { // 如果设备有子集线器,递归查找子集线器 if (d.isUsbHub()) { device = findDevice((UsbHub) d, vendorId, productId); if (device != null) { break; } } // 如果设备匹配给定的厂商ID和产品ID,则返回设备USB UsbDeviceDescriptor desc = d.getUsbDeviceDescriptor(); if (desc.idVendor() == vendorId && desc.idProduct() == productId) { device = d; break; } } return device; } private UsbInterface findInterface(UsbDevice device) throws UsbException { UsbInterface iface = null; // 遍历每个配置并找到第一个具有输入端点的接口 for (UsbConfiguration config : (Iterable<UsbConfiguration>) device.getUsbConfigurations()) { for (UsbInterface i : (Iterable<UsbInterface>) config.getUsbInterfaces()) { if (i.getUsbEndpoints().size() > 0) { iface = i; break; } } if (iface != null) { break; } } if (iface == null) { throw new UsbException("Device does not have any interfaces with input endpoints."); } return iface; } @Override public void serialEvent(SerialPortEvent event) { if (event.isRXCHAR()) { try { // 读取串口数据并输出到控制台 String data = serialPort.readString(); System.out.println(data); } catch (SerialPortException ex) { System.err.println("Error reading data from serial port: " + ex.getMessage()); } } } public static void main(String[] args) throws IOException { // 创建 USB 扫描仪侦听器 USBScannerListener listener = new USBScannerListener(); // 在按下回车键之前等待用户输入 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Press Enter to exit."); br.readLine(); // 关闭串口和 USB 管道 try { listener.serialPort.closePort(); listener.serialPort.removeEventListener(); listener.serialPort = null; } catch (SerialPortException ex) { System.err.println("Error closing serial port: " + ex.getMessage()); } } } ``` 这个代码在 jssc 库的帮助下工作,它是一组Java命令,可以访问串口和USB设备和数据的通信。 若要使用此示例,请确保已安装jssc库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shan_shmily

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值