尧图精选

YOLOv5 TensorRT DLL版:不装Python也能跑目标检测

🕒 发布时间:2026/10/2 19:58:00 📁 来源:尧图网络
简介这份压缩包提供的是约洛夫张量YOLOv5模型结合 TensorRT 优化后的 DLL 版本实现面向希望在 Windows 环境下快速部署目标检测能力的开发者尤其适合边缘计算、自动驾驶、实时视频监控等对推理速度敏感的场景。包体非常紧凑共 8 个文件包含 2 个头文件和一个 C 源文件用于定义接口与示例调用逻辑另有 README、txt 说明及 license、git 配置等辅助文档压缩包大小约 18KB并附带了精简的工程目录。已有 79 人浏览学习对需要评估 TensorRT 加速方案的小型项目有较高参考价值。拿到资源后可借助封装好的 DLL 接口把优化后的 YOLOv5 检测功能接入自身程序减少自行转换与编译 TensorRT 引擎的链路成本同时通过头文件和 main.cpp 示例还能快速理解配置流程与关键调用方式便于后续按需修改和集成。1. yolov5 tensorrt 的 dll 版本不装 Python 也能跑检测一次调用返回带坐标的结果在一台没有 Python 环境、显卡驱动还很旧的 Windows 工控机上跑 yolov5 目标检测是很多做上位机和工业视觉的工程师都撞过的墙。所谓「约洛夫张量 dll」本质上就是 yolov5 tensorrt 的 dll 版本——把训练好的 .pt 权重换成 TensorRT 的 engine再包一层 C 接口的 DLL让 C、C#、LabVIEW 这类非 Python 程序直接调用。它解决的不只是「能不能跑」而是「能不能稳定地内嵌到别人的程序里」。适合两类人一类是要把检测塞进 MFC、Qt 界面的集成工程师另一类是手里有训练好的模型、却不想维护一套 Python 环境的部署新手。你拿到的不是一个黑匣子而是一条可以落地的推理链路只是这条链路上有几个坑不值得你亲自跳一遍。2. 拿到约洛夫张量 dll 包后先做三件事核对文件、装运行时、跑通最小 C 调用先泼一盆冷水这类压缩包十有八九不是单文件。你解压后如果只盯着那个 zip 里的 dll 就急着写代码大概率第一步就翻车。不管压缩包叫「约洛夫张量 dll」还是别的什么名字一个能用的 yolov5 tensorrt dll 版本交付物至少拆成三块接口动态库那个 .dll、导入库和头文件.lib、.h、以及推理引擎文件.engine 或 .trt。前两块决定你能不能编译最后一块决定你能不能跑出结果。部分包还会附带 model 目录和示例 exe但别把示例 exe 当成唯一验证手段——它跑通只能说明作者环境没问题不能说明你的环境没问题。2.1 压缩包里少了哪样东西会导致白忙一场核对文件是第一步常见做法是把所有文件按「编译期用」和「运行期用」分开摆。编译期你只需要头文件和 .lib运行期你除了 .dll还要把依赖的 TensorRT、CUDA/cuDNN 的 dll 一并备齐。最典型的翻车是包里只有 yolo_det.dll没有 .lib你用 Visual Studio 编译器根本链接不上因为 MSVC 默认不直接吃 dll它要的是 lib 里那几个导入符号。遇到这种情况可以在工程里改用 LoadLibrary GetProcAddress 走纯运行时加载绕开链接期依赖这也是后面最小示例采用的方式。另一个容易忽略的是位数匹配。x64 的 dll 只能被 x64 进程加载32 位调用方想去 LoadLibrary 一个 64 位 dllGetLastError 会给你一个模棱两可的错误码特别容易误判成「系统缺东西」。先确认你的宿主程序是 x64 还是 x86再看 dll 的位数两者不一致就别折腾依赖了直接换匹配版本。我一般还会把依赖的 dll 挨个列一遍用 Dependencies 工具打开主 dll看红色缺失项。注意这一步别用网上那些「dll 修复工具」一键补那些工具补的是系统目录里的通用 dll补不了 TensorRT 和 CUDA 专属运行时还可能把版本搞乱。2.2 最小 C 调用代码加载、初始化、推理、释放确认文件齐全后写第一版代码目标是「跑完不崩」不是「跑得最快」。下面这段用的是动态加载方式能在没有 .lib 的情况下工作也方便排查 dll 依赖问题#include windows.h #include cstdio #include vector // 假设接口头文件 —— 实际以你拿到的头文件为准 typedef void* YoloHandle; typedef int (*InitFn)(YoloHandle* h, const char* enginePath, float confThres, float nmsThres); typedef int (*DetectFn)(YoloHandle h, const unsigned char* rgbData, int width, int height, float* boxes, int* labels, float* scores, int* count); int main() { HMODULE dll LoadLibraryA(yolo_det.dll); if (!dll) { printf(load fail: %lu\n, GetLastError()); return -1; } auto init (InitFn)GetProcAddress(dll, YoloInit); auto detect (DetectFn)GetProcAddress(dll, YoloDetect); if (!init || !detect) { printf(proc fail\n); return -1; } YoloHandle h nullptr; int ret init(h, yolov5s.engine, 0.25f, 0.45f); if (ret ! 0) { printf(init fail: %d\n, ret); return -1; } // 假设输入是 640x640x3 的 RGB 连续内存 std::vectorunsigned char image(640 * 640 * 3, 128); std::vectorfloat boxes(100 * 6); std::vectorint labels(100); std::vectorfloat scores(100); int count 0; detect(h, image.data(), 640, 640, boxes.data(), labels.data(), scores.data(), count); printf(detect count: %d\n, count); return 0; }这段代码的调用链是LoadLibrary 拿到模块句柄GetProcAddress 取出两个导出函数init 加载 engine 并做 TensorRT 上下文初始化detect 传入 RGB 裸指针和宽高结果写进调用方预分配的内存。注意三点第一所有图像数据都是调用方自己准备的裸指针dll 内部不做拷贝外部必须保证 buffer 生命周期覆盖整个 detect 调用第二boxes 数组我按每框 6 个 float 预留x、y、w、h、score 是常见排布具体顺序要看头文件注释第三count 是输出参数而不是返回值因为不少 DLL 版本把返回值留给错误码检测数量靠指针带出来。2.3 返回结果的内存排布框、置信度、类别索引各占几位结果排布是另一处容易翻车的地方。常见做法是三个平行数组boxes、labels、scorescount 是有效条数。实现里最常见的布局是每个框 6 个 float前四个是坐标x1, y1, x2, y2 或 cx, cy, w, h第五个是置信度第六个在某些版本里是类别索引有些版本又把类别单独放到 int 数组里。也有版本用一个结构体数组比如typedef struct _YoloBox { float x1, y1, x2, y2, score; int classId; } YoloBox;这时候再按纯 float 数组解析就会错位。接到这类 dll 时先翻头文件里的结构体定义别靠猜。我在接这类 dll 时有个血泪经验先在文档里找「坐标是否已映射回原图」这句话找不到就直接用一张带规律图案的测试图跑。比如在白底上贴一个黑色矩形看返回坐标和矩形实际位置的偏差如果坐标和矩形边缘对不上但比例是对的说明返回的是 letterbox 后图像坐标外部要除以缩放系数再减去 pad如果完全乱掉则是通道顺序问题很可能是 dll 内部按 RGB 处理而你传进去的是 OpenCV 读出的 BGR。还要留意输出数量。YOLOv5 类的模型如果 onnx 里没挂 NMSDLL 端可能干脆把 25200 个候选框全部吐出来由调用方自己做后处理。这时 boxes 数组预留 100 个就不够看需要按 head 输出数量预留。判断方法很简单拿测试图跑一次如果 count 返回 25200 这种整数就说明 dll 只做了前向没做后处理阈值逻辑得写到自己这边。2.4 跨语言调用的坑stdcall 与 cdecl 选错会怎样如果调用方不是 C比如 C# 的 DllImport 或 LabVIEW 的调用库函数节点调用约定比接口签名更容易先出问题。C 默认 cdeclWindows 上很多 DLL 为了兼容 C 会导出为 cdecl但也有一些用 stdcallWINAPI导出。C# 侧不声明 CallingConvention.Cdecl就默认按 StdCall 去找栈平衡错位轻则参数全乱重则直接 AccessViolation。LabVIEW 里调用库函数节点也要在配置面板把 Calling Convention 选对否则在 64 位环境下指针参数会被截断。验证办法很简单看头文件里有没有__stdcall或WINAPI字样没有就是 cdecl有就按 stdcall 声明。C# 那边用[DllImport(yolo_det.dll, CallingConvention CallingConvention.Cdecl)]就能避免这类问题。3. 把推理参数调明白置信度阈值、输入尺寸与 batch 怎么搭配很多人拿到 dll 后只调一个置信度阈值发现要么误检爆炸、要么漏检严重于是开始怀疑模型不行。实际上 TensorRT DLL 版的推理效果是阈值、输入尺寸、batch 三个参数叠加的结果而且后处理的位置决定了阈值语义。这一章把每个参数该往哪个方向调、调到多少算合理讲清楚。3.1 阈值设 0.25 还是 0.45先确认 NMS 在 dll 内部还是外部YOLOv5 官方 detect.py 的默认配置是 conf 0.25、iou 0.45很多人照搬但这在 DLL 版上不一定成立原因在于 NMS 放在哪一侧。如果 dll 内部完成了候选框解码加 NMS那 conf 和 iou 就是 dll 的入参语义和官方一致0.25/0.45 直接能用。如果 dll 只输出原始 head25200 个候选全给你那外部做后处理时通常要先按 objectness 置信度过滤一遍再做类别分数乘算最后才进 NMS——这时候 0.25 是「第一道过滤」实际生效的阈值要看后续 NMS 的 iou 以及你对分数是否做了开方之类的变换。判断方法不需要看源码跑一次就行把 conf 调到 0.99 再调回 0.01观察 count 的变化。如果 0.99 时 count 变成 0说明 dll 内部有过滤逻辑如果仍然是几百上千个框说明 dll 只做前向。顺带一提有不少 DLL 版本在代码里把 25200 这个候选数写死如果你用的是自己训练的模型且输出头改过候选数也可能变化这时候就别在阈值上较劲先核对 onnx 输出维度。还有一种情况是 dll 内部的 NMS 实现用了固定的 iou 阈值你传进去的 nmsThres 根本没被使用——验证方法是把 nms 从 0.1 调到 0.9看重叠框的数量有没有明显变化没变化就说明该参数没接到后处理里。3.2 输入尺寸 640 之外letterbox 参数与坐标还原TensorRT 引擎通常是在固定输入尺寸下生成的最常见默认值是 640。直接用别的分辨率喂进去要么报 shape 不匹配要么 dll 内部帮你缩放到 640 再检测——后者会让小目标明显变弱。所以外部传入的 width、height 应该和生成 engine 时的尺寸一致不要想当然地「越大越准」。更大尺寸不一定更好YOLOv5 本身的输入分辨率训练时就固定了推理时强行拉到 1280小目标会好一点但速度和显存都按面积二次方涨工业场景里一般不值得。letterbox 是更隐蔽的坑。检测结果若返回的是 letterbox 后坐标你要画到原图上就得记录缩放系数 scale 和灰边偏移 pad。常见做法是 dll 在初始化时通过 init 函数额外输出一组 transform 参数或者让检测接口直接返回原图坐标。如果你的 dll 没有提供这个能力外部要自己按 YOLOv5 的 letterbox 逻辑复算// 原图 1280x720 - 引擎输入 640x640 的坐标还原示例 float scale std::min(640.0f / 1280.0f, 640.0f / 720.0f); // 0.5 float padX (640 - 1280 * scale) / 2.0f; // 0 float padY (640 - 720 * scale) / 2.0f; // 140 // 引擎输出坐标 (bx, by) 还原到原图 float origX (bx - padX) / scale; float origY (by - padY) / scale;这段计算的逻辑是letterbox 先按等比缩放找出 scale再在宽或高方向补灰边所以还原就是反向操作。注意 padX、padY 用的是像素数而不是比例坐标还原前先确认 dll 吐的坐标是相对引擎输入图还是相对原图。我见过不少集成项目在这里翻车症状统一是「框整体往右下偏移一段距离」因为忘记减 pad。如果你发现框的位置偏得很有规律顺便检查一下你是不是把 OpenCV 的 Mat 行主序数据直接当成了 CHW 排列——dll 若要求 CHW 而外部给 HWC推理结果会完全不可用但不报错。3.3 batch 与显存TensorRT 动态形状怎么给batch 参数决定单次推理能处理几张图。DLL 版通常有两种实现固定 batch 的 engine比如只有 1 或 8 两种规格和动态 batch 的 engine运行时指定 1~8 任意值。拿到包后先问一个问题你的应用是一帧一帧出结果还是一次要处理多路相机帧前者 batch1 足够后者才值得考虑 batch4 以上。不要为了「看起来快」盲目加大 batchTensorRT 的加速主要来自层融合和 fp16batch 带来的吞吐提升通常在多路并行时才明显单路情况下反而可能因为显存占用过高触发 OOM。动态 batch 在生成 engine 时体现为 min/opt/max shapes 三个值比如 images 输入分别设 1/4/8。运行时你向 dll 传入 batch 数必须落在 [min, max] 范围内否则 TensorRT 会拒绝执行。如果你用的是固定 batch 的 engine那 init 接口里通常不需要传 batch直接按 engine 内定值运行。显存配置上TensorRT 默认会尽量占满可用显存做 workspace某些 dll 版本没有暴露 workspace 参数遇到显存不足时优先去检查有没有其他程序占用显存而不是去调检测参数。给个经验参数yolov5s fp16 640 输入 batch1 的 engine推理显存占用一般在 1 到 2GB 量级这在 4GB 显存的工控卡上已经偏紧建议先用 nvidia-smi 看空闲显存再定 batch。大模型则成倍增长部署前先按 batch1 跑通再往上加。还有一个经常被忽略的维度是应用形态。如果你是用在产线上的单路工业相机25 帧实时就够batch1 足够真正拖时间的反而是外部读图、拷贝到显存、再把结果搬回来这三段如果你是多路相机并行batch4 或 8 能把 TensorRT 的执行效率拉满但要注意多路图像必须拼成一个连续张量拼接逻辑别写错。我一般建议把 batch 和 D2H 拷贝时间一起测别只看模型推理时间否则你会误以为「加大 batch 就能提高帧率」结果多路场景还是卡在传输上。4. dll 加载报错避坑从 Winerror 1114 到依赖冲突的排查顺序写好了调用代码不代表能跑通。Windows 上加载 TensorRT 推理 DLL 的报错花样非常多但根因高度集中依赖缺失、依赖版本错位、路径污染。按下面这个顺序排查能省掉大半宿的加班时间。这一章的每条经验都按「现象 → 原因 → 解决」来写照着对号入座。4.1 现象LoadLibrary 报「动态链接库初始化例程失败」如果你在 Python 侧用 ctypes 导入经常看到OSError: [WinError 1114] 动态链接库(DLL)初始化例程失败C 程序里表现为 LoadLibrary 返回 NULLGetLastError 是一个不太明确的错误码。原因基本是这个 dll 依赖的运行时缺失或初始化失败最常见的是 nvcuda.dll 加载不了驱动太旧、cudart/cudnn 版本对不上或者 TensorRT 本身没装好。解决思路是按依赖树检查不要盲目重装。先用 Dependencies 打开 yolo_det.dll看缺失项集中在哪里缺cudart64_*.dll或cublas64_*.dll说明 CUDA 运行时没就位把对应 CUDA 版本的 bin 目录加进 PATH或将 dll 复制到 exe 同目录缺nvinfer.dll那是 TensorRT 没装或 PATH 里没有 TensorRT 的 lib 目录。注意一个常见误解装 TensorRT 的安装教程通常要求同时装 CUDA 和 cuDNN三者的版本要严格匹配cuDNN 版本不匹配时 Winerror 1114 的出现频率极高。4.2 现象找不到指定模块报错却不说缺哪个 dllLoadLibrary返回 NULLGetLastError 提示找不到指定模块但 Windows 不告诉你具体是谁。这是依赖缺失的典型表现原因通常是某个系统 dll 缺失比如api-ms-win-*.dll或MSVCP140.dll或者是依赖链里某个第三方 dll 路径不在搜索范围。解决先用 Dependencies 打开主 dll 看红色缺项。缺MSVCP140.dll就装 VC 2015-2022 Redistributable x64缺api-ms-win-*一般是系统镜像太旧优先做 Windows 更新而不是去网上下单个 dll 补进 System32——那种做法治标不治本还可能触发安全软件的 dll 木马提示。提示遇到「找不到指定模块」但 Dependencies 显示全绿时把目标 dll 和 exe 放到同一目录再试。Windows 的 dll 搜索顺序是先 exe 目录再系统目录再 PATH。第三方目录里的同名 dll 经常被跳过导致加载失败。4.3 现象推理能跑但框坐标整体偏移、漏检严重这个不是加载报错而是运行时逻辑错往往比报错更难查。最典型的是坐标偏移所有框都往右下方移了一段幅度固定。原因几乎都是 letterbox 的 pad 没还原或者你传给 detect 的宽高和 engine 输入尺寸不一致dll 内部做了缩放但你没按同一比例还原。另一个经典问题是漏检同一张图在 Python 侧能检出dll 侧检不出先查你是不是把 BGR 当 RGB 传了进去再查 conf 阈值语义也就是前面 3.1 说的先确认 dll 有没有做 NMS。这种问题别去调 iou 阈值那是白费力气先把数据格式对齐。还有一种偶发情况fp16 引擎在低端显卡上对某些算子支持不完整输出会出现大面积 NaN检测结果全部消失这时候把引擎换成 fp32 跑一次就能确认是不是精度模式的锅。4.4 现象同一个 cudart64 存在多份程序加载了旧版本dll 冲突是这个场景里最玄学的一类。机器上可能同时装着 CUDA 10.2 和 CUDA 11.8各自的 bin 目录里都有 cudart64_*.dllPATH 里先出现谁你的程序就加载谁。如果你用的是 TensorRT 8.x CUDA 11.x 配套的 dll 版本加载到 CUDA 10.2 的 cudart初始化时往往直接崩溃或返回 Winerror 1114。解决不要把 CUDA 的 bin 目录一股脑加进系统 PATH推荐做法是把 exe 需要的 dll 全部复制到 exe 同目录让本地目录优先。还有一个隐蔽点OpenCV 的 opencv_world 版本冲突也属于同类问题。如果是 Python 的 cv2 报DLL load failed while importing cv2多半是系统 PATH 里混进了别的 opencv 或 numpy 依赖先看 import cv2 实际加载的是哪个路径下的文件。最后说一句 dll 修复工具的事。网上那些一键修复工具能处理的只是 msvcp140、vcruntime 这类通用运行库对本场景里的 cudart、nvinfer 这类 TensorRT 专属 dll 帮不上忙反而可能拿旧版本覆盖新版本让原本正常的程序也挂掉。我见过一台机器本来只是 TensorRT 8 的问题用修复工具扫完CUDA 11 的 bin 里混进了 CUDA 10 的 dll从此所有程序都在初始化时崩溃。手工排查才是这个场景的正路。5. 从 pt 文件到 engineDLL 版本背后的导出与转换链路如果你的压缩包里已经带了现成的 engine可以跳过这一章但如果你拿到的是「dll 训练好的 .pt」或者你想换一个自己训练的模型进去就必须自己走一遍 pt → onnx → engine 的链路。这也是 pytorch 权重转换成 tensorrt 的标准路径dll 本身不参与转换它只负责加载 engine 和做推理。搞清楚这条链路你才能判断手里的 dll 到底支不支持换模型以及换了之后哪些参数会跟着变。5.1 pt 导出 onnxopset、动态维度与输出节点三个关键点用官方 export.py 导出 onnx 是最常见的做法但有几个参数值得盯住。第一条是 opsetTensorRT 8.x 对 onnx opset 的兼容区间以 12~17 为主我一般固定用 12太新可能踩到不支持的算子太老则某些自定义节点导不出来。第二条是动态维度如果 dll 支持动态 batch导出时加--dynamic如果 dll 是固定输入就别加省得 trtexec 时还要配 shape。第三条是输出节点YOLOv5 默认导出是三个 head 的输出如果你在 onnx 里挂了 NMS 节点TensorRT 端要额外依赖 EfficientNMS 插件dll 的加载逻辑也得配套很多 dll 版本根本不支持这种 onnx所以最稳妥的导出方式是裸输出把后处理留在 dll 或调用方。python export.py --weights runs/train/exp/weights/best.pt \ --include onnx --opset 12 --dynamic --batch-size 1这条命令的语义是从训练好的 best.pt 导出动态 batch 的 onnx输入名默认是 images输出是三个 head 的原始张量。如果你的模型输入宽度不是默认 640先改 export.py 里的 img-size 参数或在命令行加--img 1280保证导出和后续 trtexec 一致。导出后先用 onnxruntime 跑一遍确认输出 shape 符合预期——这一步能拦下九成转换坑不要直接上 trtexec。如果你用的是自己训练的数据集类别数 N 不是 80导出 onnx 时输出头最后一维会从 85 变成 41N。这个差异 dll 解析时必须同步调整——如果 dll 写死了 85你的模型类别数对不上推理出来类别索引全部错位看起来像模型完全不准。解决确认 dll 有没有暴露 classNum 参数如果写死只能改 dll 或换一个能配置类别数的版本。5.2 用 trtexec 生成 enginefp16、workspace 与 min/opt/max shapes拿到 onnx 后用 trtexec 转 engine是 NVIDIA 官方最省事的方式也最容易复现。常见命令trtexec --onnxyolov5s.onnx \ --saveEngineyolov5s.engine \ --fp16 \ --minShapesimages:1x3x640x640 \ --optShapesimages:1x3x640x640 \ --maxShapesimages:8x3x640x640参数逐个说--fp16打开半精度对 YOLOv5 这类卷积网络收益明显yolov5s 在 fp16 下精度损失通常可忽略是部署首选--minShapes/optShapes/maxShapes只在动态 onnx 下生效分别定义 batch 的最小、最优、最大值运行时传 batch 必须落在区间内如果不加这三个参数trtexec 会按静态 shape 生成 engine运行时就不能改 batch。workspace 参数在老版本叫--workspace2048新版本改成--memPoolSizeworkspace:2048含义是允许 TensorRT 用多少显存做优化给太低会触发部分算子未被选中的问题给太高也不会更快。转换完成后先别急着接 dll可以用 trtexec 自带--loadEngine加--shapes跑一下能正常输出就说明 engine 生成没问题。这一步很多人跳过结果 dll 初始化失败时分不清是 dll 的问题还是 engine 的问题。5.3 engine 与 dll 的匹配验证输入名、输出名、精度逐个核对engine 是本人dll 是壳两者必须匹配。匹配有三个维度输入名、输入 shape、输出节点。如果 dll 内部写死了输入名 images你导出的 onnx 输入名却不是这个TensorRT 在加载时会直接报错如果你用--fp16生成的 engine喂给一个只支持 fp32 的 dll 调用方某些 dll 会在内部检查数据类型某些则会直接跑出 NaN 一样的乱框。我一般会在接 dll 前先写一段极简 Python 脚本用 tensorrt 加载 engine 打印输入输出名和数据类型import tensorrt as trt with open(yolov5s.engine, rb) as f: runtime trt.Runtime(trt.Logger(trt.Logger.WARNING)) engine runtime.deserialize_cuda_engine(f.read()) for i in range(engine.num_io_tensors): name engine.get_tensor_name(i) mode engine.get_tensor_mode(name) print(mode, name, engine.get_tensor_shape(name), engine.get_tensor_dtype(name))这段代码的作用是把 engine 的输入输出信息打印出来和 dll 的头文件注释逐项对照。输入一般是 shape [N,3,640,640] 的 float32 或 float16输出是三个 head 或已拼接的张量。对照时注意如果 dll 是按「单个输出」设计的而你的 onnx 是三个 head 输出两者不匹配dll 侧会崩溃或只取第一个 head检测结果会少一半框。这个检查只需要半分钟能挡掉大量后续联调时间。另外engine 文件对 TensorRT 版本是敏感的同一个 engine 在 TensorRT 8.4 下生成用 8.6 的运行时可能拒绝加载。拿到包后先确认 dll 依赖的 TensorRT 版本再决定用什么版本的环境去生成 engine这点最容易被人忽略。6. 验证 dll 推理结果靠不靠谱一张测试图、四个检查点理论讲完最后一步是把 dll 当成一个黑盒子来验收。我会用一张固定测试图把验证拆成四个检查点全部通过才敢往产线上放。第一个检查点是确定性同一张图连续推理 10 次坐标和置信度必须完全一致fp16 下允许 1e-3 级别的小抖动但框不该跳变。第二个检查点是和基准对比在 Python 侧用 onnxruntime 或原始 pytorch 对同一张图出一份结果和 dll 输出比对同一个目标的框 IOU 要大于 0.9。第三个检查点是边界行为传一张纯黑图、一张纯白图程序不应崩溃count 应为 0 或极小值传异常尺寸比如宽高为 0应返回错误码而不是死锁。第四个检查点是稳定性连续跑 1000 帧显存占用应平稳不随时间增长——TensorRT 的 context 若每帧重复创建显存会像漏水一样往上爬。// 验收时我固定跑这个循环统计显存和耗时 for (int i 0; i 1000; i) { detect(h, frame.data(), 640, 640, boxes.data(), labels.data(), scores.data(), count); if (i % 100 0) printf(frame %d, count %d\n, i, count); }跑完四个检查点再去做阈值微调才有意义。我的教训是不要一上来就对着测试视频调参数那是给后续埋雷先把上面四条跑完再谈效果。这里还有一个「后悔药」式的习惯每次换 engine 或改 dll 之前把旧版本和当前测试图的结果截图存档出问题时能快速二分排查是引擎退化还是调用方改动引入的问题。希望这些经验能帮到你至少让你少走几趟我走过的弯路。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →