自动驾驶Occ实战:从Occupancy3D数据集解析到模型评测全流程指南

Occ端到端实战指南:从数据集解析到模型评估 本文是一份详细的Occupancy(Occ)网络端到端实战指南。文章从解析业界标准数据集Occupancy3D-nuScenes的结构与标注入手,深入解读了衡量模型性能的核心指标mIoU与IoU_geo。并以TPVFormer为例,系统拆解了从图像编码、2D到3D特征转换、3D特征精炼到任务输出的完整模型框架设计精髓,最后分享了数据加载、模型训练、多GPU同步及可视化调试等关键实战技巧与避坑指南。 阅读详情

自动驾驶Occ实战:从Occupancy3D数据集解析到模型评测全流程指南

最近和几个在头部自动驾驶公司做感知的朋友聊天,大家不约而同地提到了一个词:Occupancy。如果说前两年BEV(鸟瞰图)感知是行业里的显学,那么现在,Occ(占据网络)技术正接过接力棒,成为解决复杂、长尾场景下环境理解难题的新宠。它不再满足于告诉你“前面有个车”,而是试图构建一个稠密的、三维的、语义化的“占据网格”,回答“这个空间里每个小方块是什么,以及它是否被占据”这个更本质的问题。这听起来很酷,但当你真正想动手复现一个Occ模型,或者在自己的数据集上跑通评测流程时,面对的往往是一堆散乱的数据、复杂的指标和令人困惑的代码。这篇文章,就是为你准备的。我们不谈空洞的理论,只聚焦于一个目标:手把手带你走通从Occupancy3D数据集解析到模型训练、验证、评测的全流程。无论你是想快速上手一个开源Occ项目,还是计划为自己的研究构建评测基准,这里面的“坑”和经验,希望能让你少走弯路。

1. 深入Occupancy3D数据集:不止是文件,更是逻辑

拿到一个像Occupancy3D-nuScenes-V1.0这样的数据集,第一反应往往是打开文件夹看看里面有什么。这没错,但更关键的是理解其设计逻辑。这个数据集本质上是为了解决“如何从多摄像头图像生成稠密3D语义占据真值”而构建的。它的结构反映了自动驾驶数据处理的典型流水线:原始传感器数据(图像)、精确的时空对齐信息(标定与位姿)、以及人工或半自动生成的3D真值。

1.1 目录结构背后的数据流

让我们超越简单的文件列表,看看数据是如何流动的:

Occupancy3D-nuScenes-V1.0/
├── mini/          # 小型开发/调试集
├── trainval/      # 主要的训练验证集
│   ├── imgs/      # 多摄像头图像流
│   │   ├── CAM_BACK/
│   │   ├── CAM_BACK_LEFT/
│   │   └── ... (其他摄像头)
│   └── gts/       # 3D占据网格真值
│       ├── scene-0001/
│       │   ├── frame_token_abc123/
│       │   │   └── labels.npz
│       │   └── ...
│       └── ...
└── test/          # 测试集(通常无真值)

这里隐藏的第一个关键点是时间同步与传感器融合。imgs/目录下按摄像头分类的图像,文件名中编码了时间戳(如1531883530437525)。这意味着,要处理某一帧的数据,你需要能够根据时间戳,从多个摄像头文件夹里取出同一时刻拍摄的所有图像。这通常通过annotations.json中的timestamp字段来关联。

第二个关键点是真值的稀疏性与表示。gts/下的labels.npz文件是一个压缩的NumPy数组,它并不存储一个完整的、稠密的3D网格(那将极其庞大),而是存储了在特定视角(通常是激光雷达或重建点云)下可见的那些体素(3D像素)的语义标签。这种稀疏存储是高效且实用的,因为道路上大部分空间是“空”的。

1.2 解码annotations.json:数据集的“大脑”

annotations.json文件是这个数据集的元数据核心,它定义了数据如何被组织和使用。理解它的结构,是正确加载数据的前提。

注意:在处理大型JSON文件时,建议使用ijson这类流式解析库,避免一次性加载导致内存溢出。

这个JSON文件主要包含三大部分:

  1. 数据划分 (train_split, val_split): 这是最顶层的列表,告诉你哪些场景(scene-xxxx)用于训练,哪些用于验证。这是数据集作者给定的划分,务必遵守,以保证评测的公平性。
  2. 场景信息 (scene_infos): 这是数据的核心字典。它以场景名为键,值是一个嵌套字典,详细描述了该场景下每一帧的信息。
    • frame_token: 帧的唯一标识符,是连接图像和真值的桥梁。
    • timestamp: 时间标识,用于多传感器数据同步。
    • camera_sensor: 一个字典,键为摄像头标识符(如CAM_FRONT),值包含了该摄像头在该帧下的所有关键信息:
      {
        "img_path": "trainval/imgs/CAM_FRONT/n015-2018-...jpg",
        "intrinsic": [[fx, 0, cx], [0, fy, cy], [0, 0, 1]],
        "extrinsic": {
          "translation": [tx, ty, tz],
          "rotation": [qw, qx, qy, qz] // 四元数表示
        }
      }
      
      • intrinsic(内参)将图像像素坐标转换到摄像头坐标系。
      • extrinsic(外参)将摄像头坐标系转换到车辆自车坐标系(Ego Vehicle Coordinate)。这里需要特别注意:不同数据集对坐标系的定义(如X/Y/Z轴指向,旋转顺序)可能不同,必须与你的模型坐标系对齐,否则后续的投影操作会全部错误。
    • ego_pose: 自车在世界坐标系下的位姿(位置和朝向)。对于Occupancy任务,我们通常关心的是以自车为中心的局部占据,因此这个信息可能主要用于多帧融合或某些特定模型。
    • gt_path: 指向对应真值文件(labels.npz)的相对路径信息。

