海面溢油检测数据集:1800张VOC+YOLO双格式实战指南

发布时间:2026/9/28 23:29:02

海面溢油检测数据集:1800张VOC+YOLO双格式实战指南 简介这份资源是面向计算机视觉与目标检测学习者的海面石油原油泄漏检测数据集适用于环境监测、海上应急响应等场景下的模型训练与算法验证。数据集共1817张jpg图片每张均配有对应的VOC格式xml标注与YOLO格式txt标注标注类别为oil_spillage共3871个标注框说明部分图片中存在多个泄漏点可支撑多目标检测任务。压缩包内文件总数2000个以1817个xml标注文件和183个txt文件为主整体约79.05MB采用labelImg完成标注格式规范、类别单一便于直接接入YOLO或Faster R-CNN等主流检测框架。目前已有283人学习下载适合需要快速构建泄漏检测基线模型、验证数据增强策略或开展迁移学习实验的读者参考使用。1. 海面溢油检测数据集1800 张 VOCYOLO 到底能训出什么海面石油原油泄漏的遥感与近岸监控里目标检测要解决的核心问题很具体把水面上那层反光的油膜从太阳耀斑、云影、船舶尾迹和生物藻华里分出来。这个标题给的是一个 1800 张规模、同时提供 VOC 与 YOLO 两种标注格式的数据集直接对准了目标检测训练链路里最耗时的环节——数据准备。它适合三类人想快速验证溢油检测模型可行性的算法工程师、需要做海面异常目标检测但缺标注数据的在校研究者、以及要把检测能力嵌进岸基或无人机巡检系统的落地开发者。1800 张不算大但双格式意味着你不用自己写转换脚本就能分别喂给 YOLO 系列和基于 VOC 的框架省下的时间足够你多跑几轮消融实验。2. 溢油检测为什么难从油膜光学特性到标注边界2.1 油膜在图像里到底长什么样原油泄漏到海面后会经历扩散、乳化、风化几个阶段不同阶段在可见光和红外图像上的表现完全不同。新鲜油膜在可见光下呈现高反射的银灰色或彩虹色干涉条纹和太阳耀斑的镜面反射高度相似乳化后的油水混合物偏棕褐色对比度低容易和悬浮泥沙混淆薄油膜则几乎透明只在特定太阳高度角下才显现。这意味着标注时不能只靠颜色还要结合纹理和上下文——油膜通常有连续的边界和内部纹理渐变而云影边界更锐利、内部更均匀。从检测模型的角度看溢油目标有几个麻烦特性尺度变化极大从几米宽的船用燃油泄漏到几公里长的井喷油带都可能出现形状不规则没有固定长宽比正负样本极度不平衡一张图里可能只有一小块油膜其余全是海水。这些特性决定了数据增强策略和损失函数的选择不能照搬通用目标检测的默认配置。2.2 VOC 与 YOLO 格式的差异不只是文件结构VOC 格式用 XML 描述每张图的标注包含 filename、size、object 列表每个 object 有 name、bndboxxmin/ymin/xmax/ymax。YOLO 格式用每张图对应的 txt 文件每行是 class_id x_center y_center width height全部归一化到 0-1。表面看只是坐标表示不同实际影响的是训练管线的几个环节。VOC 的绝对坐标在数据增强时更直观比如你要做随机裁剪后重新计算框位置绝对坐标加减就行YOLO 的归一化坐标在缩放和填充时更省事因为不用管原图尺寸。另一个差异是类别管理VOC 在 XML 里写类别名YOLO 用数字 id需要额外维护一个 classes.txt 或 data.yaml。如果你打算用 YOLOv8 训练官方推荐 YOLO 格式如果要用 Detectron2 或 MMDetectionVOC 转 COCO 更顺。这个数据集同时给两种格式等于把选择权留给了你。2.3 1800 张的规模怎么用才不浪费1800 张在目标检测里属于小数据集直接从头训一个 backbone 几乎必然过拟合。合理的做法是分两步先用 COCO 或 Objects365 预训练权重初始化再在溢油数据上微调。微调时冻结 backbone 的前几层只训 neck 和 head学习率设小一点比如 1e-4 到 1e-3 之间。如果溢油目标和预训练类别差异大可以解冻更多层但要注意监控验证集损失一旦连续几个 epoch 不降就停。另一个策略是把它当验证集用。如果你有更大的海面图像库但没有标注可以用这 1800 张训一个基线模型然后对无标注图像做伪标签人工筛选后再加入训练。这个过程迭代两三轮有效数据量能翻倍。但伪标签的阈值要设高比如置信度 0.7 以上才保留否则错误会累积。3. 把 VOC 转成 YOLO脚本、参数与四个边界坑3.1 转换脚本的核心逻辑虽然数据集号称双格式但实际拿到的 VOC 标注可能需要你自己转成 YOLO 来适配特定训练框架。下面这个脚本处理单目录下的所有 XML输出对应的 txt。关键点是坐标归一化和类别映射。import xml.etree.ElementTree as ET import os from pathlib import Path # 类别映射根据你的数据集实际类别修改 CLASS_MAP {oil_spill: 0, ship: 1, look_alike: 2} def voc_to_yolo(xml_dir, out_dir, img_dir): xml_dir Path(xml_dir) out_dir Path(out_dir) out_dir.mkdir(parentsTrue, exist_okTrue) for xml_file in xml_dir.glob(*.xml): tree ET.parse(xml_file) root tree.getroot() # 读取图像尺寸优先从 XML 的 size 节点取 size root.find(size) if size is not None: w int(size.find(width).text) h int(size.find(height).text) else: # 兜底用 PIL 读原图尺寸 from PIL import Image img_path Path(img_dir) / (xml_file.stem .jpg) with Image.open(img_path) as im: w, h im.size lines [] for obj in root.findall(object): name obj.find(name).text.strip() if name not in CLASS_MAP: continue # 跳过未定义类别 cls_id CLASS_MAP[name] bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 裁剪到图像边界内防止越界 xmin max(0, min(xmin, w)) ymin max(0, min(ymin, h)) xmax max(0, min(xmax, w)) ymax max(0, min(ymax, h)) # 跳过无效框 if xmax xmin or ymax ymin: continue # 归一化并计算中心点 x_center (xmin xmax) / 2.0 / w y_center (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}) out_file out_dir / (xml_file.stem .txt) out_file.write_text(\n.join(lines), encodingutf-8) # 调用示例 voc_to_yolo(annotations_xml, labels_yolo, images)逻辑说明先解析 XML 拿到图像宽高优先用 XML 里的 size 节点因为有些数据集的原图可能被裁剪过而 XML 没更新这时用 PIL 读实际文件更可靠。然后遍历每个 object做类别映射把绝对坐标转成归一化的中心点加宽高。裁剪到边界内是必须的我见过不少 VOC 标注的 xmax 超出图像宽度不处理的话 YOLO 训练时归一化坐标会大于 1导致损失计算异常。参数说明CLASS_MAP 要根据你的数据集实际类别改如果只有油膜一个类就写 {oil_spill: 0}。输出精度用 6 位小数足够YOLO 官方也是这个精度。如果 XML 里有些 object 的 name 不在映射表里脚本会跳过建议先统计一下所有出现的类别名再决定是跳过还是合并。3.2 转换后必须做的三项校验转换完不能直接开训至少做三项检查。第一统计每张图的框数量如果某张图 txt 为空但 XML 里有 object说明类别映射漏了。第二随机抽 10 张图用可视化脚本画框确认框位置和原图对齐。第三检查归一化坐标是否都在 0-1 之间有超出就说明边界裁剪没生效。import cv2 import numpy as np from pathlib import Path def visualize_yolo(img_path, label_path, class_names): img cv2.imread(str(img_path)) h, w img.shape[:2] lines Path(label_path).read_text().strip().split(\n) for line in lines: if not line: continue parts line.split() cls_id int(parts[0]) xc, yc, bw, bh map(float, parts[1:5]) # 反归一化 x1 int((xc - bw/2) * w) y1 int((yc - bh/2) * h) x2 int((xc bw/2) * w) y2 int((yc bh/2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, class_names[cls_id], (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cv2.imwrite(check_vis.jpg, img) visualize_yolo(images/001.jpg, labels_yolo/001.txt, [oil_spill, ship, look_alike])这个可视化脚本把归一化坐标还原成像素坐标画框如果框明显偏移或尺寸不对回去检查转换时的宽高是否用错——常见错误是把 XML 里的 width 和 height 搞反导致框旋转 90 度。3.3 四个容易翻车的边界情况第一个坑XML 里 size 节点的 width 和 height 与实际图像不一致。有些标注工具在图像被重新保存后没更新 XML导致归一化基准错误。解决办法是始终用 PIL 读实际图像尺寸或者转换前批量校验一遍。第二个坑类别名有空格或大小写不一致。比如 oil spill 和 oil_spill 被当成两个类映射表里只写了一个另一个全被跳过。转换前先跑一遍grep -h name *.xml | sort | uniq -c统计所有类别名。第三个坑图像文件和 XML 文件名不匹配。VOC 标准里 XML 的 filename 节点应该和实际文件名一致但实际数据里经常有 .jpg 和 .JPG 混用或者 XML 叫 001.xml 而图像叫 001_aug.jpg。脚本里用 stem 匹配只能处理同名情况更稳妥的做法是解析 XML 的 filename 节点来定位图像。第四个坑空标注文件。有些图确实没有目标XML 里 object 列表为空转出来的 txt 也是空文件。YOLO 训练时空 txt 是合法的负样本但如果你用某些数据加载库空文件可能被当成损坏数据跳过。确认你的训练框架支持空标签不支持的话要么删掉这些图要么在 txt 里写一个占位行再在数据集配置里忽略。4. 用 YOLOv8 跑通第一个溢油检测基线4.1 数据集目录结构与 data.yamlYOLOv8 对目录结构有固定要求images 和 labels 分开各自下面再分 train、val、test。data.yaml 里写路径和类别名。假设你把 1800 张按 7:2:1 划分目录长这样oil_spill_dataset/ ├── images/ │ ├── train/ (1260 张) │ ├── val/ (360 张) │ └── test/ (180 张) ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamldata.yaml 内容path: /absolute/path/to/oil_spill_dataset train: images/train val: images/val test: images/test names: 0: oil_spill 1: ship 2: look_alike注意 path 要写绝对路径YOLOv8 对相对路径的解析有时会出问题。names 的 id 必须和 txt 里的 class_id 对应顺序错了模型学到的类别就全乱了。4.2 训练命令与关键参数yolo detect train \ data/absolute/path/to/oil_spill_dataset/data.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.001 \ lrf0.01 \ patience20 \ augmentTrue \ mosaic1.0 \ mixup0.1 \ degrees10.0 \ translate0.1 \ scale0.5 \ fliplr0.5 \ projectruns/oil_spill \ namebaseline_v8s参数说明model 选 yolov8s 而不是 n 或 m是因为 1800 张数据量下 s 的容量和速度比较平衡n 容易欠拟合m 容易过拟合。epochs 设 100 配合 patience 20验证损失 20 轮不降就早停。lr0 用 0.001 是微调的常见起点如果你解冻了 backbone 可以降到 1e-4。imgsz 640 是默认值如果溢油目标普遍很小可以提到 1280但显存占用会翻倍。mosaic 和 mixup 是强增强对小数据集有帮助但 mixup 设 0.1 就够了太高会让油膜边界变模糊。degrees 10 和 translate 0.1 针对海面图像做适度旋转平移fliplr 0.5 水平翻转对海面场景安全因为油膜没有固定方向。4.3 训练过程看什么指标启动训练后第一轮看 loss 是否正常下降。YOLOv8 会输出 box_loss、cls_loss、dfl_loss前几轮波动大是正常的10 轮后应该看到明显下降趋势。如果 box_loss 一直不降检查标签格式如果 cls_loss 不降检查类别映射。验证集指标重点看 mAP50 和 mAP50-95。溢油检测里 mAP50 到 0.7 以上算可用0.8 以上算不错。如果 mAP50 高但 mAP50-95 低说明框的位置不够准可以调 dfl_loss 的权重或增加定位相关的增强。混淆矩阵在 runs 目录下会生成重点看 oil_spill 和 look_alike 之间有没有大量误判有的话说明这两类在视觉上太接近需要重新定义标注规则或增加区分性特征。4.4 推理与结果导出yolo detect predict \ modelruns/oil_spill/baseline_v8s/weights/best.pt \ sourcetest_images/ \ conf0.25 \ iou0.45 \ saveTrue \ save_txtTrue \ projectruns/oil_spill \ nameinferenceconf 0.25 是召回优先的阈值溢油检测里漏检比误检代价高所以阈值设低一点。iou 0.45 用于 NMS如果油膜区域重叠多可以调到 0.5。save_txt 会输出每张图的检测结果格式和 YOLO 标签一样方便后续做定量分析。5. 避坑与排查训练不收敛、mAP 虚高、显存爆炸5.1 损失不降反升现象训练前 10 轮 box_loss 从 2.0 涨到 3.0 以上mAP 一直是 0。原因通常是学习率太大或标签格式错误。先检查 txt 里的坐标是否在 0-1 之间有超出就是转换时没裁剪。如果坐标正常把 lr0 降到 1e-4 再试。还有一种可能是 data.yaml 里的 path 写错模型实际加载的是空数据集这时 loss 会随机波动。5.2 mAP 很高但实际检测全是误报现象验证集 mAP50 到 0.9但拿真实海面图推理时满屏框。原因是验证集和训练集分布太接近模型过拟合了。检查划分时是否按图像来源分层如果训练集和验证集来自同一批连续拍摄的图像它们几乎一样。解决办法是按时间或区域划分比如用前 70% 时间的图训练后 30% 验证。另外看混淆矩阵如果 look_alike 类被大量预测为 oil_spill说明标注边界模糊需要重新定义这两类的区分标准。5.3 显存爆炸现象batch 16 时 CUDA out of memory。YOLOv8s 在 640 分辨率下 batch 16 大约需要 8-10GB 显存如果卡只有 8GB降到 batch 8 并开 gradient accumulation 补回来。或者用 yolov8n显存减半但精度会降几个点。另一个隐藏原因是 imgsz 设太大1280 分辨率下显存占用是 640 的四倍左右先确认你的 imgsz 是不是被无意中改大了。5.4 空标签导致的训练中断现象训练到某个 epoch 突然报错提示某张图的标签文件为空或格式错误。YOLOv8 对空 txt 是支持的但如果 txt 里只有换行符或空格解析会失败。批量检查所有 txt把只有空白字符的文件清空或删除。另外如果某张图的所有框都被边界裁剪掉了也会产生空 txt这种图作为负样本是合理的但确认你的数据加载器版本支持。5.5 类别不平衡导致的漏检现象油膜类 mAP 正常但 ship 类几乎检不出来。原因是 ship 样本太少1800 张里可能只有几十个。解决办法是在 data.yaml 里给 ship 类加权或者用 copy-paste 增强把 ship 实例复制到更多图里。YOLOv8 本身没有直接的类别权重参数但可以通过重复采样含 ship 的图像来间接平衡。6. 把 1800 张用出 5000 张的效果离线增强与伪标签迭代小数据集的瓶颈不在模型而在数据多样性。我一般会做两轮离线增强加一轮伪标签把有效训练量撑到 5000 张以上。第一轮离线增强用 albumentations 做几何和色彩变换重点模拟不同海况雾天降低对比度、逆光增加眩光、波浪纹理叠加。代码不复杂关键是增强后的标签要同步变换。import albumentations as A import cv2 from pathlib import Path transform A.Compose([ A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(brightness_limit0.3, contrast_limit0.3, p0.7), A.HueSaturationValue(hue_shift_limit10, sat_shift_limit20, val_shift_limit20, p0.5), A.GaussNoise(var_limit(10, 50), p0.3), A.MotionBlur(blur_limit5, p0.2), A.RandomFog(fog_coef_lower0.1, fog_coef_upper0.3, p0.2), A.ShiftScaleRotate(shift_limit0.1, scale_limit0.2, rotate_limit15, p0.5), ], bbox_paramsA.BboxParams(formatyolo, label_fields[class_labels])) def augment_image(img_path, label_path, out_img_dir, out_lbl_dir, n3): img cv2.imread(str(img_path)) h, w img.shape[:2] lines Path(label_path).read_text().strip().split(\n) bboxes, labels [], [] for line in lines: if not line: continue parts line.split() labels.append(int(parts[0])) bboxes.append([float(x) for x in parts[1:5]]) for i in range(n): augmented transform(imageimg, bboxesbboxes, class_labelslabels) out_name f{Path(img_path).stem}_aug{i} cv2.imwrite(str(Path(out_img_dir) / f{out_name}.jpg), augmented[image]) with open(Path(out_lbl_dir) / f{out_name}.txt, w) as f: for bbox, lbl in zip(augmented[bboxes], augmented[class_labels]): f.write(f{lbl} { .join(f{v:.6f} for v in bbox)}\n)这个脚本对每张原图生成 3 张增强图1800 张变 7200 张。注意 RandomFog 的系数别设太高0.3 以上油膜就完全看不见了反而引入噪声。MotionBlur 模拟无人机或岸基摄像头的抖动对海面场景很实用。第二轮用训好的基线模型对无标注海面图像做推理置信度 0.7 以上的框作为伪标签人工过一遍筛掉明显错误的再加入训练集。这个过程做两轮模型对真实场景的泛化会明显提升。我自己的习惯是每轮伪标签后重新训一个模型而不是在旧模型上继续训这样能避免错误累积。最后一轮用全部数据训一个最终模型在独立测试集上验证如果 mAP50 比基线提升不到 3 个点说明数据多样性已经饱和该去补真实场景的图而不是继续增强。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/28 23:29:02

