news 2026/10/1 19:17:25

YOLOv5+SAHI切片+超分:小目标检测推理优化实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv5+SAHI切片+超分:小目标检测推理优化实践

简介:面向从事目标检测与计算机视觉的开发者,这份演示源码围绕YOLOv5与SAHI模块的结合,提供了一套完整的超分辨率与小目标检测解决方案。项目基于PyTorch 1.7.1与CUDA 10.1,在Windows系统的PyCharm环境中即可运行,适用于交通监控、无人机巡检等需要识别小尺寸物体的场景。压缩包共4个文件,约23.05MB,含主程序脚本、预训练权重、运行说明文档及示例检测图片,类型涵盖py/pt/md/jpg,可直接对照脚本与说明上手实践。目前已有503人学习下载,对于希望提升小目标检测精度并了解SAHI机制的学习者是实用的入门材料。通过运行演示,可观察SAHI放大低分辨率图像后YOLOv5检测性能的变化;说明文档还介绍了sahi 0.8.4、yolov5 5.0环境配置及数据增强等内容,便于理解从训练到推理的完整流程,为后续迁移到自定义数据集打下基础。

1. 小目标检测为什么要叠加超分:YOLOv5+SAHI 的演示源码能解决什么

做小目标检测的人几乎都碰到过这种场面:图很大目标很小,整张图扔进 YOLOv5,置信度低得可怜;直接上超分辨率重建,把整张图放大两倍,显存先报警,检测速度也扛不住。这个演示源码给的思路是反直觉的——别急放大整张图,先用 SAHI 把大图切成切片,再配合超分辨率把目标区域顶上去,最后由 YOLOv5 完成检测。源码包里带 yolov5s6.pt 权重、main.py 推理脚本、README 和一张 small-vehicles1.jpg 样例图,在 Windows 上用 PyCharm 就能把这条链路完整跑通。适合手里有遥感、无人机俯拍、交通监控这类小目标检测需求,或者想把现有 YOLOv5 工程迁移到 SAHI 方案上的从业者。

2. 环境配置与版本匹配:PyTorch 1.7.1、CUDA 10.1、sahi 0.8.4 的落地细节

2.1 SAHI 切片推理的原理与选型理由

SAHI 全称是 Scale-Aware High-Resolution Interpreter,核心解决的是“目标像素占比太小”的问题。它不做全局超分,而是把原始大图按 slice_height 和 slice_width 切成若干块,相邻切片之间按重叠率叠加,避免目标恰好被切在边缘而丢失。每个切片单独过一遍 YOLOv5,得到检测结果后再把所有框映射回原图坐标系,统一做一次 NMS 合并。这样做的直接收益是:目标在整张图里可能只有 20×20 像素,但切到 640×640 切片里就相对清晰很多,YOLOv5 学习到的 anchor 特征能更好对齐。

为什么 YOLOv5 本身处理不好小目标?它虽然已经是速度精度兼顾的成熟检测器,用了 CSPDarknet 骨干、SPP-Block 池化、PANet 特征融合和自适应锚框,但输入尺寸被限制后,小目标的梯度贡献会被背景稀释。YOLOv5 5.0 训练时常用的 Mosaic、翻转、颜色抖动等数据增强能提升泛化,但推理阶段面对一张 4000×3000 的航拍图,直接 resize 到 1280 会把小目标压成几个像素。切片等于把“一张大图一次推理”改成“多张小图多次推理”,让每个目标都能获得足够的有效像素。

超分辨率在这个链路里属于可选的第二级增强。整图超分计算量大且背景占比过高,真正划算的是对低置信度或小尺寸切片做放大。演示源码里把这条路打通了:先用 SAHI 切片兜底,再在切片尺度上做超分,让 YOLOv5 拿到的输入既保留上下文,又强化目标细节。这就是它比“直接放大整图”更实用的根本原因,也是我建议你把这个组合用在航拍和遥感场景的原因。

2.2 环境安装:虚拟环境与依赖清单

这个源码的 README 明确写了依赖版本:PyTorch 1.7.1、CUDA 10.1、sahi 0.8.4、yolov5 5.0。我建议你用 conda 建独立环境,不要直接装在 base 里,否则后面换版本时会非常被动。Python 选 3.8 或 3.9,和 PyTorch 1.7.1 兼容性最稳。

