简介
- 复盘工地智能盒子项目,输出项目文档,以后其他项目参考
背景
- 基于已有的技术积累,制作固定功能的产品,打造低成本的边缘检测盒子,
架构
- 按照功能分为三层
- 底层流媒体和模型的处理
- 后端数据库和业务处理
- 前端页面交互
- 我主要负责后端,数据库表设计,业务实现.
后端
- 按功能分为几个模块
- 数据库
- 共享内存方式的流媒体存取
- 检测业务判断
- HTTP RESTFUL接口通讯
- 告警推送
数据库模块
-
使用sqlite3数据库,理由是 在硬件资源有限且性能要求不高的情况下,少依赖,轻量化的数据库是最佳的选择
- 数据库表有
- 用户模块
- 算法模块
- 相机模块
- 设备模块
- 任务模块
- 用户模块
- 告警模块
- 用户模块,存储用户相关的信息,创建该表的sql语句
1
CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE, password TEXT);
- id : 用户数据的索引
- username : 用户名字
- password : 用户密码
- 算法模块,存储模型文件相关的信息,创建该表的sql语句
1
CREATE TABLE IF NOT EXISTS algorithm (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, product TEXT, vendor TEXT, detector_path TEXT, model_conf TEXT, time TEXT);
- id : 模型数据的索引
- name : 模型的名字
- product : 型号
- vendor : 厂商
- detector_path : 模型的检测器配置文件路径
- model_conf : 模型配置参数(json字符串)
- time : 时间戳字符串
- 相机模块,存储相机相关的信息,创建该表的sql语句
1
CREATE TABLE IF NOT EXISTS camera (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE, url TEXT, time TEXT, url_suffix TEXT);
- id : 相机数据的索引
- name : 相机的名字
- url : 相机的地址
- time : 相机的时间戳字符串
- url_suffix : 相机的后缀,这个字段用于存储向nvr增加相机返回的后缀,之后,程序内部所有媒体数据流使用nvr固定的内部地址拼接后缀得到的地址,这样避免了向相机多次拉流导致通道被占满,也避免了网络传输带宽的消耗.
- 任务模块,存储任务相关的信息,创建该表的sql语句
1
CREATE TABLE IF NOT EXISTS task (id INTEGER PRIMARY KEY AUTOINCREMENT, identification TEXT, name TEXT UNIQUE, start INT, model_start TEXT, model_end TEXT, model_duration TEXT, algorithm INT, camera INT, models TEXT, scheduler_type TEXT, running INT, sound_platform INT, song_address TEXT);
- id : 任务数据的索引
- identification : 任务id
- name : 任务名称
- start : 是否自启动
- model_start : 模型
- model_end :
- model_duration :
- algorithm : 算法索引
- camera : 相机索引
- models :
- scheduler_type :
- running : 是否运行
- sound_platform : 音柱平台数据索引
- song_address : 音频地址
- 告警模块,存储告警相关的信息,创建该表的sql语句
1
CREATE TABLE IF NOT EXITS warning_record (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, url TEXT, task TEXT, camera INT, remark INT, time TEXT, boxes TEXT, unix_timestamp, event_id INT, height INT, width INT);
- id : 告警数据索引
- name : 告警事件名称呢个
- url : 告警图片路径
- task : 产生告警事件的任务
- camera : 产生告警事件的相机
- remark : 是否被标记
- time : 告警事件的事件
- boxes : 检测框的结构化数据(以json形式存储)
- unix_timestamp : 事件戳
- event_id : 事件id
- height : 图片高度
- width : 图片宽度
- 平台模块,存储需要推送的平台相关的信息,创建该表的sql语句
1
CREATE TABLE IF NOT EXITS cloud_platform (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE, type TEXT, protocol TEXT, address TEXT, appKeyId TEXT, appKeySecret TEXT);
- id : 平台数据的索引
- name : 平台的名称
- type : 平台的类型.目前分为两类: 事件推送和视频点播
- protocol : 平台的协议类型.通过这个字段向不同平台不同协议推送告警数据
- address : 推送地址
- appKeyId : 账号
- appKeySecret : 密码
- 音频模块,存储需要播放的音频平台相关信息,创建该表的sql语句
1
CREATE TABLE IF NOT EXISTS sound_platform (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE, product TEXT, sn TEXT, address TEXT);
- id : 音频数据的索引
- name : 音频平台的名称
- product : 音频平台的厂商
- sn : 音频平台的序列号
- address : 音频平台的地址
共享内存方式的流媒体存取
-
流媒体的处理是在底层,底层和后端之间的流媒体是以共享内存的方式进行传输的.
-
大致流程是
- 启动后端服务时,更新底层程序的许可证
- 创建任务时,返回一个任务id,此时,会在/dev/shm/目录下产生两类文件,一类是生产者索引文件,存储着已生产的图片索引;另一类是实体图片,图片文件的命名是任务id加索引.
- 根据返回的任务,在/dev/shm/下创建消费者索引文件,存储着已经消费的图片索引
- 索引只增不减,如果消费者索引小于生产者索引,就根据索引取出对应图片,同时消费者索引加一
- 底层服务会保证生产者索引始终大于消费者索引,期间缓存的图片数量默认为五,即消费者索引和生产者索引距离最大为五
后端数据库和业务处理
- 从共享内存的方式读取图片后,图片的数据存储结构如下所示
1 2
|原图数据|缩略图数据|JSON字符串数据|原图数据的大小|缩略图数据的大小|JSON字符串数据的大小| | nbytes| nbytes | nbytes | 20bytes | 20bytes | 20bytes |
- mjpeg图片中读取原图数据和JSON字符串数据。原图数据用于播放,JSON字符串数据用于业务处理进而生成告警事件
前端页面交互
-
前端页面交互,是基于HTTP协议,第三方库用的是Mongoose。
-
视频播放。支持多任务切换播放
- 每一个HTTP链接都有一个用户自定义缓冲区,存储用户定义的数据。在请求某一任务播放视频时,服务器会收到任务的id,此时,将任务id存储到这个HTTP链接的用户自定义缓冲区
- 在服务器启动时,启动定时器任务,这个任务定义检查保存的所有HTTP链接,取出该链接中用户自定义缓冲区的数据,在类成员变量中保存的任务id容器查找是否存在,如果存在,就通过回调函数取出任务id对应的图片,发送给链接的对端。