一个常见的错误是直接根据文件名去拼接真值路径。更可靠的做法是遵循annotations.json中gt_path字段或通过scene_name和frame_token的映射关系来定位文件。

1.3 剖析labels.npz:真值的具体内容

用NumPy加载labels.npz文件后,你通常会得到几个数组:

import numpy as np
data = np.load('labels.npz')
print(data.files)  # 输出可能为:['semantics', 'mask_lidar', 'mask_camera']
  • semantics: 一个形状为(N,)的整数数组,N是有效体素的数量。每个整数值对应一个语义类别(如0: 空,1: 道路,2: 车辆...)。具体的类别映射关系需要查阅数据集的文档或源码(通常在class_names.py或类似文件中定义)
Occ端到端知识解析:从数据集到评测指标 本文深入解析Occupancy技术在自动驾驶领域的应用,从Occupancy3D-nuScenes-V1.0数据集的结构设计到评测指标mIoU和IoU_geo的详细实现。通过对比主流框架如BEVDepth、TPVFormer和SurroundOcc,提供实战经验与优化技巧,帮助开发者高效构建3D空间占据地图。 阅读详情

相关推荐

自动驾驶Occ感知实战:从Occupancy3D数据集解析到模型评估全流程

本文详细解析了自动驾驶Occ感知技术,从Occupancy3D-nuScenes数据集的架构与标注文件解析,到Occ模型训练的关键技术与主流架构对比,再到几何与语义双指标评估体系。文章还探讨了工业级部署优化策略,包括模型轻量化和实际工程挑战,为算法工程师提供全流程实战指南。

n8m7b6v5c4的博客 1069

自动驾驶中的Occ端到端感知:从数据标注到模型优化全解析

本文全面解析了自动驾驶中Occ端到端感知技术的实现路径。从核心原理出发,阐述了Occ(占据网络)如何通过预测3D空间占据状态来理解开放环境,并详细介绍了端到端模型如何从原始图像直接输出3D占据网格。内容涵盖高质量数据集构建、主流模型架构(如LSS与Transformer)、多任务训练优化及评测指标,最后探讨了其如何为下游规划与端到端自动驾驶奠定基础。

n7o8p的博客 207

UniOcc:统一自动驾驶3D占据感知基准,解决多数据集评测难题

在自动驾驶感知领域,3D占据网格作为一种精细的环境表示方法,正逐渐成为研究热点。其核心原理是将环境离散化为体素网格,通过预测每个体素的占据状态与语义类别,来更准确地描述任意形状的障碍物,弥补了传统3D边界框在表示不规则物体时的不足。这项技术的价值在于为自动驾驶的规划与控制模块提供了更丰富的几何与动态信息。其应用场景广泛,包括精细避障、可行驶区域分割以及运动预测等。本文聚焦于UniOcc这一统一基准,它通过标准化数据格式与评测流程,解决了当前研究者在nuScenes、Waymo等多源数据集上验证模型时面临的“

weixin_34248023的博客 449

纯视觉OCC技术原理与性能评测全解析

Occupancy Network(OCC)是自动驾驶中从二维目标检测迈向三维空间可通行性建模的关键范式升级,其核心在于以体素网格替代传统检测框,直接输出空间占用概率。技术实现依赖BEV特征到三维体素的跨维度映射、动静态解耦建模、时序一致性约束及体素粒度优化等底层机制。相比激光雷达依赖方案,纯视觉OCC在成本、迭代效率与系统简洁性上具备显著优势,但面临深度估计失真、雨雾反光干扰、边界模糊等工程挑战。当前主流评测已摒弃mAP等传统指标,转而采用占用精度(OA)、边界锐度(BS)、时序稳定性(TS)和场景泛化鲁

weixin_29040367的博客 380

自动驾驶英文缩写大全:从BEV到OCC,一文搞定行业术语

自动驾驶作为多学科交叉领域,其技术术语大量以英文缩写形式出现,成为新人融入团队和阅读论文的隐性门槛。从感知层的BEV鸟瞰视角、OCC占用网络,到规划控制层的MPC模型预测控制,再到安全测试的ASIL等级与HIL在环仿真,每个缩写都对应一套完整的工程体系与算法原理。理解这些术语不能仅靠翻译全称,还需明确其应用场景、相邻概念及易混淆点。本文以技术栈为脉络,系统梳理感知、定位、规划、通信、安全等核心环节的高频缩略语,结合论文阅读、代码调试与工程实践中的真实案例,帮助读者建立术语与系统模块的关联,快速提升在技术评审