conda create -n yolo_sahi python=3.8 -y conda activate yolo_sahi # 安装 CPU + GPU 对应的 PyTorch(cu101 对应 CUDA 10.1) pip install torch==1.7.1+cu101 torchvision==0.8.2+cu101 -f https://download.pytorch.org/whl/torch_stable.html # 安装 SAHI,注意版本锁到 0.8.4 pip install sahi==0.8.4 # 拉取 YOLOv5 v5.0 源码仓库 git clone -b v5.0 https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt cd ..

参数说明:torch 1.7.1+cu101 是 PyTorch 官方为 CUDA 10.1 编译的版本,torchvision 0.8.2 需要和它严格对应,否则 import 阶段就可能崩。sahi 0.8.4 的 API 与 0.11 之后差别不小,比如 get_sliced_prediction 的参数名和返回结构都有变化,如果你用了新版 sahi 再按 README 的命令跑,大概率会报参数不匹配。yolov5 用 v5.0 分支而不是 main 分支,是因为这个版本的 requirements 与老模型权重、SAHI 的 model_type="yolov5" 兼容性更稳。

安装完一定要跑自检脚本确认环境不是“半通”状态:

# check_env.py import torch import sahi import yolov5 # 如果能 import 成功说明 yolov5 依赖装齐了 print("torch version:", torch.__version__) print("cuda available:", torch.cuda.is_available()) print("sahi version:", sahi.__version__)

这一段是我习惯的先验证后开工。cuda available 是 False 不代表不能跑,但你要有心理准备:CPU 推理速度会慢到怀疑人生,尤其 SAHI 要把一张图切成几十块,每块都过一遍网络,CPU 模式下跑样例图可能要几分钟。正确做法是先在 CPU 上把整个流程走通一次,确认逻辑没问题再切回 GPU,避免在 CUDA 报错和代码逻辑问题之间来回猜。

2.3 模型文件与自检:yolov5s6.pt 的放置和加载验证

yolov5s6.pt 是 YOLOv5 的 P6 模型权重,P6 意味着网络有 6 个下采样阶段,输入尺寸可以达到 1280。相比常见的 yolov5s 只在 640 输入下工作,s6 在保持速度的同时对中等尺寸目标更友好,配合 SAHI 切片很适合做小目标检测的底座。这个文件默认放在 code 目录下,和 main.py 同级,SAHI 的 AutoDetectionModel 会直接按相对路径去找。

# 确认权重文件已就位,并查看基本信息 ls -lh yolov5s6.pt # 如果还没下载,可以到 YOLOv5 官方 release 列表里找 yolov5s6.pt # 放到 code 目录后,用下面命令确认能被 PyTorch 加载 python -c "import torch; ckpt = torch.load('yolov5s6.pt', map_location='cpu'); print(ckpt['model'].type)"

一个小提醒:路径里千万别带中文和空格,Windows 下 PyCharm 工程路径如果有中文,SAHI 内部的图像读取环节有时会遇到奇怪编码问题,报错信息还不直观。我一般会在 code 目录里单独建一个 weights 文件夹存放所有 .pt 文件,main.py 里用相对路径引用,换机器部署时整个目录拷走就行。

3. 跑通演示全流程:main.py 的调用链与切片推理参数

3.1 目录结构与 main.py 核心调用链

解压后你会看到 code 目录下包含 main.py、yolov5s6.pt、README.md、small-vehicles1.jpg,以及从 GitHub 拉下来的 yolov5 仓库。README 里通常会写清楚运行顺序、依赖版本和输出目录位置。main.py 是这个演示的主入口,它做的事情可以用一段伪代码概括:加载模型、读取图片、切片推理、导出结果。核心调用链是 sahi 的 AutoDetectionModel 和 get_sliced_prediction,写法如下:

# main.py 核心逻辑(演示源码的常见写法) from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction # 1. 用 SAHI 包装 YOLOv5 模型 detection_model = AutoDetectionModel.from_pretrained( model_type="yolov5", model_path="yolov5s6.pt", # P6 权重,输入尺寸支持 1280 confidence_threshold=0.25, # 低于该分数的框会被滤掉 image_size=1280, # 推理输入尺寸,和 s6 匹配 device="cuda:0", # 改成 "cpu" 也能跑,但会很慢 ) # 2. 切片推理:大图切成小图,检测完再拼回原图坐标 result = get_sliced_prediction( "small-vehicles1.jpg", detection_model=detection_model, slice_height=512, slice_width=512, overlap_height_ratio=0.2, # 垂直方向重叠 20% overlap_width_ratio=0.2, # 水平方向重叠 20% postprocess_class_agnostic=False, # False 表示按类别独立 NMS ) # 3. 导出可视化结果和 JSON 标注 result.export_visuals(export_dir="runs/detect/") result.export_as_json(export_dir="runs/detect/") print("检测完成,结果保存在 runs/detect/ 目录")