UE5 C++多人射击:射线检测与命中点网络同步优化实践

刚在项目里调一个手感问题:联机射击时,服务器上的射线检测明明命中了掩体,客户端拉回来的弹孔却飘在半空,跟实际瞄准点差出好几个厘米。查到最后,问题出在两个平时不太起眼的技术点上:射线检测的LinetraceB…

2026/9/28 23:29:02

系统窗深度测评:觅简时光与纪房希五大性能实测对比

做了这么多年门窗评测,也见过不少品牌在宣传页上把参数吹得天花乱坠,可真到了实验室里跑数据、上墙实测的时候,差距一下子就拉开了。这次拿到的两款产品——觅简时光门窗和纪房希门窗,都是市场上比较有代表性的中高端系统窗&#…

2026/9/28 23:29:02

CH554 KEIL环境配置全指南:芯片支持、WCHISPTool协议与USB调试

1. 为什么CH554的KEIL环境配置总卡在“找不到芯片”这一步?我第一次给CH554配KEIL环境时,在WCHISPTool里点“检测设备”,串口灯亮了,但软件界面上始终显示“未连接设备”——不是驱动没装,也不是线坏了,而是…

2026/9/29 0:04:04

LLM红队实战:从攻击面枚举到防护策略的完整方法论

1. 从“Lysios”这个名字说起:LLM红队到底在防什么第一次看到“Lysios – LLM red teaming org”这个标题,很多人会愣一下:Lysios是什么?是一个开源工具、一个组织代号,还是一套方法论?从命名习惯来看&…

