☰
基于YOLOv10的麦穗计数系统:从密集小目标检测到产量估算
2026/10/12 15:27:25 网站建设 项目流程

简介:面向熟悉 Python 与深度学习基础的科研工作者和工程开发人员,这套基于 YOLOv10 的麦穗计数系统方案,聚焦麦类作物麦穗数量自动化估算,用于提升农业生产环节的管理效率。包体为 1 个 docx 文档,大小约 46KB,按项目介绍、实现步骤、代码解释、数据示例、完整代码整合等模块组织,目录清晰,便于按需求查阅。内容涵盖环境配置、预训练模型准备与 ONNX 导出、检测系统编码、GUI 实时计数与评估指标展示等完整实现链路,并提醒数据集多样性、环境适应性测试等影响泛化能力的注意事项。同时给出超参数优化、模型集成、边缘计算等未来改进方向,已有 143 人学习,适合作为从项目落地到调优的参考。

1. 基于 YOLOv10 的麦穗计数系统:从数穗子到估产量的自动化路线

基于 YOLOv10 的麦穗计数系统,解决的是农情测产里最磨人的一件事:把地头的麦穗数清楚。人蹲在田里,一米见方的样方框一套,一穗一穗点,一块地十几个样方下来,眼睛先花,腰也先投降;更麻烦的是麦穗密集、互相遮挡,穗子和麦秆颜色几乎一样,人眼数都容易重数和漏数。

这套系统做的事,就是把“数穗子”变成一次目标检测:模型在田拍图像上把每个麦穗框出来,程序再对框做去重、统计和密度换算,最后输出每平米穗数,再接上每穗粒数和千粒重就能估产量。相比传统分割或密度回归方案,检测即计数,逻辑直接,标注数据也好组织,完整的程序代码和数据组织方式后面都会给出。

这条路线适合三类人:做育种考种的农艺师、做区域产量估测的从业者,以及手里正好有一批麦田图像、想快速搭出自动计数流水线的工程师。下文按模型选型、数据准备、训练调参、踩坑记录、田间落地五节展开,代码可以直接跑,重点讲密集小目标场景里那些容易翻车的细节。

2. 为什么选 YOLOv10 做麦穗检测:密集小目标的三个硬理由

麦穗目标在大田图像里呈现出三个典型特征:个体小,大量聚集,和背景颜色高度接近。这种场景对检测模型的考验主要不在分类能力,而在“密集目标如何不被互相抑制、不被漏掉”。YOLOv10 在这三个维度上正好踩中了需求,下面拆开讲。

2.1 NMS-free 训练:省掉的推理后处理对密集场景有多重要

YOLOv10 是 YOLO 系列里第一个把 NMS 从推理链路里去掉的主流版本。之前的 YOLO 模型训练时用 one-to-many 分配,一个真值框会被分配给多个预测框,所以推理时必须接一个 NMS 后处理,把同一目标上重叠的重复框压掉;而 NMS 的阈值非常敏感,在麦穗这种高密度场景里,两个穗挨得近,NMS 很容易把其中一个真值当作重复框误删,或者阈值放太松导致一个穗保留两三个框。做过密集小目标检测的人应该都体会过“调 NMS 阈值像调玄学”的那种感觉。

YOLOv10 的做法是训练阶段引入 one-to-one 匹配,让每个目标只对应一个预测框,同时保留一个 one-to-many 的辅助头帮助收敛;推理时直接取置信度最高的框,整个链路里没有 NMS。对麦穗计数来说,这意味着少了一个需要手调的环节,密集场景下相邻穗子的预测框天然是唯一的。这一点在第五章的重叠框问题里还会体现。

模型版本的选择也直接影响效果。我的经验是从 yolov10s 起步,它在精度和速度之间最平衡,8G 显存能跑动;只有 CPU 或显存极小时退回 yolov10n;数据量超过 1500 张、想要极限精度再上 yolov10m。下面是三个版本的大致定位:

权重显存压力适用场景
yolov10n低CPU 验证流程、移动端、快速试跑
yolov10s中常规田块计数,推荐起步配置
yolov10m较高数据量大、对漏检零容忍的测产项目

