ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

ScanNet数据集下载指南:从申请到脚本实战

ScanNet数据集下载指南:从申请到脚本实战 1. 先搞清楚ScanNet里到底有什么再决定要不要下载想下载ScanNet数据集的人十有八九会在网上搜到一批三四年前的老教程照着跑一遍不是Python版本报错就是等待授权邮件等到怀疑人生。我自己当年第一次折腾这套数据时就踩过好几个坑所以这篇把它整理成一份能直接照着操作的完整记录。1.1 这组数据解决的是哪类问题真正在点云、室内场景理解或3D语义分割这条路上摸爬滚打过的人应该都有类似经历翻论文、复现PointNet系列看来看去都会碰上一个绕不开的名字——ScanNet。它是斯坦福大学在2017年CVPR上发布的室内RGB-D数据集一共包含1513个真实场景的扫描数据涵盖了酒店房间、书房、厨房、洗手间等真实室内环境。和NYUv2、SUN RGB-D这些早期数据集相比ScanNet最大优势是不仅有成对的彩色图和深度图还提供了重建后的完整三维网格模型、表面级语义标注以及逐帧的相机位姿。也就是说拿到这组数据你可以同时做三件之前要被拆成三个数据集才能做的事一是训练深度估计和位姿估计模型二是做三维语义分割和实例分割三是为SLAM系统提供带真值的评测序列。这也是为什么各个3D视觉方向的论文附录里几乎都能看到Trained on ScanNet或者Evaluated on ScanNet这样的字样。1.2 下载前先算清楚磁盘、网络和收益这笔账不过我要先泼一盆冷水ScanNet整套数据的体量绝不是你随手在硬盘上划一块就能放下的。所有场景的--task sensor_data原始文件加起来大概是84GB左右如果你顺手把语义标注也下全再加上scannet_posts里按帧解包的color和depth整体突破200GB很轻松。我个人建议至少准备一块500GB左右的NVMe固态并且预留两倍的解压中间空间。别问我为什么强调NVMe——后续对.sens逐帧解包的时候你在机械硬盘上跑和固态盘上跑等待时间差距是小时级的。在动手之前还有个更重要的问题你要的到底是哪部分数据ScanNet并不像很多常识理解的下载一个压缩包就完事它按任务把数据拆成了好几类下载时用不同的参数分别拉取。这个细节直接决定你是花半小时下一组测试样例还是要开着脚本挂一夜。后面第3章我会把参数列表完整展开但第一步建议先确认自己的场景要做点云语义分割核心是sensor_data加scannetv2_labels要跑2D图像分割核心是scannet_posts只做配准评测单独下scannet_posts里的pose就够了。2. 许可证申请这一步建议把两周时间预算进去2.1 账户注册和学术协议签署的完整流程ScanNet的下载权限并不是公开开放的这是它和很多数据集最大的区别。你可能已经在GitHub仓库里看到了download_scannet.py这个脚本但直接用它是下不到任何东西的因为脚本会要求验证你在官网上注册的账号和官方下发的密钥。整个申请流程大概是这样的第一步访问ScanNet官网的注册入口填写姓名和机构邮箱第二步进入许可协议页面完整阅读并勾选学术用途相关条款有些版本还会要求你选填学校和导师信息第三步提交之后等待人工审核。审核通过后你会收到一封邮件里面包含你的登录账号和一个专属的下载授权凭证后续脚本运行时要用这个凭证过校验。这里有三个容易被忽略的细节。第一注册时最好用学校或研究所的机构邮箱网页表单里对机构邮箱的识别相对严格纯个人邮箱被拒的概率明显更高。第二协议中关于是否用于商业用途的选项一定要慎重ScanNet的学术协议明确限制商业使用如果你只是想在公司内部做算法预研又没通过商务合作通道审核会卡得很久。第三提交一次就好别反复注册多个账号催进度后台记录里账号太多反而容易被标注为异常。2.2 从提交申请到收到下载链接实际要等多久不同时期的审核速度差别非常大。我了解到的时间跨度快的有一两天就通过的慢的等了将近三周。这里多说一句ScanNet维护团队是半人工处理方式如果你正好赶上某顶会截止日前的申请高峰等待时间普遍会更长。我的建议是凡是计划做3D视觉方向课题的人尽量在项目启动前就把ScanNet的申请提交掉不要等到数据到位了才想起来开始排期。有些版本的申请流程里还要求额外填一份使用声明说明你计划用ScanNet做什么方向的研究。这部分不用写得很复杂一两句清楚的研究目标就行关键是让审核人觉得你的用途是真实明确的。如果你只是想跑通教程里的例子就写reproducing baseline results on 3D semantic segmentation完全足够。等待期间也别闲着可以在GitHub上把ScanNet的整个仓库clone下来把下载脚本和工具链先装好后面拿到密钥就能直接开跑。ScanNet仓库本身不大几十MB级别里面除了download_scannet.py还有用于读取.sens的SensReader以及一套数据标注工具都是你迟早会用到的。3. 官方下载脚本全流程从clone到数据落盘3.1 环境准备Python版本和依赖库拿到权限之后正式下载的思路就简单了找到官方脚本运行然后等。但简单两个字里藏着一堆环境问题我先把最常用的一套环境写出来你照着搭基本不会出错。git clone https://github.com/ScanNet/ScanNet.git cd ScanNet/Scripts python download_scannet.py --help推荐使用Python 3.6到3.9之间的版本官方脚本虽然历史久远但这几个版本下跑是最稳定的再往上到Python 3.10、3.11可能会遇到依赖库编译问题。需要确认环境里有numpy和plyfile这两个库在后面的数据解析阶段是刚需pip install numpy plyfile不要一上来就创建最新的虚拟环境并安装一堆最新版本包这是个常见误区。ScanNet仓库里很多脚本是在2017年到2019年间写的依赖锁定得比较保守新的库版本反而容易导致接口不兼容。我的习惯是单独建一个Python虚拟环境给ScanNet用隔离其他项目省得莫名其妙被依赖冲突打断下载。3.2 按需选择任务参数别让全量下载拖垮磁盘下载脚本最核心的用法其实就一行关键是选对任务参数。下面是我平时用得最多的几个命令组合# 下载所有场景的原始传感器数据.sens文件 python download_scannet.py -o /data/scannet --scans --task sensor_data # 只下载指定几个场景用于前期调试 python download_scannet.py -o /data/scannet -s scan0011_00 scan0021_00 --task sensor_data # 下载语义标注v2版本 python download_scannet.py -o /data/scannet --scans --task scannetv2_labels # 下载按帧解包好的彩色图/深度图/位姿 python download_scannet.py -o /data/scannet --scans --task scannet_posts这里的--scans参数表示下载全部场景如果漏了它而你又没指定列表脚本会跑到最后提示参数不完整白忙一场。-s参数后面跟场景ID适合先拉两三个场景做流程测试。--task是真正的核心不同任务对应不同数据子集我建议第一次操作时先用-s scan0011_00和--task sensor_data下一组小数据流程跑通后再上全量。另外有个非常实用的细节download_scannet.py会检查本地目标目录里已经存在的文件如果之前下载过某个场景重新执行命令时会跳过已经落盘的部分只补缺的文件。这相当于内置了断点续传能力别因为中途断了就手动删除所有文件从头开始直接重跑一遍脚本是最省事的。3.3 大型下载里没人提醒你的隐藏坑全量下载时最容易被忽略的是.sens文件的体积差异。扫描场景内容越多生成的.sens越大最大的场景文件可以到4GB以上而小的可能只有几十MB。挂机下载的时候如果你开着下载文件夹看着进度条很容易觉得某个文件卡住了其实只是它在拉一个超大的单体文件。我还会在下载前先把输出目录的挂载检查一遍df -h看一下剩余空间ls -ld /data/scannet确认可写权限。遇到过一位同学把输出目录放在系统盘用户目录下下到一半才提示磁盘已满又找不到根目录里占用到底在哪特别心浮气躁。提前花一分钟排查能避免后面一晚上的折腾。4. 下载途中最容易翻车的四个环节4.1 Python 2与Python 3的兼容性问题这一步大概是历史遗留问题最多的环节。官方download_scannet.py最初是针对Python 2写的里面用了urllib2、iteritems这些Python 2专属写法你在Python 3环境直接跑通常会在导入阶段就报错提示找不到urllib2模块。网上很多老教程会让你装Python 2.7去跑但现代系统上搭一个旧版Python环境本身就是新的坑。我的做法很简单用Python 3.8然后对脚本做一次两分钟的小修改。把文件开头的import urllib2换成import urllib.request as urllib2再把任何出现的.iteritems()替换成.items()基本就能跑通了。如果你不想手动改也可以先试试Python 3环境直接跑老版脚本有一些分支在同版本下其实兼容得不错报错了再按上面两个地方排查大概率立竿见影。4.2 网络波动导致的任务中断和处理ScanNet的数据存放位置在海外云存储上跨区域下载时网络稳定性是最大的变量。我自己实测的经验是下载单个场景的.sens文件时如果连接断掉脚本会报超时然后退出但不会损坏本地文件。下次重新执行同一命令时脚本会自动跳过已完成的文件重新下载那一个没下完的。所以应对网络波动最粗暴也最有效的方法就是反复重跑同样的命令。如果重试多次仍然频繁断线我建议把一次拉取的量拆小比如用--scans -s先下20个场景不要一次性全量挂机。或者利用脚本对不同任务分别下发的特征把sensor_data和labels拆成两个批次的脚本执行每天下一部分避免连续长时间占用网络。挂夜机下载时我还强烈建议用tmux或screen这类会话工具起任务。它解决的不只是断网问题还有SSH连接松动导致的进程中断。你不想在第二天早上发现脚本因为终端断开而停在60%的位置尤其当它还是凌晨三点断掉的时候。4.3 下载完成后的校验环节数据下载对完整性要求很高尤其是深度学习训练场景。ScanNet官网对每个文件提供了对应的文件大小信息但并不总是提供公开可校验的MD5码。我个人的校验方法是双重的第一脚本跑完没有ERROR或WARNING输出第二抽查几个场景里所有文件的大小和官网场景详情页里标注的字节数进行对比。如果有明显不一致就对那一个文件重新下载。这里再分享一条经验不要图省事用find命令把所有文件列出来然后觉得都有文件了就是完整的。ScanNet的.sens文件在下载一半中断时同样会生成一个不完整的二进制文件占着名字但内容已经废了。最可靠的办法还是依赖脚本的日志或者文件大小对比缺文件的场景会在后续运行你自己写的数据解析代码时原形毕露。4.4 全量数据的分盘策略如果机器上磁盘空间实在紧张可以把不同任务的数据分别放到不同物理硬盘上。比如.sens原始数据放在一块SSD上语义标注放到一块机械盘上再通过软链接把目录结构拼回一个统一的/data/scannet路径这样既能跑通脚本又不耽误后续工具读文件。命令也很简单mkdir -p /data/scannet/scans ln -s /mnt/ssd1/scannet_sensor /data/scannet/scans ln -s /mnt/hdd1/scannet_labels /data/scannet/scans软链接处理得当大部分后续处理工具都不受影响。我现在的服务器就是两块2TB固态加一块4TB机械盘这么搭配的ScanNet的全量数据加上其他数据集共存完全没有压力。5. 按需下载数据子集语义标注、关键帧和2D图各取所需5.1 任务与数据子集的对应关系ScanNet的数据子集划分方式是理解整个数据集的钥匙。简单来说.sens文件是母带里面按帧封装了彩色图、深度图、内参和相机位姿但你要用某个具体任务时通常不需要反复去解这个母带直接下载官方已经解好的子集更高效。下面的表格是我平时对照用的任务方向优先下载的任务参数对应数据内容语义/实例分割scannetv2_labels点级别的语义标签、实例标签3D点云分割sensor_data scannetv2_labels重建网格、原始帧、标签多视图深度/位姿估计scannet_posts按帧彩色图、深度图、位姿、内参SLAM/配准评测sensor_data 或 scannet_posts原始传感器数据和位姿序列这里提醒一下scannet_posts是已经按帧拆包好的目录每个场景下面直接是color、depth、pose、intrinsic这些子文件夹结构直观加载代码写起来最省事。但如果未来要复现某些老论文里的基础流程它们更常要求你对.sens自行解包因为有些作者实现里传递的文件路径格式是写死的。5.2 用SenseReader读取.sens并提取关键帧如果你手头只有.sens原始文件又需要拿到某个任务的输入图可以写个小脚本提取。ScanNet仓库的SensorData目录下提供了sens_reader.py这个类本质上就是一个可迭代的传感器数据容器按帧取出Color、Depth、Pose等信息然后保存到磁盘。from sens_reader import SenseReader reader SenseReader(scan0011_00.sens) for frame_id, frame in enumerate(reader): color frame.color depth frame.depth pose frame.pose # 这里可以按需保存color/depth/pose到本地文件夹实际运行时要注意解包.sens是非常消耗磁盘I/O的操作一个4GB的.sens解出来可能占掉原来的三倍空间。所以除非确实需要完整的逐帧数据做训练我一般只解出关键帧序列。ScanNet官方在sens_reader里提供了s_reader.extract_key_frames()这样的方法传入一个关键帧的索引列表就能只提取需要的帧能省下大量空间和时间。5.3 标注文件的常见命名规则多次看到有人下载完语义标注之后面对一堆.ply文件不知道怎么用。其实ScanNet v2标注的命名规律非常清晰*_vh_clean_2.labels.ply是面片级别的语义标注*_vh_clean_2.segs.json是超体素分割结果*_vh_clean_2.instances.align.annotated.ply是实例标注。一般点云语义分割模型直接加载.labels.ply文件里面的class字段就是每个点的类别索引instance相关文件则配合标注格式用于实例分割。我还习惯在跑数据处理前先用plyfile读一个标注文件统计一下类别分布确认void和有效类别的比例是否正常。这一步看似简单但能提前发现很多问题比如标注文件没下载全、版本不一致、或者类别索引偏移省得等训练跑到一半才发现mIoU完全不对。6. 申请不下来时的出路社区镜像、目录结构和校验6.1 等不到官方许可时的替代方案总会有一些情况是不得不等的学校邮箱收不到邮件、审核周期太长、或者你只想要一小部分场景快速跑基线实验。这时候不必死磕官方网站有两个我实际用过的替代途径可以考虑。第一个是OpenDataLab这类国内公开数据集平台上面能找到ScanNet的镜像版本有的直接提供整包下载链接不用走学术协议审核流程。第二个是Hugging Face上的社区数据集仓库有研究机构和个人把ScanNet整理成更现代的目录格式上传方便用数据集加载库直接读取。不过这些渠道毕竟不是官方同步版本新旧、标注是否完整、文件是否被重新编码过都要自己花时间确认。我的建议是能申请到官方权限还是优先官方镜像渠道更适合临时跑通代码或做小规模实验。6.2 拿到数据后如何快速熟悉目录结构无论从哪个渠道拿到ScanNet第一步都建议先打印一下目录树形成对这个数据集的直觉。全量下载后scans目录下是场景ID命名的子目录每个子目录里至少包含.sens、.txt、重建后的网格模型*_vh_clean.ply以及干净版网格*_vh_clean_2.ply。语义标注则集中在scannetv2_labels目录下和场景ID一一对应。打开一个.ply网格文件看一下点数和颜色分布用一个语义标注文件对比看看PointNet里预处理的输入格式比自己直接去读一堆论文的DataLoader要直观得多。这一步做好了后面写数据处理脚本时的效率会高很多。6.3 关于数据版本和标签类别的最后提醒ScanNet的标注类别在社区里有一个大家默认的20类概念实际使用时要注意背景空点位和无法标注的点会被标成void有效类别加上otherfurniture一共是20个。很多预处理脚本里会把void过滤掉训练时只对剩余有效点计算损失。如果你直接拿20类的模型去预测别人清理过void的数据输出的mIoU会有明显差异这一点在做跨数据集评测时尤其容易踩坑。最后说个我自己常干的小事第一次下一份ScanNet子集之后我会在输出目录里放一个README.txt把任务参数、下载日期、磁盘占用、版本信息全部记下来。三个月后当你发现某个实验的基线效果不对劲翻这个文件就能快速定位是数据版本的问题还是自己代码的锅省下来的排查时间远超当时写这几行字的时间。
返回列表