简介本资源为基于YOLOv8-OBB的芯片引脚缺陷检测完整项目采用TensorRT进行推理加速面向计算机、人工智能、电子信息等专业的在校学生、教师及企业开发者可用于毕业设计、课程设计、项目立项或工程实践。压缩包共394个文件约4.7MB以276个C头文件、36个hpp、28个cpp及7个cu文件为核心涵盖模型部署、ONNX解析、TensorRT推理与DeepSORT跟踪等模块另含PNG效果图、YAML配置、Markdown说明与PDF文档便于理解整体架构。项目已通过导师评审答辩成绩达95分代码经测试可正常运行。已有63人学习关注。读者可获得完整的缺陷检测方案、旋转框标注与训练思路、TensorRT加速部署流程及排错参考适合在现有代码基础上二次开发或直接用于毕设与课设。1. 芯片引脚缺陷检测为什么选 YOLOv8-OBB TensorRT从场景到落地的完整判断芯片引脚缺陷检测这个场景跟常规目标检测最大的区别在于引脚是细长条状目标密集排列、方向各异用普通水平框标注会把大量背景框进来IOU 计算和 NMS 都会失真。YOLOv8-OBB 的旋转框输出正好解决这个问题——它直接回归带角度的矩形贴合引脚的物理形态这也是我当初决定拆这套源码的核心原因。这份资源是一套完整的芯片引脚缺陷检测工程包含 YOLOv8-OBB 训练与推理代码、TensorRT 加速部署脚本、配套文档和全部资料适合做毕设、课设或工业检测方向的项目起步。它解决的不是能不能检测的问题而是检测完能不能跑得快、跑得稳的问题。如果你手上有 GPU 环境、想跑通一条从数据标注到 TensorRT 推理的完整链路这套东西值得花时间拆一遍。2. YOLOv8-OBB 旋转框原理与数据准备为什么普通框在引脚上会翻车2.1 旋转框相比水平框的数学差异普通 YOLO 检测框用(x, y, w, h)四个参数描述其中w和h分别对应水平方向和垂直方向的边长。引脚这类目标长宽比经常到 10:1 甚至更高而且排列方向不统一用水平框标注时框内会混入大量相邻引脚和基板背景。这带来两个直接后果一是分类分支学到的特征被背景稀释二是 NMS 阶段两个相邻引脚的框 IOU 虚高容易被误抑制。YOLOv8-OBB 在检测头输出上多了一个角度参数 θ框表示为(x, y, w, h, θ)其中 θ 通常定义在[-90°, 0°)或[0°, 90°)区间。损失函数里除了常规的 CIoU还引入了旋转框专用的 ProbIoU 或 KLD 损失。这套源码里检测头的输出通道数从4 nc变成了5 nc多出来的那一维就是角度。理解这一点很关键因为后面导出 ONNX 和转 TensorRT 时输出张量的 shape 会跟普通 YOLOv8 不一样很多人在这一步对不上号就是因为没意识到角度维的存在。2.2 数据标注格式与转换脚本OBB 任务常用的标注格式是 DOTA 格式每行是x1 y1 x2 y2 x3 y3 x4 y4 class_name difficult八个坐标点按顺时针排列。但 YOLOv8-OBB 训练时用的是归一化的class x y w h θ格式所以中间需要一个转换步骤。我一般会写一个脚本把 DOTA 格式转成 YOLO-OBB 格式核心逻辑是求四点的最小外接旋转矩形。import cv2 import numpy as np def dota_to_yolo_obb(dota_line, img_w, img_h): parts dota_line.strip().split() coords list(map(float, parts[:8])) cls_name parts[8] # 四点组成旋转矩形用 minAreaRect 求中心、宽高、角度 pts np.array(coords, dtypenp.float32).reshape(4, 2) rect cv2.minAreaRect(pts) # 返回 ((cx,cy),(w,h),angle) (cx, cy), (w, h), angle rect # YOLOv8-OBB 要求角度在 [0, 90)且宽为长边 if w h: w, h h, w angle 90 angle angle % 180 if angle 90: angle - 180 # 归一化到 0-1 cx, cy cx / img_w, cy / img_h w, h w / img_w, h / img_h return f{cls_name} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f} {angle:.6f}这段代码的关键点有三个cv2.minAreaRect返回的角度范围是[-90, 0)跟 YOLOv8-OBB 期望的[0, 90)不一致需要做一次转换宽高要保证w h否则角度语义会乱归一化必须用原图尺寸不能用裁剪后的尺寸。参数上img_w和img_h一定要跟标注时用的原图一致我见过有人用 resize 后的尺寸去归一化结果训练时框全部偏移排查了半天。2.3 数据集目录结构与 YAML 配置YOLOv8-OBB 的数据集目录跟普通检测基本一致只是标签文件后缀和内容不同。常见做法是dataset/ images/ train/ val/ labels/ train/ val/标签文件名跟图片同名后缀.txt。然后写一个data.yamlpath: ./dataset train: images/train val: images/val names: 0: bent_pin 1: missing_pin 2: short_pin这里names里的类别名要跟你的实际缺陷类型对应。芯片引脚常见缺陷包括弯曲、缺失、短路、氧化具体分几类取决于你的标注规范。注意类别顺序一旦定了就不要改因为后面训练权重、TensorRT 引擎里的类别索引都是按这个顺序固化的改了就得重新训练。3. 训练、导出 ONNX 与 TensorRT 加速从 pt 文件到 engine 的完整链路3.1 训练命令与关键超参这套源码的训练入口跟 Ultralytics 官方风格一致OBB 任务用yolov8n-obb.pt作为预训练权重。我一般会先用小模型跑通流程确认数据没问题再换大模型。yolo obb train \ modelyolov8n-obb.pt \ datadata.yaml \ epochs100 \ imgsz1024 \ batch8 \ lr00.01 \ degrees180.0 \ translate0.1 \ scale0.5 \ fliplr0.5 \ mosaic1.0参数说明imgsz1024是因为引脚目标小输入分辨率太低会丢细节但也要看显存8G 显存跑 1024 的 batch 只能给到 4 到 8degrees180.0是旋转增强对 OBB 任务特别重要因为引脚方向不固定不做旋转增强模型学不到角度不变性mosaic1.0保持默认但最后 10 个 epoch 建议关掉让模型在真实分布上收敛。lr00.01是初始学习率如果 loss 震荡厉害就降到 0.005。训练过程中重点看三个指标metrics/mAP50(B)是旋转框的 mAPtrain/box_loss和train/cls_loss是否同步下降。如果 box_loss 降但 mAP 不涨大概率是角度回归出了问题检查标注角度是否规范。3.2 导出 ONNX 的坑与参数训练完得到best.pt下一步是导出 ONNX。YOLOv8-OBB 的导出跟普通检测有个区别输出张量的最后一维是5 nc其中第 5 维是角度。导出命令yolo export \ modelbest.pt \ formatonnx \ imgsz1024 \ opset12 \ simplifyTrue \ dynamicFalseopset12是 TensorRT 兼容性比较好的版本太高或太低都可能遇到算子不支持。simplifyTrue会调用 onnx-simplifier 做图优化去掉冗余节点。dynamicFalse固定输入尺寸因为 TensorRT 在固定 shape 下优化最充分。导出后可以用 Netron 打开看一眼确认输出节点名字和 shape后面写 TensorRT 推理代码时要对上。3.3 TensorRT 引擎构建与推理TensorRT 加速的核心是把 ONNX 图编译成针对你具体 GPU 架构优化的 engine。这套源码里用的是 TensorRT Python API 或者 C API我以 Python 为例说明构建流程import tensorrt as trt logger trt.Logger(trt.Logger.WARNING) builder trt.Builder(logger) network builder.create_network( 1 int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser trt.OnnxParser(network, logger) with open(best.onnx, rb) as f: if not parser.parse(f.read()): for i in range(parser.num_errors): print(parser.get_error(i)) config builder.create_builder_config() config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 30) # FP16 精度速度提升明显精度损失通常可接受 config.set_flag(trt.BuilderFlag.FP16) engine builder.build_serialized_network(network, config) with open(best.engine, wb) as f: f.write(engine)参数说明EXPLICIT_BATCH是必须的否则 batch 维处理会出问题WORKSPACE设 1GB 一般够用太小会导致某些层无法用最优 kernelFP16标志打开后推理速度通常能提升 1.5 到 2 倍但要注意如果你的 GPU 是 GTX 10 系列FP16 支持不完整可能反而变慢这种情况就关掉用 FP32。构建 engine 的过程可能几分钟到十几分钟取决于模型大小和 GPU 性能这是正常的不是卡死。推理阶段的核心是预处理和后处理。预处理要把输入图 resize 到 1024、归一化、转成 NCHW后处理要把输出张量解码成旋转框再做旋转 NMS。旋转 NMS 比普通 NMS 复杂因为两个旋转框的 IOU 计算要用多边形交集常见做法是用cv2.rotatedRectangleIntersection或者 shapely 库。4. 避坑与排查TensorRT 版本、显存和角度回归的五个血泪经验4.1 现象engine 构建成功但推理结果全是乱框原因ONNX 导出时输出节点顺序跟推理代码里解析的顺序不一致。YOLOv8-OBB 的输出可能是[1, 5nc, 21504]这种格式需要先 transpose 再解码如果直接按[1, 21504, 5nc]解析坐标和角度全错位。解决用 Netron 打开 ONNX确认输出节点的实际 shape然后在推理代码里对应调整 transpose 逻辑。我一般会在解码前打印一次输出张量的 shape确认无误再往下走。4.2 现象TensorRT 10.x 在 GTX 1070 上构建失败或推理异常原因TensorRT 10.x 对 GPU 架构有最低要求GTX 1070 是 Pascal 架构算力 6.1部分新版本的 TensorRT 已经不再支持或需要额外配置。另外 FP16 在 Pascal 上支持不完整。解决如果必须用 GTX 1070建议降到 TensorRT 8.x 版本并且关闭 FP16用 FP32 构建 engine。如果换不了卡就在构建配置里显式设置config.set_flag(trt.BuilderFlag.FP16)之前先检查builder.platform_has_fast_fp16为 False 就不开。4.3 现象训练时 mAP 一直上不去loss 震荡原因角度标注不规范。DOTA 格式转 YOLO-OBB 时如果四点顺序不是顺时针或者角度归一化区间搞错模型学到的角度就是噪声。解决写一个可视化脚本把转换后的 YOLO-OBB 标签画回原图用cv2.boxPoints和cv2.drawContours检查每个框是否贴合引脚。这一步我每次换数据集都会做能省掉大量无效训练时间。4.4 现象推理时显存溢出OOM原因imgsz1024加上 batch 太大或者 TensorRT 的 workspace 设置过大挤占了推理显存。解决先降 batch 到 1 确认能跑通再逐步加。workspace 从 1GB 降到 512MB 试试。另外注意 PyTorch 和 TensorRT 同时占用显存的情况推理前把 PyTorch 模型del掉并torch.cuda.empty_cache()。4.5 现象旋转 NMS 后框大量丢失原因旋转框 IOU 阈值设得跟水平框一样比如 0.5但旋转框的 IOU 分布跟水平框不同0.5 可能过于激进。解决把旋转 NMS 的 IOU 阈值调到 0.3 到 0.4 之间试同时检查角度差是否参与 NMS 判断。有些实现会额外加一个角度差阈值两个框角度差超过一定值就不抑制这对密集引脚场景很有用。5. 进阶技巧用 engine 做批量推理与精度验证的实操习惯5.1 批量推理的显存与吞吐权衡TensorRT engine 构建时如果用了dynamicFalse那 batch 是固定的。但实际部署时经常需要变 batch这时候要么构建多个 engine要么用 optimization profile 做动态 shape。我一般会构建两个 engine一个 batch1 用于实时单帧一个 batch8 用于离线批量处理。构建动态 shape 的配置如下profile builder.create_optimization_profile() profile.set_shape(images, (1, 3, 1024, 1024), (4, 3, 1024, 1024), (8, 3, 1024, 1024)) config.add_optimization_profile(profile)set_shape的三个参数分别是最小、最优、最大 shape。TensorRT 会针对最优 shape 做优化所以把最常用的 batch 设成最优值。注意动态 shape 的 engine 构建时间更长而且推理时如果实际 shape 偏离最优值性能会下降。5.2 精度验证engine 输出跟 PyTorch 输出对齐TensorRT 加速后最怕精度掉太多。我的习惯是拿同一张图分别跑 PyTorch 和 engine对比解码后的框坐标和类别分数。允许的误差范围坐标误差在 1 到 2 个像素内分数误差在 0.01 以内超过就说明量化或算子替换出了问题。# 对比 PyTorch 和 TensorRT 输出 torch_out model(img_tensor) # PyTorch 推理 trt_out engine_infer(img_tensor) # TensorRT 推理 # 解码后对比 boxes_torch decode(torch_out) boxes_trt decode(trt_out) diff np.abs(boxes_torch - boxes_trt).max() print(f最大坐标偏差: {diff:.4f} 像素)如果偏差大先检查预处理是否完全一致归一化系数、resize 插值方式再检查 FP16 是否引入了累积误差。FP16 在角度回归上有时会有明显偏差因为角度值域小精度损失相对敏感。这种情况可以只对检测头部分保持 FP32其余层 FP16用config.set_flag配合层级别的精度设置。5.3 一个具体技巧用 engine 的序列化文件做版本管理TensorRT engine 是跟 GPU 架构和 TensorRT 版本绑定的换卡或升级 TensorRT 后必须重新构建。我吃过这个亏在实验室的 3090 上构建的 engine拿到现场的 2080 上直接加载失败。从那以后我每次构建 engine 都会在文件名里带上 GPU 型号和 TensorRT 版本比如best_rt8.6_3090.engine并且把构建脚本和 ONNX 一起归档。这样换环境时能快速定位该用哪个文件不会拿错。另外engine 文件通常比 ONNX 大而且不可读所以 ONNX 一定要保留它是可移植的中间格式。我的习惯是best.pt用于训练和微调best.onnx用于跨平台导出best_xxx.engine用于具体部署环境。三层文件各司其职缺一不可。这套源码把训练、导出、TensorRT 推理的链路都串好了文档里也有环境配置和依赖说明。如果你正在做芯片检测相关的毕设或项目直接拿这套代码改数据、调参数就能跑起来省掉从零搭框架的时间。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?