逻辑说明:AutoDetectionModel 是 SAHI 对检测模型的统一封装,你只需要指定 model_type 为 yolov5,它会在内部加载权重并转换成 SAHI 的推理接口。get_sliced_prediction 是整个演示的灵魂,它接收原图路径、检测模型和切片参数,返回一个 SlicedPrediction 对象,里面包含所有目标框、置信度和类别名。export_visuals 会画出带框的标注图,export_as_json 会输出标准 JSON,方便你后续做统计或接其他工具。

参数说明:slice_height 和 slice_width 直接决定切片的像素尺寸,512 对小目标检测是很好的起步值,目标太小可以降到 384 或 256,目标稍大可以升到 640,这个后面第 5 章会具体讲。overlap 比例是防止目标横跨切片边界导致漏检的关键,0.2 是通用起点,如果发现边缘目标频繁被切碎,就往上调。confidence_threshold 用 0.25 和 YOLOv5 默认一致,但 SAHI 切片后目标更清晰,可以大胆降到 0.15 以换取召回。postprocess_class_agnostic 保持 False 更符合多数业务场景。

3.2 运行推理与结果验证

环境配好后,直接在 PyCharm 里打开 code 目录,运行 main.py。如果不想改代码,也可以命令行直接执行:

# 方式一:直接运行 python main.py # 方式二:临时换一张图(如果 main.py 支持 --source 参数) python main.py --source your_image.jpg

跑完后到 runs/detect/ 目录看输出。正常情况下你会看到 small-vehicles1.jpg 上画满绿色框,每辆车都有置信度分数,JSON 文件里则是每个框的类别、坐标和得分。这张样例图是车辆俯拍图,目标数量多、尺寸小,最适合验证 SAHI 的价值。

为了确认 SAHI 确实有效,我会做一步对比实验:直接用 YOLOv5 原生推理跑同一张图。

python yolov5/detect.py --weights yolov5s6.pt --source small-vehicles1.jpg --img 1280

对比两个结果:原生 detect.py 输出的检测框数量通常明显少于 SAHI 切片推理,尤其是图像边缘和远处的小车辆,置信度也偏低。这就是切片带来的差异——目标在切片里占的像素比例高了,YOLOv5 对它的响应自然更强。

3.3 迁移到自己的数据集:格式、训练与增强

这个源码本质是推理演示,并不包含训练脚本。如果你想换成自己的业务数据,需要先做好数据集,再回到 YOLOv5 仓库里训练,最后把训练好的权重替换掉 yolov5s6.pt。

YOLOv5 的数据集格式是固定的:images 目录放原图,labels 目录放对应的 txt 标注文件,每行格式是class_id x_center y_center width height,坐标归一化到 0-1。还要准备一个 data.yaml:

# datasets/my_data/data.yaml train: datasets/my_data/images/train val: datasets/my_data/images/val nc: 2 # 类别数量 names: ["car", "truck"] # 类别名列表

训练命令:

python yolov5/train.py --data datasets/my_data/data.yaml --cfg yolov5s6.yaml --weights yolov5s6.pt --img 1280 --batch 8 --epochs 100 --hyp yolov5/data/hyp.scratch.yaml

逻辑说明:--weights 用 yolov5s6.pt 做预训练权重,可以加快收敛;--img 1280 和 s6 模型匹配;--hyp 指定超参数文件。训练阶段 YOLOv5 会自动应用 Mosaic、翻转、HSV 扰动等数据增强,这些属于训练侧策略,和推理侧 SAHI 切片不冲突。训练完成后,用 best.pt 替换 demo 里的模型路径,SAHI 不需要任何改动就能直接复用。

训练完如果发现检测效果一般,先切回去跑推理演示,确认数据标注没有错位,再回头看超参数。yolov5 超参数文件里 lr0、momentum、weight_decay 对收敛影响最大,新手不要一次全调,优先动 lr0。

4. 常见问题与排查:五个高频坑的现象、原因与解法

