端侧 YOLO 检测结合大模型告警
文章目录1. 先写成 JSON2. 先说结论3. 事件字段与上一篇对齐4. 写入事件前先做过滤5. 核心模块event_writer.py6. 先用假数据把事件写入跑通7. 接到现有 YOLO / TensorRT 循环7.1 最小插入方式7.2 视频循环里还要注意7.3 和 detect_trt.py 的分工8. JSON 稳定后再接解释层9. 常见坑9.1 每帧都写 JSON9.2 类别名混乱9.3 先接大模型事件还不稳定9.4 截图路径写了但文件不存在9.5 把 EventWriter 写死进引擎代码深处9.6 多目标同一帧全部写成事件9.7 事件目录与检测工作目录不一致10. 验收清单11. 小结12. 相关阅读摘要上一篇把端侧应用封装成「检测 → 事件 → 小模型解释」。卡点通常不在解释脚本而在检测结果仍停在画框上下游拿不到稳定输入。本文写如何把现有 YOLO / TensorRT 检测输出自动写成events/*.json字段约定、阈值过滤、冷却去重、截图保存以及怎样接到已有推理循环。适合已经跑通 Orin 检测闭环准备接大模型解释层的人。可与 Orin 上目标检测 大模型做端侧应用、Orin 上目标检测最小闭环 一起看。建议目录可与上一篇共用mkdir-p~/orin-edge-app/{events,scripts,out,logs,snapshots}cd~/orin-edge-app# 本文新增event_writer.py / demo_from_detections.py / watch_and_explain.sh文件作用scripts/event_writer.py过滤、冷却、写 JSON、可选存截图scripts/demo_from_detections.py用一组假检测结果验证事件写入逻辑scripts/watch_and_explain.sh监听到新事件后调用解释脚本可选1. 先写成 JSON很多检测程序到这一步就停了屏幕上有框终端打印了检出 N 个目标下一帧继续画对值班系统和大模型解释层来说这还不够。它们需要的是可消费的记录什么时间、哪路相机、什么类别、置信度多少、要不要重复报。图1. 画框是给人看的events/*.json才是给下游系统看的。所以本篇目标很具体不重写整个检测工程只在“得到 boxes / scores / cls_ids”之后多写一步把结果保存成事件文件。2. 先说结论步骤做什么1复用上一篇的事件字段保证解释层不用改2只对白名单类别 高置信度目标写事件3同一相机、同一类别加冷却避免短时间重复告警4把结果写成 JSON同时可选保存截图路径5JSON 稳定后再接explain_event.py事件层是检测和大模型之间的稳定接口。先过滤和冷却再谈解释否则语言模型会被误报灌爆。先用假检测数据把事件写入跑通再挂到真实detect_trt.py循环。图2. 检测输出 → 过滤 → 冷却 → 写成 JSON。3. 事件字段与上一篇对齐继续使用这套字段与上一篇一致便于直接喂给解释脚本字段来源event_id相机 时间 序号ts告警时刻camera_id/line_id配置写入defect类别名由 cls_id 映射confidence检测分数bbox[x1,y1,x2,y2]取整即可repeat_count_1min冷却窗口内计数snapshot_path可选截图kb_hint可选先留空或写固定提示示例{event_id:cam01-20260804-093000-001,ts:2026-08-04T09:30:00,camera_id:cam01,line_id:line-A,defect:scratch,confidence:0.91,bbox:[100,120,240,260],repeat_count_1min:2,snapshot_path:snapshots/cam01_20260804_093000.jpg,kb_hint:}4. 写入事件前先做过滤图3. 白名单、阈值、冷却决定事件质量。规则建议默认说明类别白名单只保留缺陷类COCO 通用模型先自己映射关心的类置信度阈值如0.50起可比可视化阈值更高减少垃圾事件冷却时间如同相机同类1030s防止同一缺陷每帧都写文件没有这三个规则大模型解释层会变成“误报扩音器”。5. 核心模块event_writer.py保存为scripts/event_writer.py#!/usr/bin/env python3把检测结果写成 events/*.json。 输入约定 boxes: Nx4, xyxy scores: N cls_ids: N from__future__importannotationsimportjsonimporttimefromdataclassesimportdataclass,fieldfromdatetimeimportdatetimefrompathlibimportPathfromtypingimportDict,Iterable,List,Optional,Sequence,Tupleimportcv2importnumpyasnpdataclassclassEventWriterConfig:events_dir:PathPath(events)snapshots_dir:PathPath(snapshots)camera_id:strcam01line_id:strline-Aclass_names:Dict[int,str]field(default_factorydict)allow_classes:Optional[set]None# 空全开建议填缺陷类名集合conf_thres:float0.5cooldown_sec:float15.0save_snapshot:boolTruekb_hint:strclassEventWriter:def__init__(self,cfg:EventWriterConfig):self.cfgcfg self.cfg.events_dir.mkdir(parentsTrue,exist_okTrue)self.cfg.snapshots_dir.mkdir(parentsTrue,exist_okTrue)self._last_fire:Dict[Tuple[str,str],float]{}self._repeat_1min:Dict[Tuple[str,str],List[float]]{}self._seq0def_classname(self,cls_id:int)-str:returnself.cfg.class_names.get(int(cls_id),str(int(cls_id)))def_allowed(self,name:str)-bool:ifnotself.cfg.allow_classes:returnTruereturnnameinself.cfg.allow_classesdef_repeat_count(self,key:Tuple[str,str],now:float)-int:arr[tfortinself._repeat_1min.get(key,[])ifnow-t60.0]arr.append(now)self._repeat_1min[key]arrreturnlen(arr)defwrite_detections(self,boxes:Sequence[Sequence[float]],scores:Sequence[float],cls_ids:Sequence[int],frame_bgr:Optional[np.ndarray]None,)-List[Path]:返回本帧新写入的事件文件路径。written:List[Path][]nowtime.time()tsdatetime.now().strftime(%Y-%m-%dT%H:%M:%S)stampdatetime.now().strftime(%Y%m%d_%H%M%S)forbox,score,cls_idinzip(boxes,scores,cls_ids):iffloat(score)self.cfg.conf_thres:continuenameself._classname(int(cls_id))ifnotself._allowed(name):continuekey(self.cfg.camera_id,name)lastself._last_fire.get(key,0.0)ifnow-lastself.cfg.cooldown_sec:# 冷却期内仍计入 1 分钟重复次数但先不写新文件self._repeat_count(key,now)continueself._last_fire[key]now repeatself._repeat_count(key,now)self._seq1event_idf{self.cfg.camera_id}-{stamp}-{self._seq:03d}snapshot_pathifself.cfg.save_snapshotandframe_bgrisnotNone:snapself.cfg.snapshots_dir/f{self.cfg.camera_id}_{stamp}_{self._seq:03d}.jpgcv2.imwrite(str(snap),frame_bgr)snapshot_pathstr(snap)x1,y1,x2,y2[int(round(float(v)))forvinbox]event{event_id:event_id,ts:ts,camera_id:self.cfg.camera_id,line_id:self.cfg.line_id,defect:name,confidence:round(float(score),4),bbox:[x1,y1,x2,y2],repeat_count_1min:repeat,snapshot_path:snapshot_path,kb_hint:self.cfg.kb_hint,}outself.cfg.events_dir/f{event_id}.jsonout.write_text(json.dumps(event,ensure_asciiFalse,indent2)\n,encodingutf-8)written.append(out)returnwrittendefdemo_boxes():无引擎时的本地自测数据。boxesnp.array([[100,120,240,260],[300,80,400,180]],dtypenp.float32)scoresnp.array([0.91,0.32],dtypenp.float32)cls_idsnp.array([0,2],dtypenp.int32)returnboxes,scores,cls_ids这段代码保持独立不绑定某一版 TensorRT 封装只要提供boxes/scores/cls_ids就能用。6. 先用假数据把事件写入跑通保存scripts/demo_from_detections.py#!/usr/bin/env python3不依赖引擎先验证 EventWriter 是否正常写出事件。frompathlibimportPathimportsys sys.path.append(str(Path(__file__).resolve().parent))fromevent_writerimportEventWriter,EventWriterConfig,demo_boxes# noqa: E402defmain()-None:cfgEventWriterConfig(events_dirPath(events),snapshots_dirPath(snapshots),camera_idcam01,line_idline-A,class_names{0:scratch,1:dent,2:person},allow_classes{scratch,dent},# person 会被过滤conf_thres0.5,cooldown_sec5.0,save_snapshotFalse,kb_hint历史相似导轨毛刺可能导致周期性划痕,)writerEventWriter(cfg)boxes,scores,cls_idsdemo_boxes()foriinrange(3):pathswriter.write_detections(boxes,scores,cls_ids,frame_bgrNone)print(fround{i1}written{[str(p)forpinpaths]})if__name____main__:main()cd~/orin-edge-app python3 scripts/demo_from_detections.pylsevents/catevents/*.json|head预期第 1 轮写入scratchperson因白名单被滤低分目标因阈值被滤第 2、3 轮若在冷却期内不再重复写同相机同类文件确认这一点后再接到真实检测循环排障会轻松很多。7. 接到现有 YOLO / TensorRT 循环图4. 在得到 boxes 之后插入 EventWriter不必重写引擎加载。以 Orin 上目标检测最小闭环 里的流程为例你已经有preprocess → infer → postprocess → boxes/scores/cls_ids → draw只需在draw前后加上事件写入。关键不是改 TensorRT 初始化而是确认一件事引擎负责推理事件模块负责“哪些结果值得留下”。7.1 最小插入方式# 放在检测主程序同目录或把 scripts 加进 PYTHONPATHfrompathlibimportPathfromevent_writerimportEventWriter,EventWriterConfig writerEventWriter(EventWriterConfig(events_dirPath(events),snapshots_dirPath(snapshots),camera_idcam01,line_idline-A,# 按你的类别映射改若是自训缺陷模型这里写缺陷名class_names{0:scratch,1:dent},allow_classes{scratch,dent},conf_thres0.5,cooldown_sec15.0,save_snapshotTrue,))# ... 推理得到 boxes, scores, cls_ids, frame ...pathswriter.write_detections(boxes,scores,cls_ids,frame_bgrframe)forpinpaths:print(f[event]{p})7.2 视频循环里还要注意若你用的是视频或相机循环下面几条比“会不会写 JSON”更容易踩坑每帧都可能有框但不代表每帧都该写事件冷却就是为这个场景准备的。没有冷却解释队列和磁盘都会先被打满。截图保存必须限频1080p 连续存 JPEG几小时就能把小容量系统盘写满。事件可以留截图可先关或只在成功写出事件时存。类别映射一定要显式写清不要默认把cls_id当缺陷名。自训模型还好办若临时用 COCO 权重做联调更要在配置里写明“演示映射”避免后面误当成业务类别。告警阈值可以高于可视化阈值画面上0.25能看到框不代表就要写事件。事件阈值建议更严例如0.5起先保证下游干净。先统计“每分钟事件数”接大模型前先看真实运行 10 分钟会写出多少 JSON。若已经上百条先调白名单和冷却不要先开解释。7.3 和detect_trt.py的分工更稳的结构是两个文件文件职责detect_trt.py/ 相机循环读帧、推理、画框、展示event_writer.py过滤、冷却、写出事件不要把事件逻辑塞进 TensorRT 封装类深处。下次换导出方式、换后处理事件层还能原样复用。COCO 预训练权重做质检 demo 时常见做法是优先改用自训缺陷模型或临时把某个类映射成演示缺陷名但配置和日志里必须写清楚这是演示映射8. JSON 稳定后再接解释层图5. 事件接口稳了上一篇的explain_event.py才能真正进工作流。可选监听到新文件就解释先串行别一上来高并发。保存scripts/watch_and_explain.sh#!/usr/bin/env bashset-euopipefailEVENTS_DIR${1:-events}MODEL${MODEL:-qwen2.5:7b}PROMPT${PROMPT:-prompts/explain_alarm.txt}OUT_DIR${OUT_DIR:-out}mkdir-p$OUT_DIR# 需要 inotifywaitsudo apt-get install -y inotify-toolsinotifywait-m-eclose_write--format%w%f$EVENTS_DIR|whileread-rf;docase$fin*.json)base$(basename$f.json)echo[explain]$fpython3 scripts/explain_event.py\--event$f\--prompt$PROMPT\--model$MODEL\--out$OUT_DIR/${base}.txt||echo[explain failed]$f;;esacdonechmodx scripts/watch_and_explain.sh# 先确保 explain_event.py 与 prompts/explain_alarm.txt 已按上一篇就位# ./scripts/watch_and_explain.sh events没有inotify-tools时也可以简单轮询python3 -PY from pathlib import Path import time, subprocess seenset() while True: for p in sorted(Path(events).glob(*.json)): if p in seen: continue seen.add(p) outPath(out)/(p.stem.txt) print(explain, p) subprocess.run([ python3,scripts/explain_event.py, --event,str(p),--out,str(out) ], checkFalse) time.sleep(1) PY9. 常见坑9.1 每帧都写 JSON结果磁盘爆、解释队列堵、值班端重复告警过多。处理冷却 更高告警阈值。先看ls events | wc -l不要凭感觉。9.2 类别名混乱cls_id0直接当缺陷名解释层会不知所云。处理显式class_names映射并在日志里打印映射后的defect。9.3 先接大模型事件还不稳定模型会把垃圾输入组织成很像样的废话。处理先ls events cat人工看 20 条确认字段和类别都对再接解释。9.4 截图路径写了但文件不存在解释或复盘时对不上。处理检查cv2.imwrite是否成功磁盘满时先关截图只留 JSON。9.5 把 EventWriter 写死进引擎代码深处后期换 Ultralytics / TensorRT 版本会很痛。处理保持“推理后钩子”这种薄接入。9.6 多目标同一帧全部写成事件一帧里 8 个同类框可能对应同一物理缺陷的多次响应。处理同一帧内可先按类别取最高分或提高冷却不要无脑全写。9.7 事件目录与检测工作目录不一致检测在~/orin-detect跑事件写到别处解释脚本找不到。处理在配置里写绝对路径或统一到~/orin-edge-app/events。10. 验收清单检查项通过标准假数据脚本能写出至少 1 个 JSON字段齐全白名单不关心的类不会写成事件冷却短时间重复框不会狂写文件真检测接入有框且超阈值时出现新 JSON解释衔接任选一个 JSON 能跑通explain_event.py# 快速抽查最近事件ls-ltevents|headpython3 -PY import json,glob filessorted(glob.glob(events/*.json)) print(count,len(files)) if files: print(json.load(open(files[-1],encodingutf-8))) PY11. 小结把端侧 YOLO 检测结果接到大模型告警本质是补上检测与大模型之间的接口层统一字段阈值 白名单过滤冷却去重写成 JSON并可选取景再交给解释脚本先让检测结果变成可消费事件端侧大模型才接得上否则再强的模型也只是对着空气聊天。12. 相关阅读Orin 上目标检测 大模型做端侧应用Orin 上目标检测最小闭环Orin 上跑本地大模型适合什么场景本地大模型跑通了为什么还是不好用相关链接Ultralytics YOLOv8Ollama OpenAI compatibility如果这篇对你有帮助欢迎点赞、收藏也欢迎关注后续更新。

相关新闻

Claude Code CLI:提升开发效率的命令行工具详解

Claude Code CLI:提升开发效率的命令行工具详解

1. Claude Code 命令行工具概述Claude Code CLI(命令行界面)是一个功能强大的开发辅助工具,它通过简洁的命令语法为开发者提供了高效的工作流。这个工具最初是为了解决IDE环境中常见的重复性操作问题而设计的,现在已发展成为支持多…

2026/8/4 10:20:55 阅读更多 →
Java集合框架面试核心考点与深度解析

Java集合框架面试核心考点与深度解析

1. Java集合面试题全面解析作为Java开发者,集合框架是面试必考的核心知识点。我在技术面试中经常遇到候选人因为对集合理解不够深入而错失机会的情况。本文将系统梳理Java集合框架中的高频考点,结合我作为面试官的实际经验,分享那些真正能打动…

2026/8/4 10:20:55 阅读更多 →
Office自动化部署终极指南:LKY_OfficeTools一键搞定办公软件安装

Office自动化部署终极指南:LKY_OfficeTools一键搞定办公软件安装

Office自动化部署终极指南:LKY_OfficeTools一键搞定办公软件安装 【免费下载链接】LKY_OfficeTools 一键自动化 下载、安装、激活 Office 的利器。 项目地址: https://gitcode.com/GitHub_Trending/lk/LKY_OfficeTools 还在为繁琐的Office安装过程头疼吗&…

2026/8/4 10:19:55 阅读更多 →

最新新闻

短剧追更指南:个性化片单与资源管理技巧

短剧追更指南:个性化片单与资源管理技巧

1. 短剧追更指南:如何打造个性化片单最近两年,短剧市场呈现爆发式增长。根据行业数据显示,2023年国内短剧市场规模已突破百亿,平均每天上线新剧超过50部。这种每集3-15分钟的轻量级内容,正在成为年轻人碎片化时间的主要…

2026/8/4 11:08:13 阅读更多 →
如何用DouyinLiveRecorder实现40+平台24小时自动直播录制:终极指南

如何用DouyinLiveRecorder实现40+平台24小时自动直播录制:终极指南

如何用DouyinLiveRecorder实现40平台24小时自动直播录制:终极指南 【免费下载链接】DouyinLiveRecorder 可循环值守和多人录制的直播录制软件,支持抖音、TikTok、Youtube、快手、虎牙、斗鱼、B站、小红书、pandatv、sooplive、flextv、popkontv、twitcas…

2026/8/4 11:08:13 阅读更多 →
YT2786A/YT2786A5 离线式无电感交流输入(30ma) 5V3.3V双路输出线性稳压电路 典型应用电路

YT2786A/YT2786A5 离线式无电感交流输入(30ma) 5V3.3V双路输出线性稳压电路 典型应用电路

YT2786A 是一款紧凑型无电感设计的离线式线性稳压器。YT2786A 输出电压已由内部设定为 5V/3.3V/2.7V 三个版本。YT2786A 是一种简单可靠的获得偏置供电的离线式电源解决方案。 标准最简典型应用电路(市电转 5V/3.3V 给 MCU 供电) 1. 外围器件清单&#x…

2026/8/4 11:08:13 阅读更多 →
动态IP到底是什么?动态IP的使用方法

动态IP到底是什么?动态IP的使用方法

“动态IP”到底是啥? 简单说,动态IP就是会变动的IP地址。当你连接网络、拨号或切换代理时,获取的IP地址不是固定的,而是从一个IP池中动态分配来的。 你可以把它理解为:每次“上线”,你的网络身份就变了个样…

2026/8/4 11:08:13 阅读更多 →
长期时间管理系统的设计与实践:Day24-20260120编码解析

长期时间管理系统的设计与实践:Day24-20260120编码解析

1. 项目背景与核心价值这个看似简单的日期标记"Day24-20260120"背后,隐藏着一个持续记录系统的设计哲学。作为连续记录的第24天,2026年1月20日这个未来日期暗示着这是一套面向长期时间管理的解决方案。我在实际使用类似系统三年多的时间里&…

2026/8/4 11:08:13 阅读更多 →
MAA明日方舟助手:解放双手的智能游戏管家,一键完成全部日常任务

MAA明日方舟助手:解放双手的智能游戏管家,一键完成全部日常任务

MAA明日方舟助手:解放双手的智能游戏管家,一键完成全部日常任务 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项…

2026/8/4 11:07:13 阅读更多 →

日新闻

AI Agent白手起家26: 使用标准事件驱动大模型实践

AI Agent白手起家26: 使用标准事件驱动大模型实践

纲要 练习目标:掌握大模型标准事件的调用回顾 LangChain 中的核心标准事件 invokestreambatchastream_eventswith_structured_output 环境准备实战代码:多种事件调用对比 同步调用与流式输出批量处理异步事件流监听结构化输出 运行说明与预期结果总结与扩…

2026/8/4 0:00:40 阅读更多 →
dealsea是什么?跨境卖家必知的美国deal站入门指南

dealsea是什么?跨境卖家必知的美国deal站入门指南

说实话,第一次听说美国这个老牌折扣网站的跨境卖家,十个有八个会问同一个问题:这个平台到底是干嘛的?我见过一个做家居出口的朋友,他在亚马逊上月销二十万美金,却从来没用过它。我给他看了首页——一屏一屏…

2026/8/4 0:01:40 阅读更多 →
清华大学重磅EST:植物自导电闪蒸焦耳热600°C/2600°C两步法!稀土超积累植物秒级转化为CeO₂-石墨烯电催化剂!

清华大学重磅EST:植物自导电闪蒸焦耳热600°C/2600°C两步法!稀土超积累植物秒级转化为CeO₂-石墨烯电催化剂!

通讯作者:邓兵、刘建国通讯单位:清华大学DOI:https://doi.org/10.1021/acs.est.6c00603研究背景稀土元素(REEs)是清洁能源技术与电子器件不可或缺的核心原料,然而传统提取方式依赖能耗高、排放大的采矿与强…

2026/8/4 0:01:40 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/3 4:58:13 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/3 1:53:31 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/4 5:26:40 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/3 13:07:03 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/3 5:19:38 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/3 8:27:36 阅读更多 →