需要说清楚边界:NMS-free 只解决“同一目标重复框”的问题,不解决“漏检”和“误检”。光照差、穗子太小、遮挡过半,模型照样会漏;麦芒、秸秆横截面在特定角度下也会被误判成穗。所以模型选型只是第一步,数据质量和推理参数才是决定最终计数误差的大头。

2.2 检测、跟踪、密度回归:三条计数路线的取舍

麦穗计数在工程上并不只有一条路,常见做法是先把需求分成三类,再定技术路线。

第一类是检测计数:对单张图像跑检测,直接数框的个数。适合样方静态拍照、考种台架、无人机单帧处理,做法最简单,也是这套系统的核心。第二类是跟踪计数:对视频连续帧做检测加多目标跟踪,按 track ID 去重,统计整个视频里出现的独立穗子数量,适合人拿着相机沿田埂走一遍、或者农机搭载相机的场景,能覆盖更大的田块。第三类是密度回归计数:用点标注训练密度图模型,直接输出每平米穗数密度,这类方案对逐穗定位不敏感,适合快速估产,但没法做单穗考种,而且在小麦灌浆后期穗子互相叠压时误差会显著上升。

我的选型建议很直接:只要目标是产量数字、不在乎单穗位置,也先别急着上密度回归,YOLOv10 检测路线拿到的精度转计数已经足够;要做单穗考种、数无效穗、看穗粒数分布,只有检测路线能给到逐穗框。密度图方案的数据标注方式和检测不互通,中途切换的沉没成本很高,这个后悔药不好吃。

2.3 环境准备与最小目录规划

先搭环境。GPU 机器按 PyTorch 官方对应 CUDA 版本的安装命令装好 torch,然后装 YOLOv10 依赖的训练框架:

pip install -U ultralytics pip install -U opencv-python

装完后跑一条命令验证环境和预训练权重能不能正常加载:

yolo predict model=yolov10s.pt source=test.jpg

第一次运行会自动拉取预训练权重,网络慢的时候可以先放后台,或者先用小图验证流程。纯 CPU 机器也能跑通整条链路,只是训练速度慢几个量级,建议先用 yolov10n 加小数据集验证逻辑,再上 GPU 正式训练。

目录结构我习惯这样规划,后面所有脚本都按这个路径写:

wheat-count/ ├── dataset/ │ ├── images/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ ├── labels/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ └── wheat.yaml ├── scripts/ │ ├── voc2yolo.py │ ├── train.py │ └── count.py ├── runs/ # 训练与验证输出 └── weights/ # 预训练权重和最终权重

dataset 目录下 images 和 labels 必须同名同前缀,训练框架按文件名匹配图像和标签文件。后面所有路径建议用绝对路径,避免 YAML 里相对路径在不同工作目录下把数据找丢。这套目录规划看起来简单,但能省掉后面大量“路径不对导致训练静默跳过数据”的排查时间。

3. 麦穗数据准备:标注规范、格式转换与训练集划分

数据是这套系统里最大的杠杆。我见过太多人把精力花在调参上,最后卡在标注口径不统一上。这一章把采集、标注、转换、划分一次讲完,照着做基本不会在数据环节翻车。

3.1 采集与标注:把“一个麦穗”定义清楚

先说采集。相机镜头尽量垂直朝下拍穗层,镜头离穗层 40 到 60 厘米,保证单穗在图像里不小于 40 像素;一个样方一张图,不同地块、不同时段、不同天气都采一些,别只在一个晴天正午拍。同一个地块的连续照片放进同一个组,后面划分训练集时要按组分开。

标注规范必须在开工前写死,我用的口径是:

  • 只框穗体,不含芒。麦芒又细又长,框进去会把目标拉长,干扰宽高比。
  • 框贴穗体边界,留 1 到 2 像素余量即可。
  • 遮挡超过一半的穗不标;遮挡小于一半的按可见部分标一个框。
  • 一个穗绝对不允许拆成两个框,也不允许一个框套两个穗。

这个口径直接决定了后续所有评估的可信度。标注工具用常见的图像标注软件就可以,导出成 VOC XML 或 COCO JSON 都行,后面脚本按 VOC 讲,因为 XML 结构直观、好排查。如果多人协作,建议先让每个人各标 20 张,互相算一下框级 IoU,低于 0.7 就先别开工,回去对齐口径。

