资讯详情 恶劣天气三维重建:3D高斯Splatting雨雾场景全流程解析
📅 2026/10/11 11:26:25
简介面向恶劣天气下室外场景三维重建的项目包基于高斯Splatting算法实现解决雨、雾、雪等天气干扰导致重建精度下降的问题。包内包含完整源码与流程教程覆盖数据采集、模型训练、渲染到评估全流程适合计算机视觉研究者、三维重建开发者及中高级学习者压缩包共37个文件以24个Python脚本为主涵盖训练、渲染、评估等核心模块另含9张对比效果图、YAML环境配置、Shell运行脚本、SVG图标及README文档整体体积约3MB结构清晰。目前已有277人学习浏览内容实用性得到初步验证。项目通过高斯核函数平滑与插值处理增强点云表面连续性和重建精度同时提供环境配置与运行脚本可快速复现实验教程部分详细说明从图像采集到三维模型输出的操作细节配套示例图片便于直观对比。该实现不仅能服务城市规划、交通监控还能在灾害应急中快速建模分析具有较高的学术与实用价值。1. 恶劣天气三维重建为什么3D高斯遇到雨雾就“翻车”以及它到底在解决什么把相机架到室外对着街道、工地或园区拍一圈视频然后让算法重建出可自由漫游的三维场景——这件事在晴天已经不算新鲜3D高斯Splatting3D Gaussian Splatting业内常直接叫3DGS凭借分钟级训练和高质量渲染成了这两年三维重建方向最“能打”的算法之一。但同样一套流程只要把拍摄时间挪到雨夜、雾霾天或是沙尘天气重建结果立刻会变得没法看远处楼体发虚、路面积水处浮起一层“雾状噪点”、雨丝被当成实体结构固化在场景里甚至整个模型出现半透明的重影。问题不出在采集设备也不出在相机标定而是出在算法对“场景是什么”和“天气是什么”的区分能力上。这正是标题里那套“恶劣天气条件下的室外场景三维重建算法”要解决的事在3DGS的基础上加入天气退化建模先识别并剥离雨雾、雨丝、雪片对成像的干扰再重建干净且几何一致的场景辐射场。它的落点不是“把图修干净”而是让重建出来的三维模型在几何精度和渲染质量上同时扛住恶劣天气的干扰。适合谁适合正在做室外三维重建、自动驾驶仿真场景生成、数字孪生和城市级模型采集的工程师也适合刚入门高斯Splatting、想找一个能写进简历的完整实战项目的同学。下面我会按“表示原理 → 天气建模 → 完整流程 → 常见问题 → 验证方法”的顺序把这条链路拆开讲透所有操作都按可直接复现的标准来写。2. 高斯Splatting在室外场景的表示与优化从点云稀疏重建到可微渲染2.1 为什么选3D Gaussian而不是NeRF或传统MVS室外恶劣天气场景下传统多视图立体匹配MVS很容易在弱纹理区域天空、墙面、雾霾遮挡后的远处产生深度空洞因为MVS本质上依赖特征匹配而雨雾恰恰是破坏特征一致性的头号凶手。NeRF虽然对视图退化有一定鲁棒性但训练速度慢几百张图就要训练数小时甚至更久户外采集的场景往往上万帧NeRF的时间成本撑不住工程迭代。3DGS的做法是把场景表示成几百万个带空间位置、形状和颜色的三维高斯椭球通过可微光栅化直接渲染成图像在前向传播里避开NeRF那种逐点采样射线的昂贵计算。训练速度可以比NeRF快一个数量级以上而且显存占用更可控这对“采集了很大一片室外区域、需要在合理时间内出结果”的项目来说很关键。更妙的是3DGS本质上是一个“显式”表示每个高斯的位置、大小、不透明度都能单独访问这意味着我们可以在天气退化模型里对特定高斯做“体检”判断它到底是真实几何还是雨雾伪影——这种可解释性是NeRF的隐式场很难给出的。2.2 3D Gaussian的核心属性位置、协方差、颜色与不透明度3DGS把场景离散成一组三维高斯分布每个高斯由五类参数组成中心位置 μ、三维协方差矩阵 Σ、球谐系数 SH用于表达视角相关颜色、不透明度 α以及一个缩放矩阵和旋转四元数用来参数化协方差保证 Σ 半正定。渲染时这些高斯被投影到二维图像平面按深度排序后做alpha混合得到像素颜色。优化目标是最小化渲染图像与真实采集图像的差异通常用L1损失加上一个D-SSIM结构相似度项。用代码来定义一个高斯的初始结构大致长这样class GaussianModel: def __init__(self, num_points): # 位置从稀疏点云初始化形状为 [N, 3] self.xyz torch.zeros(num_points, 3) # 缩放每个轴一个取对数保证协方差正定 self.scaling torch.zeros(num_points, 3) # 旋转四元数表示长度4归一化后使用 self.rotation torch.zeros(num_points, 4) # 不透明度经过sigmoid前是logit范围不受限利于梯度下降 self.opacity torch.zeros(num_points, 1) # 球谐系数视角相关颜色0阶就是漫反射3阶已能覆盖大多数室外材质 self.shs torch.zeros(num_points, 16, 3)这段初始化代码里有几个值得注意的设计。第一缩放和旋转分开存缩放取对数可以避免优化过程中协方差矩阵变成非半正定这是新手最容易忽略的细节直接用协方差矩阵的六个分量做梯度下降大概率训练到一半就会崩溃。第二不透明度用logit空间存储理由是它经过sigmoid后才会映射到0到1区间梯度在两端不会饱和。第三球谐阶数我一般选3阶室外场景的天空和路面有很强的视角光泽效应0阶漫反射完全不够但再往上加维度对内存的消耗会显著增加对恶劣天气这个场景来说收益有限。2.3 从COLMAP输出到Gaussian初始化的数据管线3DGS不是从随机点开始的它依赖COLMAP产出的稀疏点云作为初始几何。标准流程是先对输入视频抽帧然后做SFM运动恢复结构得到相机位姿和稀疏点云再把稀疏点云喂给3DGS作为初始高斯基元。这步听起来简单但在恶劣天气下COLMAP本身就是第一个瓶颈雾气会让特征检测器找到大量“伪特征点”——它们反复出现在不同帧的同一片雾气区域但对应的物理位置并不存在。一个实用的缓解策略是先在原始图上跑一遍去雾预处理再做特征提取。我一般不会用太重的深度学习去雾网络而是先用基于暗通道先验的快速去雾把图像“压”到COLMAP能接受的特征质量范围跑完SFM后再回到原始带雾图像做训练。为什么这样做因为去雾网络会改变图像的颜色分布如果直接用去雾后的图像训练3DGS会让颜色偏灰重建出来的场景像蒙了一层滤镜而只用它辅助特征匹配误差是可以接受的。# 伪代码读取COLMAP生成的稀疏点云转为高斯初始化数据 import numpy as np import torch from pathlib import Path def init_gaussians_from_colmap(sparse_dir: Path, num_sh_coeffs: int 3): cameras, points3D read_colmap_model(sparse_dir) # 自己实现或复用pycolmap xyz torch.tensor(points3D[xyz], dtypetorch.float32) # 稀疏点云的RGB直接作为0阶球谐的初值 shs torch.zeros(len(xyz), (num_sh_coeffs 1) ** 2, 3) shs[:, 0, :] torch.tensor(points3D[rgb], dtypetorch.float32) / 255.0 # 离群点过滤与最近邻距离超过3倍中位数的直接丢掉 dist nearest_neighbor_distance(xyz) keep dist 3.0 * torch.median(dist) return xyz[keep], shs[keep]初始化的细节直接决定训练能不能收敛。COLMAP的稀疏点云通常包含大量误差较大的离群点尤其在有雨雾遮挡时这些点会出现在完全错误的空间位置如果全部保留训练早期梯度会被这些“野点”带着跑。按最近邻距离的中位数做三倍标准差过滤是最稳妥的做法既不会过度删点导致初始化几何稀疏又能把明显飘在空中的野点清理掉。过滤之后的高斯数量一般在几十万到两三百万之间具体取决于场景大小和COLMAP匹配到的特征数。3. 把雨雾雪写进成像方程天气退化模型的搭建与训练数据构造3.1 大气散射模型把雾霾写成数学公式要处理恶劣天气首先得知道天气是怎么破坏图像的。最常见的物理模型是大气散射模型相机看到的像素强度 I(x) 等于目标反射光经过衰减后的结果加上大气光散射的干扰。公式上写成 I(x) J(x)·t(x) A·(1 - t(x))其中 J(x) 是清晰场景辐射t(x) 是介质透射率A 是大气光。透射率 t(x) 又和场景深度 d(x)、大气衰减系数 β 挂钩t(x) exp(-β·d(x))。换句话说雾对图像的破坏是深度相关的——远处的物体透射率低退化严重近处的物体相对干净。这是去雾算法的基础也是恶劣天气三维重建必须显式建模的地方。普通去雾算法到这里就结束了输出一张干净图。但三维重建比去雾要更进一步我们需要给每个三维高斯基元估算出一个“天气属性”或者更准确地说在辐射场里把“干净的场景辐射”和“天气散射场”分开优化。大气光 A 在现实场景中不是常数它会随方向变化尤其是天空方向的大气光远强于地面方向如果把 A 当成全局常数重建出的模型在天空区域会泛白地面上则出现偏色。我在项目里通常把大气光建模成一个低阶球谐函数而不是标量# 用球谐函数表示方向相关的大气光 class DirectionalAtmosphericLight: def __init__(self, sh_degree2): # 每个通道 9 个球谐系数近似描述不同方向的大气光强度 self.sh_coeffs torch.zeros(3, (sh_degree 1) ** 2) # 初始化为灰白色光 self.sh_coeffs[:, 0] 0.8 def get_A(self, view_dir): 输入视线方向 [B, 3]输出大气光 [B, 3] return evaluate_sh(self.sh_coeffs, view_dir)把 A 从标量升维成方向相关以后模型能同时照顾“天空方向泛白”和“地面雾气偏灰”这两种不一致的退化代价只是多了几十个参数对训练负荷可以忽略。这个改动算是我做恶劣天气重建时收益最高的小模块比单纯加深网络更直接。3.2 双分支解耦天气特征与三维场景分开学恶劣天气下观察图像里的“雾感”并不全是叠加在清晰图像上的雨雪还带来高频条纹和运动模糊。雨丝在图像里是明亮的短线本质上是前景物体雨滴快速移动在曝光时间内划出的轨迹雪花则是更大面积的散焦光斑。把雨雪当成大气散射去处理是不成立的它们和雾的物理机制完全不同。所以架构上我采用双分支解耦策略一个分支负责重建干净的场景辐射场 J(x)一个分支负责估计天气退化场 W(x)——雾霾用透射率图表示雨雪用条纹密度场表示。渲染时把两个分支的输出合成加噪图像I(x) J(x)·t(x) A·(1-t(x)) RainField(x)。这样优化器的压力被分摊了场景分支只负责学习稳定的几何和材质天气分支只负责吸收雨雾的干扰。如果没有这个解耦结构优化器会把雨丝硬解释成场景中的高反射表面重建结果就是“玻璃渣”效果。实际实现时我给天气分支单独设了更高的学习率并且限制它的作用范围——用拉普拉斯平滑约束让透射率图足够平滑避免天气分支把场景纹理也“吃”进去loss_tv torch.mean(torch.abs(transmittance[..., 1:] - transmittance[..., :-1])) \ torch.mean(torch.abs(transmittance[..., 1:, :] - transmittance[..., :-1, :])) loss_weather loss_render 0.05 * loss_tv这里的0.05是平滑项的权重太小则透射率图会出现棋盘格状的噪声太大会把远处的物体边缘也抹掉。数据上我一般会在训练时先把透射率图的初始值设为全1也就是假设初始状态没有雾让优化器在需要的时候再往下调如果反着初始化为全0.5模型会把场景整体劈成两半一半特别亮一半特别暗而且很难自己恢复过来。3.3 合成雨雾数据给干净场景加退化训练恶劣天气重建模型最大的现实困难是数据真实采集的成对“雨天/晴天”数据几乎不可能对齐因为场景在不断变化车辆、树叶、光照。工程上被验证过的路是用合成数据——在干净场景上叠加物理模型生成雨雾退化图让模型在有监督信号的情况下学习解耦。下面是一个合成雨天样本的简化代码import cv2 import numpy as np def add_rain_effect(clean_img, density0.15, length15, angle30): h, w clean_img.shape[:2] rain np.zeros((h, w), dtypenp.float32) # 随机生成雨丝按泊松分布控制数量 num_drops int(density * h * w) for _ in range(num_drops): x0, y0 np.random.rand(2) x0, y0 int(x0 * w), int(y0 * h) angle_rad np.deg2rad(angle np.random.uniform(-10, 10)) dx, dy length * np.cos(angle_rad), length * np.sin(angle_rad) brightness np.random.uniform(0.3, 0.9) cv2.line(rain, (x0, y0), (int(x0 dx), int(y0 dy)), brightness, 1) # 雨丝模糊化模拟运动模糊 rain cv2.GaussianBlur(rain, (3, 3), 0) # 叠加雾效深度越远雾越浓 depth_map generate_fake_depth(h, w) t np.exp(-0.03 * depth_map) A np.random.uniform(0.6, 0.9) foggy clean_img * t[..., None] A * (1 - t[..., None]) rainy foggy rain[..., None] * 0.2 return np.clip(rainy, 0, 1), t这个合成为什么要这么做雨滴在真实曝光里不会是一条锐利直线运动模糊会让它变成半透明的短线所以画完线以后要GaussianBlur。雾效叠加时用了深度相关的透射率模拟的是远处更模糊的物理规律深度图在真实数据里可以由COLMAP稀疏重建结果插值得到这也是为什么流程里先做COLMAP再做数据合成更合理。合成数据的退化应该尽量“有限”——如果合成的雨比真实更密、雾比真实更重模型的天气分支会趋向于把所有东西都解释成天气反而把真实几何学得稀烂。4. 从视频帧到天气鲁棒模型完整流程与核心参数4.1 环境准备PyTorch、CUDA与可微光栅化器3DGS依赖可微光栅化器通常自己编译一个CUDA扩展。环境上我推荐用Anaconda建独立环境Python版本选3.9或3.10PyTorch版本需要和CUDA匹配。这里给出一套我验证过的安装顺序conda create -n gsweather python3.10 -y conda activate gsweather pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install plyfile tqdm wandb opencv-python pycolmap git clone --recursive gaussian-splatting仓库地址 cd 仓库目录 pip install -e submodules/diff-gaussian-rasterization pip install -e submodules/simple-knn注意事项有几个版本不匹配是黑匣子报错的重灾区比如CUDA是12.x却装了cu118的PyTorch光栅化器编译过了运行时会直接段错误还有不建议用最新版PyTorch因为部分老版本CUDA扩展的算子写法没跟上新API编译能过前向传播数值全错。显存管理方面室外场景分辨率不要一上来就开1080p先用512p跑通流程再往上加一张12G的RTX 4070在512p下能处理大约200帧的序列超过这个规模就需要做分块训练。4.2 数据准备帧提取与COLMAP稀疏重建室外数据采集的基线建议是绕场景走一圈帧率25fps的视频提取每5帧一张保证相邻帧之间有足够的视野重叠。提取帧数和场景复杂度匹配好后直接进COLMAP。这个阶段唯一需要手工干预的是删掉模糊帧和曝光突变帧这类帧在恶劣天气里尤其多。# 每5帧提取一张输出到项目目录下 ffmpeg -i raw_video.mp4 -vf fps5 -qmin 1 -qmax 1 frames/%06d.jpg # COLMAP特征提取与匹配从0.4.0版本开始匹配器是graph-based colmap feature_extractor --database_path db.db --image_path frames --ImageReader.camera_model OPENCV colmap exhaustive_matcher --database_path db.db --SiftMatching.use_gpu 1 # 稀疏重建与导向三角化 colmap mapper --database_path db.db --image_path frames --output_path sparse colmap model_converter --input_path sparse/0 --output_path sparse_text --output_type TXTCOLMAP的SIFT匹配在雾天很容易在天空区域爆发海量匹配对它们对应的三角化点会落在非常近的深度上形成一片贴近相机的“雾墙”。我一般会在跑mapper之后检查一下sparse_text里的点云数量分布如果靠近相机的点占比异常高超过总量的20%就需要做一次位姿筛选把匹配对集中在天空区域的图像删掉一部分再重跑。这个规律的判断依据是真实的室外场景几何大体上空间分布均匀不会出现大量点集中贴在相机跟前。4.3 训练启动命令行与关键参数训练命令在官方框架基础上需要加入天气分支的开关和权重。核心参数是迭代次数晴天场景一般3万步就够恶劣天气建议加到5万步以上——因为优化器不仅要拟合几何还要同时解开天气场收敛会更慢。位置学习率衰减是另一个敏感项默认的1.6倍指数衰减到1万步以后会变得极慢天气分支还在学透射率主干已经冻结导致出现“几何清晰但雾没去掉”的半成品。我的做法是把位置学习率衰减延后到2万步才开始。python train.py \ --source_path ./data/scene_dir \ --model_path ./output/scene_dir \ --iterations 50000 \ --position_lr_init 0.00016 \ --position_lr_final 0.0000016 \ --position_lr_max_steps 30000 \ --lambda_tv 0.05 \ --weather_branch on参数说明position_lr_init设为0.00016是官方默认值一般不动weather_branch控制是否开启天气分支不开启等价于普通3DGSlambda_tv是透射率平滑权重前面说过太低会出棋盘格太高会糊边。还有一个容易被忽略的参数是densify_grad_threshold它控制高斯分裂/克隆的梯度阈值恶劣天气下天气伪影会给场景分支带来异常大的梯度阈值比默认值上调一点比如从0.0002调到0.0005能抑制高斯基元在雨雾区域疯狂繁殖。4.4 评估天气场景不能只看PSNR三维重建的评估通常以PSNR、SSIM、LPIPS三个指标为准但在恶劣天气场景下这些指标有一个致命的盲区它们全部是在图像空间做比较只要渲染出来的图像和真实图像接近就打分高并不区分这个“接近”是靠正确几何还是靠把雾“渲染”出来的。换句话说一个过拟合了天气效果、完全没有重建出干净几何的模型也能拿到很高的PSNR。所以我在做天气鲁棒性评估时一定会加一组额外的验证指标计算方式作用PSNR / SSIM / LPIPS渲染图 vs 真实图基础图像质量去雾图一致性天气分支输出的透射率图去雾后 vs 模型渲染图验证天气分支没有偷吃几何信息几何平滑度高斯基元的尺度分布标准差数值上没有大面积细碎高斯的天气伪影5. 恶劣天气三维重建避坑五个实际案例的现象、原因与修法5.1 天空区域出现大片黑色空洞现象重建后的模型从某些视角看天空位置出现明显黑色或全透明的空洞换个视角又恢复了。原因天空区域在COLMAP里几乎没有特征点稀疏点云缺失3DGS在这里没有初始高斯基元训练过程中如果不主动在那里克隆高斯就会一直空着。恶劣天气下天空更是一片死白特征匹配彻底失效空洞概率大增。解决在COLMAP之后做一次背景点云补全把天空区域按远距离均匀撒点注意点的颜色设为天空的均值色。补充的点不需要很密集它们的作用是给优化器一个“这里该有东西”的提示后续密集化会把细节补上。如果补点后仍有小洞把densify_until_iter调大让克隆操作多持续一段时间。5.2 雨丝被重建进模型出现“玻璃渣”效果现象渲染出来的模型表面附着许多细长的高亮条纹像玻璃碎渣贴在墙上运动起来还会闪烁。原因工具链里没有开天气分支或天气分支权重太低。优化器无法区分雨丝和场景几何只能为它们分配高斯基元且这些基元尺度极小、数量极大专门用来拟合雨丝的高频亮纹。解决开了weather_branch之后仍出现少量渣点直接用稠密度阈值过滤把尺度小于某个体积阈值的高斯删除。我通常的做法是遍历所有高斯的scaling参数小于0.0001的直接从模型里移除这一步对画质几乎没有肉眼可见影响但能显著减少“玻璃渣”。5.3 远景出现抖动和半透明重影现象模型在漫游时远处的山体或楼宇边缘出现抖动、闪烁还有轻微的半透明双影。原因恶劣天气下远景透射率低观测到的颜色信噪比低梯度信号弱优化器对远景几何的约束不足同时因为雾的存在同一物理点在不同帧里呈现不同的颜色和对比度优化器在中间状态反复摇摆最终落在一个“平均”位置上。解决给远处的透射率施加更强的平滑先验让天气分支把远景雾袪得更彻底还原出更锐利的信号供几何分支学习还可以对远景区域加大稠密化频率——具体做法是把densify_grad_threshold在远景的投影区域调低让更多高斯被克隆到远处去拟合细节。5.4 训练不收敛loss卡在某个高位不降现象训练前几千步loss下降正常到了某个位置突然停滞而且一停就是几万步看不出恢复迹象。原因最大概率是学习率设置不当或数据里有大量模糊帧。恶劣天气数据尤其容易混入对焦不准的帧这类帧对loss的贡献是持续的高误差不会被优化掉只能把整体loss钉死在那里。解决训练前遍历所有帧用拉普拉斯算子的方差检测模糊度把得分最低的帧删掉。另外检查position_lr_max_steps是否设置得过小导致几何分支过早冻结天气分支独自挣扎把它调到总迭代数的60%左右是我最常用的设置。5.5 GPU显存溢出现象训练进行到中段突然报CUDA out of memory前面一切正常。原因3DGS的显存消耗是动态的——随着稠密化进行高斯基元数量会从几十万涨到几百万每个基元的球谐系数在3阶时要占48个浮点数数量翻十倍显存直接爆炸。恶劣天气下生成的高斯数量通常远超晴天因为雨雾伪影和真实几何在争夺空间两边都在疯狂繁殖。解决最有效的是限制最大高斯数量在稠密化逻辑里加上总数截断超过阈值后触发一次剪枝删除不透明度低于阈值的和尺度异常大的高斯。其次可以降低图像分辨率或开启分块训练把场景拆成几个重叠块分别训练最后合并。6. 进阶验证技巧用消融实验和可视化证明模型真的“抗天气”6.1 消融实验证明每个模块都起作用如果你要把这套流程做成一个项目交付或者写进论文和技术报告“天气分支到底有没有用方向相关大气光到底有没有用”必须有数字撑腰。消融实验的最低配置是四组完整模型、去掉天气分支退化为普通3DGS、把方向相关大气光换成全局标量、去掉透射率平滑项。每组在同一个数据集上跑同样的迭代数记录PSNR、SSIM和LPIPS同时把天气分支输出的透射率图保存下来做对比。有一个实用的观察点在雨天数据上带天气分支的模型PSNR可能只比普通3DGS高0.5到1dB这个差距看着不大但如果用“去雾后的渲染图”去做对比差异会非常明显——普通3DGS去雾后是灰蒙蒙的而完整模型去雾后边缘锐利、对比度高。这个对比才是恶劣天气重建的真正收益点。6.2 天气鲁棒性可视化给高斯基元按天气相关度染色数字指标之外我习惯做一张“天气相关度分布图”——把每个高斯的不透明度变化量与天气分支输入的相关性算出来然后按这个值给高斯基元染色越红代表越可能属于天气伪影越蓝代表越可能是真实几何。这个可视化能直观回答一个关键问题模型是真的理解了天气还是碰巧在某个局部区域拟合得好。# 伪代码计算每个高斯对天气输入的梯度敏感性 def compute_weather_sensitivity(gaussians, renderer, view): output renderer(gaussians, view) weather_grad torch.autograd.grad(output.sum(), gaussians.weather_attr, retain_graphTrue) sensitivity weather_grad[0].norm(dim-1) # 归一化到 [0, 1] 后映射到热力图色标 return sensitivity从这批图里通常能看出一个规律雨丝区域的敏感性显著高于墙面、地面而远处山体也偏高。前者是对的后者说明模型把雾的退化和对应几何混合在一起了提示我需要加强远景的透射率平滑。6.3 我总结的三条实操习惯恶劣天气三维重建做过三轮迭代我自己的经验是第一永远不要在纯合成数据上收敛后就上真实场景中间隔着一个巨大的域差距先在真实雨天视频帧上做微调再交付第二COLMAP阶段花的时间应该占总流程的一半以上这一半时间省下来后面训练和调试要多花两倍去填第三不要迷信单次训练结果同一组数据跑两次把两次结果做diff你会发现恶劣天气下两次重建的差异远大于晴天这是评估模型稳定性的一个常用手段。说到第三点我做项目时经常用这种方式检查——第一次全流程跑通后看到的闪烁、空洞很多其实是稳定性问题而不是精度问题把两次重建做平均效果往往比单次调参数更好。这套流程我自己踩了不少坑才理顺希望帮到你。本文还有配套的精品资源点击获取