2026/9/29 0:04:04

LSTM时间序列预测实战:从数据窗口构造到模型调参避坑

简介:这份资源面向高校学生与Python初学者,提供一套可直接运行的LSTM时间序列预测完整项目,适用于期末大作业、课程设计及入门级深度学习实践。项目以空气质量等真实数据为样本,覆盖数据预处理、模型搭建、训练与预测全流程&#…

2026/9/29 0:04:04

Java采购管理系统实战:从数据库设计到事务一致性

简介:这是一套面向Java Web初学者与课程设计者的采购管理系统完整源码,采用JSP技术搭建,配合MySQL数据库,用于解决企业采购信息的管理问题,适合作为毕业设计、课程大作业或进销存类项目的参考模板。系统实现了用户登录…

2026/9/29 0:04:04

AI Evals实战指南:从零搭建LLM应用评估体系与CI/CD集成

1. 为什么AI Evals值得你花时间搞明白做LLM应用的人,迟早会撞上同一堵墙:模型输出飘忽不定,今天答得好好的,明天换个问法就胡说八道。你改了一版提示词,感觉好像好了点,但到底好了多少?说不清。…

2026/9/28 23:59:03

ESP-IDF离线安装三步法:绕过网络校验与工具链劫持

1. 为什么离线装Python依赖会卡在“正在下载esp-idf-tools”这一步?我第一次在客户现场部署ESP-IDF开发环境时,就栽在这儿了。客户机房网络策略极其严格:所有外网出口被封死,DNS只允许解析内网地址,连ping通8.8.8.8都做…

2026/9/28 3:03:23

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/28 6:05:15

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/28 6:07:41

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 0:04:04

AI Evals实战指南:从零搭建LLM应用评估体系与CI/CD集成

1. 为什么AI Evals值得你花时间搞明白做LLM应用的人,迟早会撞上同一堵墙:模型输出飘忽不定,今天答得好好的,明天换个问法就胡说八道。你改了一版提示词,感觉好像好了点,但到底好了多少?说不清。…

2026/9/29 0:04:04

Java采购管理系统实战:从数据库设计到事务一致性

简介:这是一套面向Java Web初学者与课程设计者的采购管理系统完整源码,采用JSP技术搭建,配合MySQL数据库,用于解决企业采购信息的管理问题,适合作为毕业设计、课程大作业或进销存类项目的参考模板。系统实现了用户登录…

2026/9/25 20:55:38

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/26 19:58:38

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/28 1:59:25

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