3.2 从 VOC XML 到 YOLO 格式的转换脚本

YOLO 系列训练需要 txt 标签,每行一个目标,格式是:类别 id、归一化中心 x、中心 y、宽、高。下面这段脚本把 VOC XML 批量转成 YOLO txt:

import os import xml.etree.ElementTree as ET def convert(xml_path, txt_path, img_w, img_h): tree = ET.parse(xml_path) root = tree.getroot() lines = [] for obj in root.findall('object'): name = obj.find('name').text if name != 'wheat_head': continue box = obj.find('bndbox') xmin = float(box.find('xmin').text) ymin = float(box.find('ymin').text) xmax = float(box.find('xmax').text) ymax = float(box.find('ymax').text) # 归一化到 [0,1],YOLO 要求用图像原图宽高 x_center = ((xmin + xmax) / 2) / img_w y_center = ((ymin + ymax) / 2) / img_h w = (xmax - xmin) / img_w h = (ymax - ymin) / img_h # 越界框裁剪,防止训练时出现无效标签 x_center = max(0.0, min(x_center, 1.0)) y_center = max(0.0, min(y_center, 1.0)) w = max(0.001, min(w, 1.0)) h = max(0.001, min(h, 1.0)) lines.append(f"0 {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}") # 写出的 txt 与图像同名,放在 labels 对应目录下 with open(txt_path, 'w') as f: f.write('\n'.join(lines)) # 使用示例:遍历某目录下所有 xml,传入原图宽高调用 convert

逻辑说明:这里只处理类别名为 wheat_head 的标注,类别 id 固定写 0,对应后面 data.yaml 里的第一个类;归一化时用原图宽高而不是 xml 里某个对象的尺寸,这两个搞混是新手最常见的翻车点。越界框必须裁剪,很多标注工具允许框画出图像边界,不处理会让训练在 loss 计算时出现无效值。

参数说明:img_w、img_h 是图像原始宽高,必须从图像文件里读出来,不能从 xml 字段里猜。如果你用的是 COCO JSON,转换时把 bndbox 换成 annotation 里的 bbox 四元组即可,归一化公式完全一样,中心坐标和宽高依次除以图像宽高。

3.3 训练集划分与 data.yaml 配置

划分时有个关键原则:按田块划分,而不是按图像随机划分。同一块地相邻图像光照、角度高度相似,随机划分会让验证集“作弊”,mAP 虚高十几个点都很正常,一旦换到新地块立刻露馅。做法是把同一个地块、同一次拍摄的图放进同一组,再按 7:2:1 分成 train、val、test。

# wheat.yaml path: /home/user/wheat-count/dataset train: images/train val: images/val test: images/test # 麦穗就是单类别检测 nc: 1 names: 0: wheat_head

说明:path 写绝对路径,train、val、test 写相对 path 的目录;nc 是类别数,麦穗场景就是 1。训练框架会自动校验 images 和 labels 目录下的文件是否一一对应,缺标签的图会被跳过并打印警告,跑之前先确认警告数量为 0。

数据量建议从 800 张起步。每张图按 1280 分辨率算,麦穗目标几十到上百个,训练样本数其实很充足;低于 300 张会明显感受到过拟合,mAP50 在验证集上波动很大。如果实在缺图,先把 3.1 节的标注口径执行到位,再考虑用水平翻转、亮度抖动做离线增强,不要指望训练时那点在线增强能变出信息量。数据集这块可以先用公开的麦穗检测数据做预训练,再用自家田块数据微调,能显著减少新数据需求量。

4. 训练落地与调参:把麦田里的穗子捞干净

环境、数据都齐了,接下来是训练。这一章给一条能直接跑的训练命令,把参数含义讲透,再讲增强和验证,目标是让模型在你的田块图像上把穗子尽量捞干净。

4.1 一条能跑的训练命令与参数含义

yolo detect train \ data=/home/user/wheat-count/dataset/wheat.yaml \ model=yolov10s.pt \ epochs=200 \ imgsz=1280 \ batch=8 \ lr0=0.01 \ lrf=0.01 \ close_mosaic=10 \ patience=30 \ device=0

参数说明:

参数推荐值说明
modelyolov10s.pt中小模型,精度速度平衡;显存小换 yolov10n,精度优先换 m
epochs200配合 patience 早停,足够收敛
imgsz1280小目标关键参数,见下方解释
batch88G 显存建议 2 到 4,再配合梯度累积
lr00.01预训练权重微调的常见起点
lrf0.01末轮学习率为初始的 1%
close_mosaic10最后 10 轮关闭 Mosaic 增强

逻辑说明:imgsz 是训练时缩放的边长。麦穗在原图里经常只有 20 到 40 像素,imgsz=640 会把它们压到 10 到 15 像素,特征基本消失;提到 1280 后单穗能保留 25 像素以上,召回率提升明显。代价是显存和训练时间大约翻倍,8G 显存跑 yolov10s 加 imgsz=1280 时 batch 设 2 到 4 比较稳,训练脚本里开梯度累积可以模拟更大 batch。

预训练权重文件放在 weights 目录下,训练输出会自动写到 runs/detect/train 下,best.pt 是按验证集 mAP 保存的最优权重,last.pt 是最后一轮权重。习惯上只用 best.pt 做后续推理,last.pt 偶尔会在训练被中断时派上用场,比如用来续训。

4.2 针对小麦图像的增强参数设置

田间图像的光照变化比一般目标检测场景大得多,增强参数要按麦田特性来调。下面这组配置是我在多个地块上验证过的起点:

yolo detect train \ data=/home/user/wheat-count/dataset/wheat.yaml \ model=yolov10s.pt \ epochs=200 imgsz=1280 batch=8 \ hsv_h=0.02 hsv_s=0.7 hsv_v=0.5 \ degrees=5 translate=0.1 scale=0.5 \ fliplr=0.5 mosaic=0.5 mixup=0.2 \ label_smoothing=0.05 \ close_mosaic=10 device=0

参数含义说明:hsv_h、hsv_s、hsv_v 分别控制色相、饱和度、亮度的随机抖动幅度,麦田从清晨到正午再到黄昏,色温和亮度差异很大,这三项开大一点能明显提升泛化;degrees 只给 5 度,因为麦穗基本垂直向上,大角度旋转会制造出田间不存在的姿态;mosaic 从默认的 1.0 降到 0.5,拼接增强会把小目标进一步缩小,对麦穗这种小目标反而不友好;mixup 开 0.2,轻量混合增强能提升遮挡场景的鲁棒性;label_smoothing 对标注边缘含糊的框有帮助,尤其多人协作标注时边界争议多。

这些参数不用一次调到位。我的习惯是先跑一版默认参数看基线,再只改 imgsz 和 mosaic,确认小目标指标有提升后再动 hsv 和 mixup。一次改一堆参数,最后出了问题根本不知道是谁的锅。

4.3 验证指标怎么读:mAP 和计数误差是两回事

训练完先跑验证,确认指标:

yolo detect val \ model=/home/user/wheat-count/runs/detect/train/weights/best.pt \ data=/home/user/wheat-count/dataset/wheat.yaml \ imgsz=1280

训练框架会输出 mAP50、mAP50-95、Precision、Recall 四组数字。对麦穗计数来说,最该盯的是 Recall:漏检一个穗,计数就少一个,这是直接损失;而 Precision 误差可以通过后处理降低。mAP50 到 0.9 左右通常就意味着检测质量不错,但 mAP 再高也不能替代计数误差评估。

计数误差要人工抽检才能看出来。我常用下面这个小脚本,拿 10 张人工数过的验证图逐张比对:

import numpy as np from ultralytics import YOLOv10 model = YOLOv10("/home/user/wheat-count/runs/detect/train/weights/best.pt") # 人工数的 10 张图,键是文件名,值是手工数出来的穗数 manual = { "plot_001.jpg": 87, "plot_002.jpg": 92, "plot_003.jpg": 76, } errors = [] for img_name, true_count in manual.items(): res = model.predict( source=f"/home/user/wheat-count/dataset/images/test/{img_name}", imgsz=1280, conf=0.30 ) pred_count = len(res[0].boxes) errors.append(abs(pred_count - true_count)) print(f"{img_name}: 模型 {pred_count}, 人工 {true_count}") print("平均绝对计数误差:", np.mean(errors))