这章写的都是实际跑这个包时会撞上的问题。排查顺序我建议固定成:先看报错出现在哪个环节,是 import 阶段、加载权重阶段还是推理阶段,确定了环节再下手,别从第一行改到最后一行业。

4.1 import 报错:版本与安装顺序

现象:import sahi 或 from sahi import AutoDetectionModel 时报 ImportError,提示找不到 AutoDetectionModel。原因:sahi 版本过低或安装的是不完整包,旧版本还没有 AutoDetectionModel 这个类。另外,如果你把项目文件命名为 sahi.py,会导致 import 时加载到你自己的文件而不是真正库。解决:确认pip show sahi的版本是 0.8.4;把项目里所有和库同名的文件改名;最后用pip install --upgrade sahi==0.8.4强制重装一次。

4.2 CUDA 与 PyTorch 不匹配:torch.cuda.is_available() 为 False

现象:代码里 device="cuda:0",运行后报 Torch not compiled with CUDA enabled,或 GPU 显存占用了但计算在 CPU 上跑。原因:最典型的是 PyTorch 装了 CPU 版。pip 默认安装的 torch 1.7.1 不带 CUDA 支持,必须从官方 wheel 索引安装 +cu101 版本。另一个原因是显卡驱动太新,CUDA 10.1 不识别,但这种情况少见。解决:卸载重装明确指定 cu101:

pip uninstall torch torchvision -y pip install torch==1.7.1+cu101 torchvision==0.8.2+cu101 -f https://download.pytorch.org/whl/torch_stable.html

装完跑 check_env.py,确认 cuda available 为 True 再继续。如果机器没有 NVIDIA GPU,就把 main.py 里 device 改成 "cpu",这个 demo 跑得动,只是慢。

4.3 显存 OOM:RuntimeError: CUDA out of memory

现象:推理跑到一半报 CUDA out of memory,或 PyCharm 直接卡死。原因:slice 尺寸偏大、输入 image_size 是 1280,加上超分模块,显存压力叠加,8G 显存很容易不够。解决:优先把 slice_height 和 slice_width 从 512 降到 384,overlap 从 0.2 降到 0.1,然后逐步试。还不行就把 image_size 降到 960 或 640。实在不行先 device="cpu" 跑通,再回头优化显存。这个操作能解决 90% 的 OOM。

4.4 检测框坐标偏移

现象:导出可视化后发现检测框错位,框的位置明显和目标对不上。原因:SAHI 的输出已经是原图坐标,但如果你手动从 prediction_list 里取框再绘制,而没有用 bbox 的转换接口,拿到的可能是切片内坐标或归一化坐标。解决:坚持用结果的 export_visuals 和 export_as_json,不要自己写绘制逻辑。需要手动拿坐标时,用pred.bbox.to_xywh()或pred.bbox.to_xyxy(),这两个方法返回的就是映射回原图的坐标。

4.5 小目标仍然漏检或误检

现象:切片后效果有提升,但部分小目标还是没检测到,或类别判断错误。原因:切片尺寸选择不当。切片太大,目标在切片里仍然很小;切片太小,目标上下文丢失,误检率上升。另一个常见原因是 confidence_threshold 太高。解决:把 conf 降到 0.1 看输出,如果召回明显提升但误检增加,再升到 0.15 找平衡点;把切片调到 384 或 256 试一轮,观察漏检目标是否出现在边角,如果是就提高 overlap 到 0.3。

这里我整理了一张表,按现象快速定位:

现象定位方向首选解法
import 报错sahi 版本锁 0.8.4,检查同名文件
CUDA 不可用torch 版本重装 cu101 版本
显存溢出切片大小降 slice 到 384,降 image_size
坐标偏移后处理用 to_xywh / to_xyxy 接口
小目标漏检切片与阈值conf 降到 0.15,overlap 提到 0.3

5. 进阶技巧:切片大小、重叠率与超分辨率的配合经验

演示跑通后,下一步就是把这套组合用到自己的真实数据里。我先给一组经过多次验证的起步参数,你可以按目标尺寸对号入座:

目标尺寸建议切片建议重叠率建议超分倍数
< 16 像素256 - 3840.3 - 0.42x 或 4x
16 - 32 像素384 - 6400.22x
> 32 像素640 - 12800.1 - 0.2不开启

判断目标尺寸的方法很简单:用图像标注工具打开一张代表性图片,量一下目标框的宽和高,取中位数。如果中位宽高小于 16,直接上 256 切片加高重叠;如果接近 30 像素,384 切片最划算。别一上来就抄 512。

