保姆级教程:用Shell脚本一键搞定nuScenes v1.0数据集下载与解压(附避坑指南)
保姆级教程:用Shell脚本一键搞定nuScenes v1.0数据集下载与解压(附避坑指南)
在计算机视觉和自动驾驶领域,nuScenes数据集因其丰富的标注和多样化的场景而成为研究热点。然而,初次接触这个数据集的研究者往往会遇到一个令人头疼的问题:数据集由多个压缩包组成,手动下载和解压不仅耗时耗力,还容易出错。本文将带你用Shell脚本实现nuScenes数据集的全自动下载与解压,解决以下痛点:
- 多个压缩包需要按特定顺序处理
- 图形化解压可能导致目录结构混乱
- 附加数据(如Map expansion)需要特殊处理
- 缺乏完整性校验可能导致后续使用问题
1. 环境准备与目录结构规划
在开始编写脚本前,合理的目录结构能避免后续很多麻烦。建议按以下方式组织:
~/datasets/ └── nuscenes/ ├── maps/ # Map expansion存放位置 ├── can_bus/ # CAN bus expansion存放位置 ├── downloads/ # 临时下载目录 └── scripts/ # 存放我们的自动化脚本创建基础目录结构的命令:
mkdir -p ~/datasets/nuscenes/{maps,can_bus,downloads,scripts} cd ~/datasets/nuscenes/scripts注意:-p参数可以自动创建不存在的父目录,避免因目录不存在导致的错误。
2. 自动化下载脚本编写
nuScenes数据集通常包含多个压缩包,手动下载既费时又容易遗漏。我们可以用wget配合简单的Shell脚本实现批量下载。
创建下载脚本download_nuscenes.sh:
#!/bin/bash # 定义下载链接数组 DOWNLOAD_LINKS=( "https://example.com/nuscenes/v1.0-trainval.tar" "https://example.com/nuscenes/v1.0-test.tar" "https://example.com/nuscenes/map-expansion-v1.3.zip" "https://example.com/nuscenes/can-bus-v1.0.zip" ) # 创建下载目录 DOWNLOAD_DIR="../downloads" mkdir -p $DOWNLOAD_DIR cd $DOWNLOAD_DIR # 下载函数 download_with_retry() { local url=$1 local filename=$(basename $url) local max_retries=3 local retry_count=0 while [ $retry_count -lt $max_retries ]; do echo "正在下载: $filename (尝试 $((retry_count+1))/$max_retries)" wget -c $url && return 0 retry_count=$((retry_count+1)) sleep 5 done echo "下载失败: $filename" return 1 } # 主下载循环 for link in "${DOWNLOAD_LINKS[@]}"; do download_with_retry $link || exit 1 done echo "所有文件下载完成!"脚本亮点解析:
- 断点续传:
wget -c支持中断后继续下载 - 重试机制:失败后自动重试3次
- 进度显示:清晰显示当前下载状态
提示:实际使用时,请替换
DOWNLOAD_LINKS数组中的URL为真实的下载链接。nuScenes官方下载需要先获取授权。
3. 智能解压脚本开发
解压是处理nuScenes数据集最易出错的环节。我们将开发一个能处理各种情况的健壮解压脚本。
创建解压脚本extract_nuscenes.sh:
#!/bin/bash # 定义解压目录和下载目录 BASE_DIR=".." DOWNLOAD_DIR="$BASE_DIR/downloads" EXTRACT_DIR="$BASE_DIR" # 检查下载目录是否存在 if [ ! -d "$DOWNLOAD_DIR" ]; then echo "错误: 下载目录不存在 $DOWNLOAD_DIR" exit 1 fi # 解压函数:自动识别压缩格式并解压 extract_file() { local file=$1 local target_dir=$2 echo "正在处理: $(basename $file)" case $file in *.tar|*.tar.gz|*.tgz) tar -xzvf "$file" -C "$target_dir" ;; *.zip) unzip -q "$file" -d "$target_dir" ;; *) echo "不支持的压缩格式: $file" return 1 ;; esac # 检查解压是否成功 if [ $? -ne 0 ]; then echo "解压失败: $file" return 1 fi return 0 } # 主解压流程 cd $DOWNLOAD_DIR # 优先处理主数据集 for archive in v1.0-*.tar*; do extract_file "$archive" "$EXTRACT_DIR" || exit 1 done # 处理Map expansion if [ -f "nuScenes-map-expansion-*.zip" ]; then mkdir -p "$EXTRACT_DIR/maps" extract_file "nuScenes-map-expansion-*.zip" "$EXTRACT_DIR/maps" || exit 1 fi # 处理CAN bus expansion if [ -f "nuScenes-can-bus-*.zip" ]; then mkdir -p "$EXTRACT_DIR/can_bus" extract_file "nuScenes-can-bus-*.zip" "$EXTRACT_DIR/can_bus" || exit 1 fi echo "所有文件解压完成!目录结构已自动整理。"关键功能对比:
| 功能 | 手动解压 | 本脚本 |
|---|---|---|
| 格式识别 | 需人工判断 | 自动识别 |
| 目录结构 | 易混乱 | 自动整理 |
| 错误处理 | 无 | 自动检测 |
| 附加数据 | 需单独处理 | 自动归类 |
| 批量处理 | 逐个操作 | 一键完成 |
4. 完整性校验与错误处理
数据集不完整会导致后续训练或评估失败。我们增强脚本的健壮性:
#!/bin/bash # 添加校验函数 check_integrity() { local file=$1 local expected_size=$2 # 单位: MB actual_size=$(du -m "$file" | cut -f1) if [ $actual_size -lt $((expected_size * 9 / 10)) ]; then echo "文件可能损坏: $file (大小: ${actual_size}MB, 预期: ${expected_size}MB)" return 1 fi return 0 } # 在download_with_retry函数后添加校验 download_with_retry() { # ...原有代码... # 下载成功后校验 check_integrity "$filename" $expected_size || { rm -f "$filename" return 1 } } # 定义预期文件大小(示例值,需根据实际情况调整) declare -A FILE_SIZES=( ["v1.0-trainval.tar"]=15000 ["v1.0-test.tar"]=5000 ["nuScenes-map-expansion-v1.3.zip"]=300 ["nuScenes-can-bus-v1.0.zip"]=100 ) # 修改主下载循环 for link in "${DOWNLOAD_LINKS[@]}"; do filename=$(basename $link) expected_size=${FILE_SIZES[$filename]} download_with_retry $link $expected_size || exit 1 done常见错误及解决方案:
解压后目录嵌套:
# 在extract_file函数中添加修复逻辑 if [ -d "$target_dir/nuScenes" ]; then mv "$target_dir/nuScenes"/* "$target_dir/" rmdir "$target_dir/nuScenes" fi权限问题:
# 在脚本开头添加 chmod -R a+rw $DOWNLOAD_DIR磁盘空间不足:
# 添加空间检查 REQUIRED_SPACE=20000 # 单位: MB AVAILABLE_SPACE=$(df -m . | awk 'NR==2 {print $4}') if [ $AVAILABLE_SPACE -lt $REQUIRED_SPACE ]; then echo "错误: 磁盘空间不足 (需要: ${REQUIRED_SPACE}MB, 可用: ${AVAILABLE_SPACE}MB)" exit 1 fi
5. 一键式整合脚本
将下载、解压和校验整合为单个脚本setup_nuscenes.sh:
#!/bin/bash # 导入环境变量 SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd) BASE_DIR="$SCRIPT_DIR/.." # 执行下载 echo "=== 开始下载nuScenes数据集 ===" "$SCRIPT_DIR/download_nuscenes.sh" || { echo "下载阶段失败" exit 1 } # 执行解压 echo "=== 开始解压数据集 ===" "$SCRIPT_DIR/extract_nuscenes.sh" || { echo "解压阶段失败" exit 1 } # 最终校验 echo "=== 验证目录结构 ===" [ -d "$BASE_DIR/samples" ] && \ [ -d "$BASE_DIR/sweeps" ] && \ [ -d "$BASE_DIR/maps" ] && \ [ -f "$BASE_DIR/v1.0-trainval_meta.tgz" ] && \ echo "验证通过!数据集已准备就绪。" || { echo "错误: 目录结构不完整" exit 1 }使用方式:
chmod +x setup_nuscenes.sh ./setup_nuscenes.sh性能优化技巧:
- 并行下载(需安装
parallel):parallel -j 4 wget -c {} ::: "${DOWNLOAD_LINKS[@]}" - 进度显示美化(需安装
pv):tar -xzvf large_file.tar | pv -p -t -e -r -s $(du -sb large_file.tar | awk '{print $1}') > /dev/null - 内存限制(防止解压大文件时OOM):
ulimit -v $((1024 * 1024 * 4)) # 限制4GB内存
在实际项目中,这套脚本帮我节省了数小时的手动操作时间,特别是在需要频繁设置实验环境时。最实用的功能是自动整理目录结构,彻底解决了因解压方式不同导致的数据路径问题。