逻辑说明:脚本用模型预测框数量直接对人工数逐图算差值,误差稳定在 ±5% 以内再谈落地。如果系统偏差为正,说明重复框或误检偏多,优先调 conf 阈值和重叠框合并;偏差为负,优先查漏检,回到 imgsz 和数据覆盖这两个方向。mAP 是模型对自己的评价,人工比对才是系统对田间的评价,这两者一定要同时看。

5. 麦穗计数系统避坑记录:5 个高频翻车点与对应解决

这一章是我在搭建麦穗计数系统过程中踩过的真实坑,每条按“现象、原因、解决”记录,希望能帮你省掉几周排查时间。

5.1 小穗漏检:imgsz、切片与增强三选一

现象:训练 mAP50 到 0.75 左右,验证集看着不错,换到另一块田,图像边缘的穗和灌浆初期的嫩穗大量漏检,计数偏低 20% 以上。

原因:麦穗在原图里只有十几个像素,imgsz=640 训练时被进一步压小,模型没见过足够大的目标特征;灌浆初期穗色偏绿,和叶片对比度低,网络学到的特征偏向中后期金黄色穗。

解决:优先把 imgsz 提到 1280,这一步能解决大部分漏检;图像超过 4000 像素的田块大图,先用切片推理再合并结果,等效于让模型在原分辨率上看目标;增强侧把 hsv 色相抖动调大,覆盖嫩穗的绿色。改完重训后验证集 recall 通常能从 0.82 提到 0.93 左右,计数误差从 -20% 收窄到 -3%。

5.2 同一麦穗被重复计数:视频与拼接图的去重逻辑

现象:人拿着相机沿田埂走一遍录像,模型每帧都数出 80 到 100 个穗,把全部帧加起来一个样方有上千个,明显不对。

原因:没有给检测目标分配身份。同一个麦穗在 30 帧视频里出现 30 次,每次都被当成一个新目标计数,累加自然爆炸。

解决:视频场景走跟踪路线,用 ByteTrack 或 BoT-SORT 给每个穗分配 track ID,统计时按 ID 去重。具体做法在第六章的 count_video 函数里给出。对于需要拼接的切片图,先做重叠区域的 IoU 合并再计数,不能让切片的边缘重复计入。视频计数的核心原则是:身份去重优先于逐帧数量。

5.3 一个穗出两个框:密集场景的重叠框合并

现象:单图计数一直比人工多 5% 到 8%,打开可视化发现部分大穗被模型拆成上下两个框,两个框 IoU 很高但都保留了。

原因:穗体较长,局部外观差异大,在极端遮挡或视角下,one-to-one 匹配仍可能让一个目标对应两个高置信度预测;NMS-free 推理时不抑制重叠框,这个角案例就被保留下来。

解决:推理时对置信度高于阈值的框做一次轻量合并。两个框 IoU 大于 0.3 且类别相同,就保留置信度高的那个:

def merge_overlap_boxes(boxes, iou_thr=0.3): # boxes 是 [x1, y1, x2, y2, conf] 的列表 boxes = sorted(boxes, key=lambda b: b[4], reverse=True) used = [False] * len(boxes) keep = [] for i, a in enumerate(boxes): if used[i]: continue for j, b in enumerate(boxes): if i != j and not used[j] and b[4] > 0.3: if box_iou(a, b) > iou_thr: used[j] = True # 低置信度框被合并掉 keep.append(a) return keep

逻辑说明:按置信度从高到低遍历,高置信度框吃掉所有与它重叠超过阈值的低置信度框。box_iou 是标准的 IoU 计算函数,x1、y1、x2、y2 是像素坐标,conf 是模型输出的目标置信度。注意这个后处理只在计数偏差为正、确认存在重叠框时才需要加,如果误差已经在 ±3% 以内,加上它反而可能引入新的误合并,保持流水线简单更重要。

5.4 标注口径不一致:mAP 虚高的假象

现象:模型验证结果 Precision 0.96、Recall 0.91,数字很漂亮,和人工数的偏差却最大;换个人重新标同一批图,发现框的大小和遮挡穗标注标准完全不一样。

原因:部分标注者把芒也框进去了,宽高比变了;遮挡穗有人标有人不标。模型学到的“麦穗”概念和考种口径不一致,mAP 只是在标注口径一致的子集上自我评价,虚高不代表田间表现好。