weixin_34060741的博客 462

SurroundOcc 实战:从数据加载到可视化,构建端到端3D场景重建流程

本文详细介绍了SurroundOcc在3D场景重建中的端到端流程,从数据加载到可视化,特别适合自动驾驶和机器人感知场景。通过实战案例和优化技巧,帮助开发者快速掌握多摄像头3D重建技术,提升重建质量和效率。

weixin_29053073的博客 211

使用 Mid360 从零开始搭建实物机器人入门级导航系统 —— 基于 Fast_Lio 和 Move_Base

本文详细介绍了如何使用Mid360机器人从零开始搭建一个基于Fast_Lio和Move_Base的入门级导航系统。通过配置 ROS2、集成激光雷达、IMU、Fast_Lio、Move_Base 等模块,我们成功构建了一个能够实现自动导航的机器人系统。在实际开发中,随着需求的变化,你可以不断调整参数、优化路径规划算法、增加新的传感器等,逐步提升机器人的智能与功能。

小蜗牛的珍贵百宝箱 3568

驯服电源尖峰:从BUCK/BOOST环路剖析到高di/dt噪声的实战抑制

本文深入探讨了电源系统中高di/dt噪声的产生机制及抑制方法,通过BUCK/BOOST电路的环路分析,揭示了电流路径不连续导致的电压尖峰问题。文章提供了实用的PCB布局技巧和噪声抑制策略,包括最短回路原则、铺铜优化和过孔阵列战术,帮助工程师有效降低EMI噪声,提升电源系统的稳定性。

weixin_29587015的博客 275

首个基于LBS方案的3D传感器,VoxelSensor解析

该传感器将结合OQmented的Lissajous模式的MEMS扫描镜,与每帧逐行工作的光栅扫描相比,Lissajous轨迹扫描速度更快,并且能耗很低,它可以更快地捕获完整的场景和快速移动,并且需要更少的数据处理,可满足AR/VR对于低延迟、高效率的需求。简单来讲,Switching Pixels的区别是专注于识别激光事件,性能比普通事件相机更好,但也可以使用事件相机的算法。在具体应用中,它需要在X和Y方向发射一个或多个脉冲光束,以在X和Y轴上定位,而Z轴,也就是深度,则是通过计算光返回的时间来测量。

qingtingwang的博客 576

Win11下Wezterm配置Powershell默认终端全攻略(含主题同步技巧)

本文详细介绍了在Windows 11系统中,如何安装和配置Wezterm终端模拟器,并将其设置为PowerShell的默认终端。内容涵盖使用Winget或手动安装Wezterm,通过修改.lua配置文件切换默认Shell,并同步Campbell主题配色以还原熟悉的PowerShell视觉体验,旨在帮助开发者打造高效、个性化的命令行工作环境。

weixin_28363123的博客 1237

使用VNA(Vector Network Analyzer)对S参数进行去嵌(二)

无论是使用 EM 仿真工具创建的简化模型(如一段理想传输线)还是复杂模型用于测试夹具,现在都需要使用该 S 参数模型执行去嵌入过程。

小孟同学的博客 6111

CXSMILES细则-用于在 SMILES 字符串后存储分子的特殊特征

Chemaxon 扩展 SMILES/SMARTS 用于在 SMILES 字符串后存储分子的特殊特征。任何信息都可以存储在 SMILES 字符串后,只要它们由空格或制表符字符分隔,因为 SMILES 解析器会忽略这些信息,或者将它们作为注释使用。扩展特征以以下格式存储:Chemaxon 的扩展 SMILES/SMARTS 不包含非 ASCII 字符,它们通常以字符代码 n 的形式被转义为 &#n;。在 S-group 中,ASCII 字符“,”、“;”、“|”、“{”、“}”也以这种方式转义。此外,符号“$

ASKCOS博客 402

ThingsBoard3.9.1规则引擎方式发送钉钉通知消息

thingsboard3.9.1/4.0规则链方式发送钉钉通知消息。

hssjf的专栏 531

vue3 - 高德地图定位出错Get ipLocation failed.Geolocation permission denied.(info: “FAILED“ | status: 0)报错解决!

vue3,nuxt3,高德地图,定位,位置,报错,AMap.Geolocation,解决报当前定位失败,高德地图H5 定位失败报错,web网页网站,报错详细解决教程,Get ipLocation failed.Geolocation permission denied.,高德地图定位报错info: "FAILED",高德地图status: 0,已经是https了还是报错,确保了浏览器位置已经开了,手机定位也开了,没解决,H5页面在ios的浏览器上使用 高德地图 报当前定位失败Geolocation,移动端设

✅ 精选推荐文章 6771

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: LangGraph实战:如何通过Human-in-the-loop机制优化AI工作流决策
下一篇: eNSP实战:中小型企业网络中的VLAN划分与DHCP动态分配
code8
博客等级 码龄17年 65粉丝 1720原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值