共计 13611 个字符,预计需要花费 35 分钟才能阅读完成。
2021-2023 是积淀的几年,经济不景气,各行各业都不太好混,所以这几年也没有太多心理花在 csdn 上为各大网友写一些技术文章,2024 年初,也算是给本人留下一点岁月的脚印吧,所以把这段时间精心钻研的货色写进去供大家交换,顺带也看看是否有机会遇到能帮忙到其余技术公司或敌人,在交换中实现双赢,有须要的敌人能够威信(幺捌零叁捌捌伍陆柒零贰,威信与电画同号),具体单干形式具体交换。
开发背景
从事安防多年,但根本都是从事音视频的编解码工作,很少解决图形图像相干算法,起因如下:
(1)图形图像相干算法如车牌辨认辨认、人脸识别等如果是本人研发,波及到高等数学等及图形图像解决等浅近的反对,开发难度较大;
(2)前 n 年根本没有开源的、繁难的不须要相熟底层算法的 AI 辨认框架,很难将生存中波及的 AI 辨认或机器学习的相干算法变成事实;
次要基于以上两点,导致 AI 相干的算法落地很难、实现很难、利用更难!
而后,基于百度 paddle 和 yolo 的开源框架呈现了,这使得 AI 辨认难度大大降落,利用门槛大大降低,然而 paddle 则是面向服务器,对硬件要求较高,部署也绝对简单,很难将广泛利用到生存中,所以通过多番调研 yolo 则是咱们最好的抉择。
抉择 yolo 有如下劣势
(1)开源且辨认效率十分高,仅需一次辨认即可实现所有对象的分类辨认。
(2)能够利用到服务器中,也能够利用到小型硬件中,本文部署的硬件就反对 windows/ubun, 反对 jetson nano、jetson orin nano 等 3 款中高低档硬件(约 5000 元、3000 元、1000 元)
(3)开源技术论坛和材料较多
(4)反对应用 python,反对跨平台部署(一套代码,多套环境部署)
在安防畛域,基于音视频的根底操作曾经基本上没有任何难度(看视频、直播、录像等),但基于音视频的 AI 利用却很难,但随着技术的成熟,这些利用也变得越来越多,联合生存理论需要的场景就有很多,例如
(1)非法闯入:夜间无人值守或重要地点进出监控
(2)摔倒检测:关爱老人,老人摔倒检测或打架斗殴跌倒检测,可用于社区、监狱、广场、学校等场合。
(3)明火辨认:严禁烟火的第三方辨认火焰,避免火宅,可用于森林、车间、化工产等场合。
(4)烟雾排放:同明火场景。
(5)越界检测:越过指定边界,产生报警,个别用于行人辨认与闯入检测,联合视频区域检测。可用于无人值守场景。
(6)睡岗检测:工作期间睡觉检测,防止安全事故产生。
(7)离岗检测:工作期间来到岗位检测,防止安全事故产生。
(8)人群聚众:检测人员汇集,防止打群架、防止踩踏事件产生。
(9)攀高检测:检测人员是否进行攀登,防止安全事故产生。
(10)打架斗殴:检测人员是否打架,可用于学校、公共场所。
(11)人脸抓拍:人脸数据抓拍,可推送给人脸识别服务进行 1 &1 辨认及陌生人辨认。
(12)遮挡检测:检测摄像机是否被人为遮挡或被损坏。协调运维人员进行保护。
(13)垃圾满溢:检测垃圾桶垃圾是否满溢,帮助环卫人员智能调度环卫车辆,节俭人力和物力。
(14)占道经营:检测是否有占用路线非法经营,帮助城管治理,加重工作量。
(15)安全帽辨认:工地安全帽辨认,进步工地平安。
(16)反光衣辨认:工地反光衣辨认,避免非工作人员闯入工地区域。
(17)电动车进电梯:检测电动车进出电梯,避免火灾产生。
(18)口罩检测:明厨亮灶,检测食品从业人员是否佩戴口罩。
(19)虫害辨认:智慧农业,通过 AI 辨认虫害,智能领导农户作业。
(20)动物辨认:公共场所,不容许动物进出场合。
(21)电梯超员检测:电梯人员是否超载工作。
(22)河边垂钓检测:严禁垂钓河边检测人员是否有钓鱼或捕鱼行为。
(23)河边游泳检测:严禁游泳河边检测人员是否有上水游泳行为。
(24)人数统计:人数统计或客流统计,通过 AI 形式统计绘制市场的客流热力求。
(25)抽烟检测:明厨亮灶,检测从业人员是否有吸烟行为。
(25)泥头车辨认:街道泥头车随便、掉土的事件。
(27)打电话辨认:检测开车是否有打电话行为。
(28)机动车 / 非机动车辨认:机动车和非机动车辨认。
(29)车流量统计:辨认车辆及统计车流量
以上是我总结的贴近生活,很有可能在生活中十分实用的场景,这些算法都是能够通过数据采集进行一一训练的。
技术实现
开发环境:pycharm
开发语言:python、vue2.0、pytorch、vision
部署环境:
(1)windows-conda、jetson-nano:conda(低配)、
(2)jetson orin nano:python、cuda、cudnn(sdk)(中高配)
(3)orange PI(正在适配中)
硬件选型:
(1)低配 jetson naco(b01 替换版本),ubuntu,价格 1312 元(含外壳),0.5tops,剖析实时视频约 4 路;一张图约 200ms~300ms 耗时;
(2)中配 jetson orin nano,ubuntu,价格 3200 元高低,20tops,剖析实时视频约 8 路;一张图约 100ms 耗时;
(3)高配 jetson orin nano,Ubuntu,价格在 5200 元高低,70-100tops,剖析实时视频约 16 路;一张图约 30ms 耗时;
(4)国产华为芯片 orange PI,4G,16 外围,价格在 1000 元左右,剖析视频预估在 16 路;(正在适配中,硬件一片难求)
产品成果
为此,我开发了一个 AI 盒子框架,这个框架能够动静增加训练好的模型、动静增加须要剖析的网络摄像机、动静为每一路摄像机增加不同的剖析场景(算法)、动静配置 AI 盒子参数、动静重启 AI 盒子等性能;
AI 盒子提供了
(1)登录 AI 盒子
AI 盒子登录页面提供用户名和明码模式登录,登录后能够批改初始密码。
为适配不同的中央需要,AI 盒子最新版本,反对中文简体版本、英文版本和中文繁体版本。
(2)零碎首页
AI 盒子次要提供设施治理、报警治理、录像治理、模型配置以及零碎设置性能。
(3)设施治理
能够动静增加须要剖析的设施,此处的设施为网络设备,AI 盒子通过设施的 rtsp 标准协议从摄像机获取视频流,而后进行抽帧剖析,抽帧距离能够动静进行配置。
能够管制设施进行 AI 抽帧的剖析时间段管制,如早上 08:00 开始剖析,到早晨 23:00 截止。
能够配置设施剖析的区域,区域反对多边形绘制(区域入侵)、绘制边界线段(周界检测)(4)场景治理
一个设施抽帧的图片,能够做不同场景的算法剖析,例如一个摄像机能够同时剖析明火烟雾检测、攀登检测,也能够剖析更多的算法(当然,算法越多,耗时就减少,不过对于在 1 - 3 秒内能实时响应就曾经是十分实用了,能够疏忽)(5)报警治理
当剖析场景检测到超过设定置信度的预警时,会存储到 AI 盒子中,AI 盒子会将报警异步推送到配置的第三方平台中,能够在 AI 盒子中保留 n 天
如果 AI 盒子关上报警录像性能,AI 盒子会主动录取事件产生的前 3 秒以及后 3 秒,总共 6 秒录像,这些录像也会被推送给第三方平台
(6)录像治理
此外 AI 盒子反对视频转发(rtmp)、手动抓拍、近程录像性能,录像后能够存储在 AI 盒子,当推送给第三方平台后会主动从本地移除
(7)模型治理
AI 盒子提供模型载入、辨认、上报等残缺框架,并不固化整个流程,所以对 AI 盒子而已,算法、设施、场景都是灵便能够配置的,反对动静的模型增加性能,咱们能够将训练好的模型动静增加到 AI 盒子中
模型能够包含所有剖析,哪些是属于失常的(不会报警的), 哪些属于异样的(显示红框,可能要报警的)
(8)系统配置
AI 盒子反对系统配置,配置我的项目包含 AI 盒子编码(推送到第三方,区别多个盒子)、报警保留天数、并发剖析数量管制、辨认后是否显示标签、是否反对报警联动录像、是否凌晨主动重启、报警第三方平台介绍地址、长连贯管制地址。
(9)GPIO 及 modbus 联动
此外,AI 盒子反对本身引脚联动或 t 通过外接 modbus 协定进行对接,以下为 AI 盒子定制的一个仓库物料支付场景:
A、人通过人脸机刷脸开门进入物料仓库(人脸机器联动门磁)
B、门禁从常开(1 状态)变为断点开门状态(0),AI 盒子检测到人员进入,开始联动摄像机进行录像;
C、人员进入仓库后支付物料,拿去实现之后将物料搁置到物料台,而后按墙壁上的拍照 IO 开关;
D、AI 盒子检测到 AI 开关后,联动摄像机视频进行物料实物抓拍,能够抓图多张;
E、人员拍照后拿取物料并来到物料仓库,门磁从开门(0)状态复原为常闭状态(0);
F、AI 盒子检测到关门信号,进行联动录像,并将从门禁到出门的录像 + 物料拍照打包存储并发送给第三方平台;
这样,一个人从进门支付物料开始录像 ==> 物料拍照 ==> 进行录像整个过程留影留像,保留了整个过程的证据。如果是非法闯入则主动通过 AI 预警进行报警录像,产生非法闯入预警,如果正常人脸刷脸进入则不会产生非法报警。
源码预览
(1)服务启动
"""=========== 导入装置的 python 库 ==========="""
import sys
from pathlib import Path
from box.box import Box
from utils.general import check_requirements
# 获取以后文件门路
FILE = Path(__file__).resolve()
# 获取以后文件父目录 -YOLOv5 根目录
ROOT = FILE.parents[0]
# 获取绝对路径
PARENT = ROOT
# 将根目录增加到零碎 path 中
if str(ROOT) not in sys.path:
sys.path.append(str(ROOT))
# 程序启动入口
if __name__ == '__main__':
# 查看申请参数
check_requirements(ROOT / 'requirements.txt', exclude=('tensorboard', 'thop'))
# 创立 AI 盒子
box = Box()
# 初始化盒子
box.init()
# 启动 AI 盒子
box.start()
# 期待盒子退出
box.join()
# 进行 AI 盒子
box.stop()
(2)websocket 协定
# 报警推送实现
class SocketService(threading.Thread):
# 构造函数
def __init__(self):
# 重写父类办法
threading.Thread.__init__(self)
# 套接口
self.ws = None
self.connected = False
self.do_run = True
# 数据接管
self.msg_thread = None
# 视频数量
self.count = 0
# 视频回调
self.video_back = None
pass
# 进行服务
def stop(self):
self.do_run = False
# 敞开套接口
if self.ws is not None:
self.ws.close()
# 期待接管退出
if self.msg_thread is not None:
if self.msg_thread.is_alive():
self.msg_thread.join()
pass
# 设置命令回调
def set_video_back(self, call):
self.video_back = call
# 响应后果
def send_result(self, url, cmdId, state, desc, data=None, file_path=None):
try:
if url is None or cmdId is None:
return
# 申请字典
dict_info = {}
# 追加文件
if file_path is not None:
# 读取文件内容
file = open(file_path, "rb")
name = os.path.basename(file_path)
dict_info['file'] = (name, file, 'application/octet-stream')
# 追加数据
if data is not None:
dict_info['data'] = data
# multipart 编码
encoder = MultipartEncoder(fields=dict_info)
# 申请头部
headers = {'Content-Type': encoder.content_type}
# 发送到第三方
result_url = (url + "?boxId=" + SystemConfig.ID + "&cmdId=" + cmdId +
"&state=" + str(state) + "&desc=" + desc)
response = requests.post(result_url, json=data, headers=headers)
if response.status_code != 200:
return False
# 解决返回后果
result = response.json()
# 解决返回后果
if result['error'] != 0:
error = result['error']
LOGGER.error(f'upload box {SystemConfig.ID} command result failed, reason: {error}')
return False
# 返回胜利后果
return True
except Exception as e:
LOGGER.error(f'upload alarm error {e}')
pass
# 报警推送
def run(self) -> None:
# 开始工夫
last_time = datetime.datetime.now()
while not Global.restart and self.do_run:
try:
# 查问通信地址
result_url = SystemConfig.ALARM_URL
if SystemConfig.ALARM_URL is not None:
if not result_url.endswith("/"):
result_url += "/"
result_url += "result"
# 零碎重启
if Global.restart:
break
# 连贯服务器
if not self.connected:
if SystemConfig.SOCKET_URL is None or SystemConfig.SOCKET_URL == '':
time.sleep(1)
continue
try:
# 连贯服务
self.ws = create_connection(SystemConfig.SOCKET_URL)
self.connected = self.ws.connected
# 连贯胜利
if self.ws.connected:
LOGGER.info(f'@connect websocket success: {SystemConfig.SOCKET_URL}')
# 连贯信息
box = {
'id': SystemConfig.ID,
'ip': Global.ip,
'port': Global.port,
'cmd': 'connect'
}
# 发送连贯
self.ws.send(json.dumps(box))
# 更新心跳工夫
last_time = datetime.datetime.now()
# 同步盒子数据
self.sync_server_data()
pass
except Exception as e2:
LOGGER.error(f'websocket connect error:{e2}')
self.connected = False
pass
# 链接失败期待
if not self.connected:
time.sleep(3)
continue
(3)系统配置
# 零碎全局配置
import uuid
from box.util import SystemUtil
# 全局配置
class Global:
# 数据库配置
dbIp = '127.0.0.1'
dbPort = 3306
dbUser = 'root'
dbPwd = 'root'
dbName = 'box3'
# web 配置
ip = '127.0.0.1'
port = 5700
# 零碎重启标记
restart = False
# 启用串口信号读取
enableIO = False
# linux- 设施名
LUX_IO_NAME = '/dev/ttyCH341USB0'
# win- 设施名
WIN_IO_NAME = 'COM13'
# 初始化
def __init__(self):
pass
# 获取本机 ip
@staticmethod
def local_ip():
try:
if Global.ip == '127.0.0.1':
Global.ip = SystemUtil.get_local_ip()
except Exception as e:
print(f'get local ip error {e}')
# 系统配置
class SystemConfig:
# 盒子以后编码
ID = str(uuid.uuid1()).replace("-", "")
# 零碎登录账号
ADMIN = 'admin'
# 零碎账号密码
PASSWORD = 'dd123456'
# 零碎并发剖析数
PATROL_NUM = 4
# 报警保留天数
SAVE_DAYS = 1
# 是否显示标签
SHOW_LABEL = 1
# 是否报警录像
ALARM_RECORD = 1
# 是否定时重启
AUTO_RESTART = 1
# 报警推送地址
ALARM_URL = ''
# 长连贯地址
SOCKET_URL = ''
(4)文件清理
import threading
import os
import time
from threading import Lock
from box.config import Global
from utils.general import LOGGER
# 文件异步清理
class FileClear(threading.Thread):
# 待清理文件列表
files = []
# 全局文件列表锁
lock = Lock()
# 构造函数
def __init__(self):
# 重写父类办法
threading.Thread.__init__(self)
pass
# 增加清理文件
@classmethod
def push(cls, file):
if file is None:
return
cls.lock.acquire()
try:
cls.files.append(file)
except Exception as e:
LOGGER.warning(f'add clear file error {e}')
finally:
cls.lock.release()
pass
# 报警推送
def run(self) -> None:
# 零碎未重启
while not Global.restart:
try:
# 零碎重启
if Global.restart:
break
# 尝试清理
try:
# 获取文件大锁
self.lock.acquire()
# 以后零碎无工作
if len(self.files) <= 0:
# 开释文件大锁
self.lock.release()
# 睡眠期待 1 秒
time.sleep(1)
continue
# 删除所有文件 - 疏忽异样
for file in self.files:
try:
os.remove(file)
except Exception as e1:
LOGGER.warning(f'{e1}')
pass
pass
# 清空数据
self.files.clear()
# 开释文件大锁
self.lock.release()
time.sleep(0.1)
except Exception as e:
# 开释文件大锁
self.lock.release()
LOGGER.warning(f'clear file error {e}')
pass
except Exception as e:
LOGGER.warning(f'clear file error: {e}')
因为性能较多,此处不在一一赘述,有须要单干的请分割我(威信: 幺捌零叁捌捌伍陆柒零贰,威信与电画同号),咱们在进一步沟通。
性能介绍
AI 盒子是基于 yolov5 框架开发的一套 AI 辨认框架,能够反对多模型、多设施、多场景(算法)辨认,反对 http 协定(同一个局域网)通信、反对 websocket 协定(不同局域网)通信,反对视频取流辨认,反对接口图片 AI 辨认、反对媒体视频转发(视频播放)等性能。
AI 盒子是独立的个体,能够 独自部署 (外接显示器,通过浏览器即可实时查看报警、实时播放报警),AI 盒子也能够 集成内部平台,通过 AI 盒子对接接口(包含 http 协定、websocket 协定),将报警及录像等信息推送至第三方平台。
具体性能介绍如下所示
(1)系统配置
能够配置 AI 盒子的根本配置,包含 AI 盒子的编码(多个盒子时对接内部应用)、录像及报警保留天数、并发 AI 剖析设施路数、AI 预警是否显示预警标签、是否 12 点主动重启(用不上,异常情况下解决)、第三方报警推送地址、第三方平台信令下发连贯地址(服务端下发指令到 AI 盒子,如模型下发、设施下发、场景下发、设施重启、系统配置等)。这些配置都能够实时配置实时失效,不须要重启。
(2)模型治理
能够通过 AI 盒子自带的 web 端治理界面治理 AI 盒子中的模型,也能够通过 AI 盒子对接协定治理 AI 盒子模型,AI 提供与模型无关的解决框架,训练的模型分类依据理论填写即可
(3)设施治理
AI 盒子次要通过 rtsp 协定(规范)剖析设施视频流(海康、大华等都能够),通过视频流帧采样的形式(采样帧频率能够动静配置)剖析对应设施的图片流,并且反对指定时间段内进行剖析(如工作工夫或下班时间进行 AI 剖析),实现设施动静治理、动静配置,除反对剖析视频流之外,当然 AI 盒子也提供了图片剖析接口(能够第三方通过接口投递图片并进行剖析)并返回后果
(4)场景治理
AI 剖析的每一个设施(视频流)都能够配置多个场景,如一个摄像机同时反对火焰辨认、安全帽辨认、摔倒检测、打架斗殴等多个场景,因为 AI 盒子是框架,摄像机配置哪些场景都是能够动静灵便配置的。
(5)录像治理
AI 具备设施近程录像动能,当 AI 盒子启动视频转发之后,能够通过 websocket 接口管制 AI 盒子进行手动录像,AI 会长期存储录像信息在本地,当服务器失常时会主动将录像信息推送给第三方平台,而后清理本地的长期录像。
AI 盒子也提供了 web 治理页面对这些录像进行治理,包含查问、录像播放、录像清理等性能
(6)协定反对
AI 盒子反对通过 Http 协定治理 AI 盒子配置、模型、设施、场景等(如 AI 的 WEB 端),也能够通过 websocket 协定下发和操作 AI 盒子,实现与 AI 和的多协定交互。
Http 协定代码案例
# 登录盒子
@app.route("/user/login", methods=["POST"])
def login():
# 获取用户信息 json 对象
user_data = request.json
# 获取 post 的 form 表单账号密码
username = user_data['username']
password = user_data['password']
# 账号密码有效
if username is None or password is None:
return jsonify({"error": -1, "description": "账号或明码有效!"})
# 账号信息校验
if username != SystemConfig.ADMIN:
return jsonify({"error": -1, "description": "用户名或明码谬误!"})
# 用户明码校验
if password != SystemConfig.PASSWORD:
return jsonify({"error": -1, "description": "用户或明码不正确!"})
# 用户明码正确
md5 = get_md5(username + ":" + password)
# map 字典转 json
return jsonify({"error": 0, "description": "success", "value": md5})
# 更新明码
@app.route("/user/setPwd", methods=["PUT"])
def set_pwd():
# 校验用户令牌
result = check_token()
if result['error'] != 0:
return jsonify({"error": result['error'], "description": result['description']})
# 获取用户信息
user_data = request.json
if user_data['oldPassword'] is None:
return jsonify({"error": -1, "description": "原明码为空"})
if user_data['newPassword'] is None:
return jsonify({"error": -1, "description": "新密码为空"})
if SystemConfig.PASSWORD != user_data['oldPassword']:
return jsonify({"error": -1, "description": "原明码不正确"})
# 更新明码
SystemConfig.PASSWORD = user_data['newPassword']
# 更新零碎用户
user_info = {"username": SystemConfig.ADMIN, "password": user_data['newPassword']}
config_mapper.update('ADMIN', json.dumps(user_info), 1)
# map 字典转 json
return jsonify({"error": 0, "description": "success"})
# 重启盒子
@app.route("/system/reboot", methods=["GET"])
def reboot():
# 进行 web 应用服务
print("reboot box...")
try:
# 获取 app 进行函数
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
# 进行 app 服务
func()
except Exception as e:
print(e)
# 设置为重启标记
Global.restart = True
# 期待 5 秒主程退出
time.sleep(5)
# posix:linux nt:windows
SystemUtil.reboot()
# 如果机器还未重启先返回胜利
return jsonify({"error": 0, "description": "success"})
websocket 协定代码
# 报警推送实现
class SocketService(threading.Thread):
# 构造函数
def __init__(self):
# 重写父类办法
threading.Thread.__init__(self)
# 套接口
self.ws = None
self.connected = False
self.do_run = True
# 数据接管
self.msg_thread = None
# 视频数量
self.count = 0
# 视频回调
self.video_back = None
pass
# 进行服务
def stop(self):
self.do_run = False
# 敞开套接口
if self.ws is not None:
self.ws.close()
# 期待接管退出
if self.msg_thread is not None:
if self.msg_thread.is_alive():
self.msg_thread.join()
pass
# 设置命令回调
def set_video_back(self, call):
self.video_back = call
# 响应后果
def send_result(self, url, cmdId, state, desc, data=None, file_path=None):
try:
if url is None or cmdId is None:
return
# 申请字典
dict_info = {}
# 追加文件
if file_path is not None:
# 读取文件内容
file = open(file_path, "rb")
name = os.path.basename(file_path)
dict_info['file'] = (name, file, 'application/octet-stream')
# 追加数据
if data is not None:
dict_info['data'] = data
# multipart 编码
encoder = MultipartEncoder(fields=dict_info)
# 申请头部
headers = {'Content-Type': encoder.content_type}
# 发送到第三方
result_url = (url + "?boxId=" + SystemConfig.ID + "&cmdId=" + cmdId +
"&state=" + str(state) + "&desc=" + desc)
response = requests.post(result_url, json=data, headers=headers)
if response.status_code != 200:
return False
# 解决返回后果
result = response.json()
# 解决返回后果
if result['error'] != 0:
error = result['error']
LOGGER.error(f'upload box {SystemConfig.ID} command result failed, reason: {error}')
return False
# 返回胜利后果
return True
except Exception as e:
LOGGER.error(f'upload alarm error {e}')
pass
(7)视频转发
AI 盒子具备视频转发性能,如 AI 盒子个别是最靠近摄像机的硬件(从服务器资源、带宽和延时、效率等多方面思考),所以 AI 盒子是能够拜访摄像机的,如果平台是云端的或者服务端与 AI 盒子或摄像机不在同一个局域网,那么这样就很有可能平台无奈播放摄像机视频(除非应用海康的平台 -ehome 协定或萤石云协定播放,或大华的主动注册协定播放),为了能通过 AI 盒子查看摄像机的视频,AI 盒子就集成了这个性能,通过 AI 盒子就能够将视频转发到 rtmp 服务器,能够应用 srs 进行部署,使得视频播放反对 rtmp、http-flv、webrtc、hls 等协定。
(8)报警预览
AI 盒子是独立的个体,咱们通过 AI 盒子的 WEB 端即可实时查看报警信息,当报警产生时候,AI 盒子即可接管到报警信息,如下所示
(9)语音播报
web 端反对 tts 预警语音播报性能,当开启报警预览时,接管到报警后,浏览器端就会播放对应的报警语音,只须要查看一个小音箱即可实现安保语音告诉性能。
(10)web 治理
AI 盒子提供以上所有性能的 web 端治理性能。
(11)GPIO 联动录像
AI 盒子能够通过硬件连贯的开释实现对 AI 盒子联动接入的摄像机进行实时录像,也能够进行抓拍,这个场景次要用于仓库物料管理系统的解决方案:
当人员通过人脸机失常刷脸进入仓库时,人脸机联动门磁开门,AI 盒子通过 APIO 信号监测门磁开启联动关联摄像机开始录像;当人员进入仓库后,支付物料,将物料搁置到物料台,按 IO 开关进行实物拍照(能够按屡次),AI 盒子通过信号监测联动关联摄像机进行抓拍,人员携带物料走出仓库,敞开门禁,AI 盒子通过检测进行关联摄像机的联动录像;
当人员通过非人脸形式非法闯入仓库时,AI 盒子通过区域入侵、人形辨认等算法进行抓拍、录像,并将报警信息实时推送给后盾管理员(第三发平台或 web 端),管理员安顿安保人员染指预警事件,保障公司财产平安;
实现场景如下所示
演示视频如下所示
[video(video-KK8JfD3o-1709279734315)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=1101073367)(image-https://img-blog.csdnimg.cn/img_convert/f243737adc106ec363f3c…)(title- 仓库领料零碎解决方案)]
第三方平台进出仓库记录以及录像信息
(12)近程录像
同 GPIO 联动录像之外,AI 盒子 也反对手动近程录像和进行录像性能,接口如下所示
(13)近程抓拍
如图上所示,AI 盒子也反对播放视频的同时进行实时抓拍。
(14)报警推送
AI 可通过接口将报警推送到第三方平台,如下所示
(15)录像推送
如上所示,推送的报警蕴含录像信息
(16)区域配置
AI 盒子能够配置检测视频范畴的某一部分区域,能够配置区域内检测,也能够配置边界检测,当检测物体跨过边界触发报警
(17)文件清理
AI 盒子会定期清理报警信息、报警录像信息、联动录像信息等;
(18)资源国际化(多语言反对)
反对简体中文、繁体中文、英文 3 中语言
(19)报警治理
AI 盒子能够治理产生的报警信息、报警录像等信息
以上是 AI 盒子具备的所有性能,因为盒子由 python+vue 框架开发,反对 ubuntu、windows,反对 CPU 和 GPU,曾经通过 jetson nano、jetson orin nx 高中低 3 种型号的适配,欢送有须要的敌人请来电沟通交流(幺捌零叁捌捌伍陆柒零贰,威信与电画同号),如果须要实物演示成果,能够提供近程连贯或实时视频查看,目前产品曾经通过 3 个版本(轮询版本、实时版本、国际化版本),十分成熟,曾经在我的项目中应用。