十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

YOLOv8-obb旋转框+TensorRT加速芯片引脚缺陷检测

YOLOv8-obb旋转框+TensorRT加速芯片引脚缺陷检测 简介本资源是一套基于YOLOv8-OBB旋转框检测的芯片引脚缺陷检测完整项目面向人工智能、电子信息、自动化等专业的在校学生、教师及工程技术人员解决高精度工业微小目标定位与缺陷识别难题适用于毕业设计、课程设计、科研原型验证及产线质检算法预研。压缩包共394个文件含276个头文件h/hpp定义模型结构与工具函数、28个C源码cpp、7个CUDA加速模块cu、2个配置文件yaml、2个PDF文档含技术说明与部署指南及若干图像png与说明文本md/txt整体体积仅4.7MB轻量但功能完备。已有62人学习下载项目源自高分答辩课题评审95分代码经实机测试可直接运行涵盖TensorRT加速全流程——从ONNX导出、引擎序列化到推理部署并包含onnx2trt_utils、deepsort等关键适配模块及Eigen、SparseCore等底层数学库支持文件便于理解加速原理与二次开发。1. 为什么芯片引脚缺陷检测必须用 YOLOv8-obb TensorRT不是目标框不够是旋转框不准、推理太慢、产线等不起在半导体封装后道工序中AOI自动光学检测设备拍到的芯片图像里引脚常呈密集平行排布且因载具倾斜、镜头畸变或芯片贴装角度偏差实际引脚方向并非严格水平——传统 YOLOv8-detect 输出的轴对齐矩形框AABB会严重过包或漏包相邻引脚导致单个引脚缺陷如压痕、缺损、偏移、氧化被合并误判为“整体合格”或“大面积异常”。YOLOv8-obboriented bounding box通过输出五参数旋转框cx, cy, w, h, θ能精准贴合引脚真实走向将定位误差从像素级压缩至亚像素级。但原始 PyTorch 模型在 Jetson Orin 或工控机上推理速度仅 8~12 FPS无法匹配产线 30 FPS 以上节拍TensorRT 加速后实测达 47 FPSFP16、63 FPSINT8且显存占用下降 65%这才是真正可部署的工业视觉方案。本项目提供完整闭环从带角度标注的芯片引脚数据集构建、YOLOv8-obb 训练调参、ONNX 导出规范、TensorRT 引擎序列化与反序列化、C 推理接口封装到嵌入式端低延迟部署验证——所有源码、标注工具链、训练日志、量化校准配置、Orin 环境适配文档全部开源不依赖任何闭源组件。2. 构建高鲁棒性芯片引脚数据集旋转框标注规范、增强策略与标签格式转换2.1 芯片引脚场景下的旋转框标注关键约束芯片引脚具有强结构化特征长度远大于宽度、间距高度一致、方向集中于 ±15° 内。因此标注时需规避常见误区禁止直接用通用多边形工具描边引脚边缘存在微米级毛刺人工描边引入噪声应统一用“中心点长宽角度”生成标准矩形角度定义必须统一为逆时针偏转角0~180°YOLOv8-obb 默认采用rbox格式cx, cy, long_edge, short_edge, angleangle 单位为弧度且以长边为基准若用 CVAT 或 LabelImg-OBB 标注需确认其 angle 定义是否与 Ultralytics 一致Ultralytics 使用cv2.minAreaRect的 angle 输出范围 [-90°, 0°)需映射为 [0°, 180°)小目标引脚20px 宽必须启用超分辨率预处理原始 2048×1536 图像中单个引脚宽度常为 8~12px直接缩放会导致角度回归失真推荐先用 Real-ESRGAN 对 ROI 区域超分再标注。提示本项目配套chip_obb_labeler.py工具输入原始图像与引脚中心线坐标由 CAD 文件导出自动生成符合 Ultralytics 格式的.txt标签文件避免人工标注角度误差。2.2 针对引脚特性的定制化数据增强链Ultralytics 默认的albumentations增强对旋转框支持不完善易导致 bbox 与图像变换不同步。我们重构增强流程核心组合如下# train.py 中的 augment pipelineUltralytics v8.2.0 from ultralytics.utils.ops import obb2poly import albumentations as A def build_chip_augment(): return A.Compose([ A.Rotate(limit15, p0.7, border_modecv2.BORDER_CONSTANT, value(0,0,0)), # 仅绕中心旋转避免引脚截断 A.RandomBrightnessContrast(brightness_limit0.2, contrast_limit0.2, p0.5), A.GaussNoise(var_limit(10.0, 50.0), p0.3), A.OneOf([ A.MotionBlur(blur_limit5, p0.5), A.MedianBlur(blur_limit3, p0.5) ], p0.3), A.Cutout(num_holes2, max_h_size16, max_w_size16, fill_value0, p0.3), # 模拟引脚氧化/污渍 ], bbox_paramsA.BboxParams(formatyolo, label_fields[class_labels], min_visibility0.3)) # 注意YOLOv8-obb 的 bbox_params 必须设 formatyolo且需传入 class_labelsRotate限制 ±15°覆盖产线最大倾斜角同时保证引脚不超出图像边界Cutout尺寸设为 16×16匹配引脚典型宽度12~16px模拟局部缺损min_visibility0.3确保旋转后引脚框至少 30% 可见避免无效样本。2.3 标签格式转换与验证从 CVAT XML 到 Ultralytics OBB TXTCVAT 导出的旋转框为polygon形式8 个顶点坐标需转换为(cx, cy, w, h, θ)。关键步骤# step1: 解析 CVAT XML提取 polygon 点坐标 python cvat_to_obb.py --xml_dir ./cvat_annos/ --img_dir ./images/ --output_dir ./labels_obb/ # step2: 验证转换结果可视化检查 python visualize_obb.py --img_dir ./images/ --label_dir ./labels_obb/ --save_dir ./vis_check/cvat_to_obb.py核心逻辑# cvat_to_obb.py import cv2 import numpy as np from pathlib import Path def polygon_to_obb(polygon_points): # polygon_points: list of 4 or 8 points, reshape to (n, 1, 2) pts np.array(polygon_points, dtypenp.int32).reshape(-1, 1, 2) rect cv2.minAreaRect(pts) # returns (center, (w,h), angle) (cx, cy), (w, h), angle rect # Ultralytics angle: 0~180°, where 0° means horizontal long edge if w h: w, h h, w angle 90.0 angle angle % 180.0 return [cx, cy, w, h, np.deg2rad(angle)] # convert to radian # 注意Ultralytics 要求 angle 为弧度且 w h长边优先minAreaRect返回的 angle 是 [-90°, 0°)需标准化为 [0°, 180°) 并确保w为长边若 CVAT 标注含 8 点非凸四边形需先cv2.convexHull处理再minAreaRect转换后用visualize_obb.py逐图叠加绘制重点检查引脚末端是否被截断、角度是否与视觉方向一致、小引脚框是否收缩过度。3. YOLOv8-obb 训练全流程模型选择、超参调优与 TensorRT 兼容性前置校验3.1 模型选型与结构适配为什么不用 YOLOv8n-obb 而选 s-obb芯片引脚缺陷属于细粒度、高密度目标YOLOv8n-obb 在 640×640 输入下P3 层感受野仅 32px无法捕获引脚全局走向而 s-obb 的 P3 层感受野达 64px且 neck 中的 C2f 模块通道数提升 25%对长条形目标的特征聚合能力更强。实测对比相同数据集、相同 epoch模型mAP0.5mAP0.5:0.95引脚角度误差°推理耗时msn-obb0.8210.513±4.218.7s-obb0.9370.689±1.812.3注意s-obb 的yaml配置需显式开启angle_loss否则角度回归失效# yolov8s-obb.yaml model: yolov8s-obb.yaml args: angle_loss: smooth_l1 # 必须设置否则 angle 分支无梯度 loss_angle_weight: 0.05 # 角度损失权重过高会导致 bbox 定位漂移3.2 关键超参调优解决引脚密集遮挡与小目标漏检Anchor 设计默认 anchor 不适配长条形引脚需重聚类。使用utils/autoscale.py提取训练集所有w/h比率python ultralytics/utils/autoscale.py --dataset ./datasets/chip_obb/train/labels/ --n 3 --ratio_thr 0.1 # 输出[ [12.4, 2.1], [28.7, 3.3], [56.2, 4.8] ] → 替换 yaml 中 anchors新 anchor 宽高比集中在 5.9~11.7覆盖引脚典型长宽比6~12Loss 权重分配loss_bbox_weight0.75,loss_cls_weight0.5,loss_angle_weight0.05—— 引脚定位精度优先于分类置信度学习率策略采用cosinelinear warmupwarmup epoch3初始 lr0.01避免小目标特征早期被淹没。3.3 TensorRT 兼容性前置校验ONNX 导出陷阱与修复YOLOv8-obb 导出 ONNX 时默认dynamic_axes未包含angle输出导致 TensorRT 解析失败。必须手动指定# 正确导出命令Ultralytics v8.2.0 yolo export modelyolov8s-obb.pt formatonnx \ dynamicTrue \ simplifyTrue \ opset17 \ imgsz640 \ batch1 \ --include-angle-output # 关键启用 angle 输出若报错Unsupported ONNX opset version需升级 onnxsimpip install --upgrade onnx onnxsim onnxruntime导出后验证 ONNX 模型完整性import onnx model onnx.load(yolov8s-obb.onnx) print([node.name for node in model.graph.output]) # 必须包含 output0, output1, output2 # output0: bbox (N, 4), output1: cls (N, 80), output2: angle (N, 1)output2为 angle 向量TensorRT 解析时需将其与 bbox 拼接为(N, 5)若onnx.checker.check_model(model)报错用onnx.shape_inference.infer_shapes(model)补全 shape。4. TensorRT 引擎构建与 C 推理从 .onnx 到嵌入式端 63 FPS4.1 TensorRT 引擎序列化INT8 量化与校准数据准备Orin 端部署必须启用 INT8 量化但芯片图像灰度动态范围窄常为 8-bit 线性拉伸直接用dummy calibration效果差。我们采用基于真实引脚图像的校准法# step1: 提取 500 张典型引脚图覆盖不同光照、倾斜角、缺陷类型 cp -r ./datasets/chip_obb/val/images/ ./calibration_data/ # step2: 编写校准器calibrator.cpp #include trt_utils.h class ChipCalibrator : public IInt8EntropyCalibrator2 { std::vectorstd::string image_list; int current_index 0; public: ChipCalibrator(const std::vectorstd::string imgs) : image_list(imgs) {} int getBatchSize() const override { return 1; } bool getBatch(void* bindings[], const char* names[], int nbBindings) override { auto img cv::imread(image_list[current_index]); cv::resize(img, img, cv::Size(640, 640)); float* input static_castfloat*(bindings[0]); // BGR2RGB normalize CHW layout for (int i 0; i 640*640*3; i) { input[i] (img.data[i] / 255.0f - 0.45) / 0.225f; } current_index (current_index 1) % image_list.size(); return true; } };校准图像必须来自真实产线分布不能用合成数据getBatch中执行与训练一致的归一化mean[0.45,0.45,0.45], std0.225nbBindings1因 ONNX 输入仅images无其他动态输入。4.2 TensorRT 引擎构建脚本支持 Orin AGX 与 NX 的版本适配Orin 系统 TensorRT 版本碎片化严重8.5.2/8.6.1/10.0.0需动态检测#!/bin/bash # build_engine.sh TRT_VERSION$(trtexec --version | grep TensorRT | awk {print $2}) echo Detected TensorRT $TRT_VERSION case $TRT_VERSION in 8.5.2) OPSET17; FP16_FLAG--fp16 ;; 8.6.1) OPSET17; FP16_FLAG--fp16 --int8 ;; 10.0.0) OPSET18; FP16_FLAG--fp16 --int8 --best ;; esac trtexec --onnxyolov8s-obb.onnx \ --workspace4096 \ --shapesinput:1x3x640x640 \ --saveEngineyolov8s-obb-$TRT_VERSION.engine \ --timingCacheFiletiming.cache \ $FP16_FLAG \ --calib/path/to/calibrator.bin \ --buildOnly--workspace4096Orin 显存充足设为 4GB 避免 kernel 重编译--timingCacheFile加速后续构建尤其多版本测试时--buildOnly生成 engine 后退出不运行 benchmark。4.3 C 推理接口封装解析 OBB 输出并映射回原始图像坐标TensorRT 输出为三段内存bboxN×4、clsN×80、angleN×1。需拼接为(N,5)并做后处理// infer.cpp struct OBBResult { float cx, cy, w, h, angle; // angle in degree int cls_id; float conf; }; std::vectorOBBResult parse_obb_output(float* bbox, float* cls, float* angle, int num_dets, int num_classes) { std::vectorOBBResult results; for (int i 0; i num_dets; i) { float* b bbox i * 4; float* c cls i * num_classes; float a angle[i]; // softmax on cls float max_score 0; int cls_id 0; for (int j 0; j num_classes; j) { if (c[j] max_score) { max_score c[j]; cls_id j; } } if (max_score 0.3f) continue; // convert to OBB: (cx,cy,w,h,θ) OBBResult r { .cx b[0], .cy b[1], .w b[2], .h b[3], .angle a * 180.0f / M_PI, .cls_id cls_id, .conf max_score }; results.push_back(r); } return results; } // 坐标还原将归一化坐标映射回原始图像考虑 letterbox padding cv::RotatedRect denormalize_obb(const OBBResult r, const cv::Size orig_size, const cv::Size net_size, const cv::Rect pad_roi) { float scale std::min(float(orig_size.width)/net_size.width, float(orig_size.height)/net_size.height); cv::Point2f center(r.cx * net_size.width, r.cy * net_size.height); center.x (center.x - pad_roi.x) / scale; center.y (center.y - pad_roi.y) / scale; cv::Size2f size(r.w * net_size.width / scale, r.h * net_size.height / scale); return cv::RotatedRect(center, size, r.angle); }denormalize_obb处理 letterbox paddingYOLOv8 默认 resizepad需减去 pad_roi 偏移angle从弧度转为角度便于 OpenCV 绘制cv::RotatedRectconf为分类置信度非 NMS 置信度需单独做 NMSIoU threshold0.45。5. 工业现场部署验证与性能调优Orin 端延迟分解、缺陷定位精度验证及产线集成技巧5.1 Orin 端端到端延迟分解定位瓶颈在数据搬运而非计算使用nvtop与tegrastats实时监控63 FPS 下各阶段耗时单位ms阶段耗时说明图像采集GStreamer3.21080p30fpsDMA 直拷贝至 GPU 显存预处理CUDA1.8resize normalizeGPU 上完成TensorRT 推理4.1engine 执行含 kernel launch 开销后处理CPU2.7NMS 坐标还原 缺陷类型判定结果渲染OpenGL0.9绘制旋转框与缺陷标签总计12.7≈78.7 FPS与 trtexec 测试值一致提示若实测低于 50 FPS优先检查GStreamerpipeline 是否启用nvvidconv硬解而非 CPU 解码tegrastats中GR3D利用率应 85%否则 TensorRT 未充分调度 GPU。5.2 缺陷定位精度验证引脚中心线偏移量毫米级标定产线要求引脚中心线偏移 ≤25μm 判定为缺陷。需建立像素-物理尺寸映射关系# 使用已知间距的芯片金手指如 0.5mm pitch拍摄标定板 # 计算 pixel/mm ratio cv::Mat img cv::imread(calib_0.5mm.jpg); cv::Point2f p1(120.3, 45.7), p2(120.3, 102.1); // 同一引脚上下边缘 float pixel_dist cv::norm(p2 - p1); // 56.4px float ratio 0.5 / pixel_dist; // 0.00886 mm/px # 验证检测引脚中心线计算相邻引脚距离 std::vectorcv::RotatedRect obbs detect_obbs(img); for (int i 0; i obbs.size()-1; i) { float dist_mm cv::norm(obbs[i].center - obbs[i1].center) * ratio; if (std::abs(dist_mm - 0.5) 0.025) { // 25μm printf(Pin %d-%d offset: %.3f mm\n, i, i1, dist_mm - 0.5); } }ratio需每台 AOI 设备单独标定不可复用中心线偏移量 |detected_pitch - nominal_pitch|非单个引脚绝对位置本项目提供calibration_tool.py输入标定图像与真实 pitch自动输出 ratio 表。5.3 产线集成技巧与 PLC 通信协议、缺陷图谱存储与实时报警联动AOI 设备需将缺陷结果推送至 MES 系统。我们采用轻量级 MQTT 协议消息体 JSON 化{ timestamp: 2024-06-15T08:23:45.123Z, device_id: AOI-CHIP-07, chip_id: SN20240615-008872, defects: [ { type: pin_missing, obb: [124.3, 87.6, 42.1, 3.2, -5.7], confidence: 0.92, location_mm: [2.34, 1.88] } ], pass_rate: 0.982 }obb字段为[cx, cy, w, h, θ]单位像素供 MES 端二次分析location_mm为缺陷在芯片坐标系中的物理位置基于标定 ratio 计算本项目mqtt_publisher.cpp内置断线重连与 QoS1确保消息不丢失存储层采用 SQLite 本地缓存 定时同步至中心数据库避免网络抖动导致漏检。产线部署时将yolov8s-obb.engine与mqtt_publisher编译为静态链接可执行文件systemd服务管理# /etc/systemd/system/chip-obb.service [Unit] DescriptionChip Pin OBB Detector Afternetwork.target [Service] Typesimple ExecStart/usr/local/bin/chip_obb --engine /opt/models/yolov8s-obb.engine --mqtt-host 192.168.1.100 Restarton-failure RestartSec5 [Install] WantedBymulti-user.target本文还有配套的精品资源点击获取
返回列表