实际修改就是一个参数的问题:

result = get_sliced_prediction( "your_image.jpg", detection_model=detection_model, slice_height=384, # 按你的目标尺寸改 slice_width=384, overlap_height_ratio=0.3, overlap_width_ratio=0.3, )

手动取检测框做统计时,用这段代码:

for pred in result.object_prediction_list: x, y, w, h = pred.bbox.to_xywh() # 原图坐标系,单位是像素 label = pred.category.name conf = float(pred.score.value) print(f"{label}: {conf:.2f} at x={x:.0f}, y={y:.0f}, w={w:.0f}, h={h:.0f}")

超分辨率在什么时候真正有用,这也是踩出来的经验:目标本身是清晰但太小的,超分能把轮廓细节补出来,检测收益明显;目标在源图里就是模糊的,超分只能插值平滑,提升有限,别指望它把失焦的图“变清晰”,这不是玄学,是信息量的边界。所以我会建议先用切片方案跑一轮,把小目标漏检的图片单独拎出来,再决定要不要对这些切片单独开超分。

验证时别只盯着效果图看。我会把所有检测结果导成 JSON,和标注文件做一个简单的召回率统计,对比几种参数组合下的召回变化,判断 SAHI 到底提升了多少。如果你的 sahi 版本带了 evaluation 模块,也可以直接用它自带的评估接口对验证集做 mAP 计算,这比肉眼数框可靠得多。

那段时间我为了追求完美指标,把切片调到了 1024,结果 2080 显卡直接 OOM,折腾了一天才发现方向就错了。从那以后我每次跑小目标推理都先按目标尺寸倒推切片大小,再用 CPU 模式把流程完整走一遍,确认参数合理后才上 GPU,这套习惯帮我省了太多排查时间。希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 19:17:25

电力巡检YOLOv9绝缘子缺陷检测实战指南

简介&#xff1a;本资源是一套面向电力设备智能巡检与计算机视觉初学者的绝缘子缺陷检测专用数据集&#xff0c;聚焦输电线路运维场景中破壳、闪络损坏外壳、外壳正常及绝缘子串四类关键状态识别任务。数据集基于YOLOv9格式构建&#xff0c;经实测在标准验证集上达到93.5%的准确…

作者头像 李华
网站建设 2026/10/1 19:17:18

Agent Memory 实战:从记忆沉淀到 MCP 与 Docker 部署

1. 从“hindsight”这个词说起&#xff1a;为什么记忆是 Agent 最被低估的能力“hindsight”这个词本身很有意思&#xff0c;字面意思是“事后的洞察力”&#xff0c;也就是我们常说的“后见之明”。放在 LLM Agent 的语境里&#xff0c;它指向一个非常具体、也非常要命的问题&…

作者头像 李华
网站建设 2026/10/1 19:16:59

fdisk原理与实战:Linux磁盘分区底层工具详解

1. 为什么今天还要学 fdisk&#xff1f;——一个被低估却不可替代的分区基石工具你可能已经用过lsblk看磁盘布局&#xff0c;用过parted做 GPT 分区&#xff0c;甚至在图形界面里点几下就完成了分区操作。但只要你在 Linux 下真正做过服务器部署、嵌入式系统烧录、数据恢复现场…

作者头像 李华
网站建设 2026/10/1 19:16:24

多尺度排列熵参数优化:从原理到故障诊断实战

简介&#xff1a;面向需要优化多尺度排列熵&#xff08;MPE&#xff09;参数的研究者与工程人员&#xff0c;压缩包内给出了基于遗传算法&#xff08;GA&#xff09;和粒子群优化&#xff08;PSO&#xff09;的完整MATLAB实现。资源首先通过分析时间序列长度N、嵌入维数m、延迟…

作者头像 李华
网站建设 2026/10/1 19:16:22

openrig 配置编排实战:统一管理 Claude Code 与 Codex 的 YAML 方案

1. 从零认识 openrig&#xff1a;它到底解决什么问题第一次看到 openrig 这个名字&#xff0c;很多人会以为是某个硬件项目或者机械臂相关的工具&#xff0c;毕竟“rig”这个词在工程领域常指设备支架或测试台架。但如果你最近在折腾 Claude Code、Codex 这类命令行 AI 编程助手…

作者头像 李华