基於yolov5實現的AI智慧盒子框架

發表於2024-03-01

2021-2023是沉澱的幾年,經濟不景氣,各行各業都不太好混,所以這幾年也沒有太多心思花在csdn上為各大網友寫一些技術文章,2024年初,也算是給自己留下一點歲月的足跡吧,所以把這段時間精心研究的東西寫出來供大家交流,順帶也看看是否有機會遇到能幫助到其他技術公司或朋友,在交流中實現雙贏,有需要的朋友可以威信(么捌零叄捌捌伍陸柒零貳,威信與電畫同號),具體合作方式具體交流。
先給大家演示一下安全帽的使用案例(以安全帽為例)
https://www.bilibili.com/video/BV1Dm411o7PX/?aid=413672301&ci...

開發背景

從事安防多年,但基本都是從事音影片的編解碼工作,很少處理圖形影像相關演算法,原因如下:
(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個版本(輪詢版本、實時版本、國際化版本),非常成熟,已經在專案中使用。

相關文章