解决:标注前做一套标准图例,三个人各标 20 张,两两算框级平均 IoU,低于 0.7 就重新对齐口径再开工。训练后对置信度在 0.3 到 0.5 之间的边界样本人工复核,确认是漏标还是误检。这个环节工作量最大但最值,标注标得乱,后面所有数字都不可信。

5.5 跨生育期泛化崩坏:数据与增强的覆盖短板

现象:拔节期和灌浆期的穗色、姿态差异很大,只用一种生育期的图训练,换到另一个时期 mAP 掉 0.2 以上。

原因:麦穗在灌浆前期是嫩绿色且带芒直立,后期是金黄色且穗头轻微下垂,外观差异超过很多人的直觉。模型学到的是“训练集那一个生育期的麦穗”,不是抽象的麦穗概念,换个物候期就等于换了半个任务。

解决:采集时按生育期归档,训练集至少覆盖两个关键时期。如果项目启动得晚,先用公开麦穗检测数据预训练,再用自家田块数据微调,新数据一两百张就有明显效果。验证时注意地块来源不能混入训练集,否则指标虚高。模型不是万能黑匣子,边界案例最好在项目早期就暴露出来,拖到验收阶段再发现跨期泛化问题,改数据重训的成本非常高。

6. 落到田间算产量:推理计数脚本与穗数-产量换算技巧

最后一步是把模型封装成能直接用的计数工具,并接上产量估算。这里给出单图和视频两套脚本,再讲透标定和换算。

6.1 单图与视频的计数脚本

from ultralytics import YOLOv10 model = YOLOv10("/home/user/wheat-count/runs/detect/train/weights/best.pt") def count_single(image_path, conf=0.30): # 单图计数:数出当前图像里的麦穗框数量 res = model.predict(source=image_path, imgsz=1280, conf=conf, device=0) return len(res[0].boxes) def count_video(video_path, conf=0.30): # 视频计数:按 track ID 去重,统计整个视频里出现的独立麦穗数 track_ids = set() for res in model.track( source=video_path, persist=True, conf=conf, tracker="bytetrack.yaml", imgsz=1280, device=0 ): if res.boxes is None or res.boxes.id is None: continue for tid in res.boxes.id.cpu().tolist(): track_ids.add(tid) return len(track_ids)

逻辑说明:count_single 直接数当前帧的检测框数量,适合样方静态图,所有框默认可信。count_video 用 ByteTrack 给每个穗分配身份编号,把整个视频里出现过的 ID 集合求大小,这是视频去重的标准做法。tracker 参数指定跟踪器配置,persist=True 让跟踪状态跨帧保持。固定相机场景如果只想统计新进入画面的穗,可以再加一个记录首次出现时间帧的过滤条件。

6.2 标定与产量换算:从框数到每平米穗数

单图数出的是“这张图里有多少穗”,要变成有农学意义的“每平米穗数”,必须做标定。最常见的做法是拍照时放一个 1 米乘 1 米的标定框,镜头垂直向下,让标定框充满画面。此时 count_single 的输出就是每平米穗数。没有标定框时,用镜头高度和视场角算出图像覆盖的实际面积,再拿框数除面积,同样能得到密度。

拿到每平米穗数后,接上考种数据就能估算产量:

  • 每穗粒数:从样方里随机取 20 个穗人工脱粒统计
  • 千粒重:晾干后称重得到

亩产量估算公式约为:产量(公斤/亩)约等于每平米穗数乘以每穗粒数乘以千粒重(克)再乘以 0.000667。这套公式是农学里常用的测产换算,检测模型只负责最前面那个乘数,也就是穗数。

我的习惯是给这套系统配一个固定的人工复核集:每次模型更新或参数调整,都在那 10 张金标准图上重新跑一遍计数误差,误差超过 5% 就回头查 conf、合并阈值和数据覆盖。这个集子不动,模型怎么改都有个对照,精度下滑第一时间就能暴露,而不是等到整片田数完才发现系统性偏差。

这套方案从数据准备到产量估算已经形成闭环,照着做一遍,你手上的麦田图像就会变成一套能重复使用、误差可量化的计数工具。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询