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 sysfrom pathlib import Pathfrom box.box import Boxfrom 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 uuidfrom 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 threadingimport osimport timefrom threading import Lockfrom box.config import Globalfrom 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个版本(轮询版本、实时版本、国际化版本),十分成熟,曾经在我的项目中应用。