Compare commits

...

11 Commits

  1. 2
      .idea/FristProject.iml
  2. 9
      .idea/deployment.xml
  3. 2
      .idea/misc.xml
  4. BIN
      DB_table.xlsx
  5. 22
      config.yaml
  6. 55
      core/ACLModelManager.py
  7. 197
      core/CapManager.py
  8. 673
      core/ChannelData.py
  9. 252
      core/ChannelManager.py
  10. 157
      core/DBManager.py
  11. 20
      core/DataStruct.py
  12. 552
      core/ModelManager.py
  13. 221
      core/ModelNode.py
  14. 76
      core/ModelNodeManager.py
  15. 122
      core/Upload_file.py
  16. 110
      core/WarnManager.py
  17. 6
      core/logs/2024-06-04.log
  18. 1
      core/logs/2024-06-09.log
  19. 0
      core/logs/2024-06-11.log
  20. 2
      core/logs/2024-06-18.log
  21. 257
      core/logs/2024-06-19.log
  22. 91
      core/logs/2024-06-20.log
  23. 3
      core/logs/2024-06-24.log
  24. 4
      logs/2024-05-25.log
  25. 0
      logs/2024-06-04.log
  26. 3
      logs/2024-06-05.log
  27. 0
      logs/2024-06-07.log
  28. 6
      logs/2024-06-08.log
  29. 0
      logs/2024-06-09.log
  30. 4
      logs/2024-06-10.log
  31. 5
      logs/2024-06-11.log
  32. 0
      logs/2024-06-14.log
  33. 0
      logs/2024-06-15.log
  34. 0
      logs/2024-06-17.log
  35. 458
      logs/2024-06-20.log
  36. 356
      logs/2024-06-21.log
  37. 238
      logs/2024-06-22.log
  38. 15
      logs/2024-06-23.log
  39. 190
      logs/2024-06-24.log
  40. 4
      logs/app.log
  41. 204
      model/ModelManager.py
  42. 9
      model/base_model/ascnedcl/classes.py
  43. 54
      model/base_model/ascnedcl/det_utils.py
  44. 107
      model/base_model/ascnedcl/det_utils_v10.py
  45. 9
      model/plugins/AQM_Model.py
  46. 98
      model/plugins/ModelBase.py
  47. 76
      model/plugins/Peo_ACL/Peo_Model_ACL.py
  48. BIN
      model/plugins/Peo_ACL/people.om
  49. BIN
      model/plugins/Peo_ACL/yolov5s_bs1.om
  50. 8
      model/plugins/RYRQ/RYRQ_Model.py
  51. 110
      model/plugins/RYRQ_ACL/RYRQ_Model_ACL.py
  52. 130
      model/plugins/RYRQ_Model_ACL/RYRQ_Model_ACL.py
  53. 80
      model/plugins/RYRQ_Model_ACL/coco_names.txt
  54. BIN
      model/plugins/RYRQ_Model_ACL/yolov5s_bs1.om
  55. 155
      model/plugins/yolov5-1.py
  56. 64
      model/weights/yolov5-1/yoloV5.py
  57. 300
      myutils/IPManager.py
  58. 33
      myutils/MyDeque.py
  59. 52
      myutils/MyRtspManager.py
  60. 28
      myutils/MyTraceMalloc.py
  61. 16
      myutils/mydvpp.py
  62. 70
      run.py
  63. BIN
      uploads/8.zip
  64. 2
      web/API/__init__.py
  65. 352
      web/API/channel.py
  66. 198
      web/API/model.py
  67. 22
      web/API/system.py
  68. 70
      web/API/user.py
  69. 253
      web/API/viedo.py
  70. 89
      web/API/warn.py
  71. 6
      web/__init__.py
  72. 2
      web/main/__init__.py
  73. 24
      web/main/routes.py
  74. BIN
      web/main/static/favicon.ico
  75. BIN
      web/main/static/favicon_bak.ico
  76. 7
      web/main/static/files/实时预览/data.js
  77. 1397
      web/main/static/files/实时预览/styles.css
  78. 7
      web/main/static/files/用户管理/data.js
  79. 4032
      web/main/static/files/用户管理/styles.css
  80. 7
      web/main/static/files/登录/data.js
  81. 763
      web/main/static/files/登录/styles.css
  82. 7
      web/main/static/files/算法管理/data.js
  83. 3945
      web/main/static/files/算法管理/styles.css
  84. 7
      web/main/static/files/系统管理/data.js
  85. 1604
      web/main/static/files/系统管理/styles.css
  86. 7
      web/main/static/files/通道管理/data.js
  87. 6164
      web/main/static/files/通道管理/styles.css
  88. BIN
      web/main/static/images/实时预览/u20_menu.png
  89. BIN
      web/main/static/images/实时预览/u22.png
  90. BIN
      web/main/static/images/实时预览/u26.png
  91. BIN
      web/main/static/images/实时预览/u32.png
  92. BIN
      web/main/static/images/实时预览/u48.png
  93. BIN
      web/main/static/images/实时预览/u48_selected.png
  94. BIN
      web/main/static/images/用户管理/u410.png
  95. BIN
      web/main/static/images/用户管理/u411.png
  96. BIN
      web/main/static/images/用户管理/u412.png
  97. BIN
      web/main/static/images/用户管理/u413.png
  98. BIN
      web/main/static/images/用户管理/u441.png
  99. BIN
      web/main/static/images/用户管理/u442.png
  100. BIN
      web/main/static/images/用户管理/u443.png

2
.idea/FristProject.iml

@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Remote Python 3.9.2 (sftp://root@192.168.3.48:22/usr/local/miniconda3/bin/python)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Remote Python 3.9.2 (sftp://root@192.168.3.104:22/usr/local/miniconda3/bin/python)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

9
.idea/deployment.xml

@ -1,7 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData" autoUpload="Always" serverName="root@192.168.3.48:22" remoteFilesAllowedToDisappearOnAutoupload="false">
<component name="PublishConfigData" autoUpload="Always" serverName="root@192.168.3.104:22" remoteFilesAllowedToDisappearOnAutoupload="false">
<serverData>
<paths name="root@192.168.3.104:22">
<serverdata>
<mappings>
<mapping deploy="/mnt/zfbox" local="$PROJECT_DIR$" />
</mappings>
</serverdata>
</paths>
<paths name="root@192.168.3.48:22">
<serverdata>
<mappings>

2
.idea/misc.xml

@ -3,7 +3,7 @@
<component name="Black">
<option name="sdkName" value="PyTorch" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Remote Python 3.9.2 (sftp://root@192.168.3.48:22/usr/local/miniconda3/bin/python)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Remote Python 3.9.2 (sftp://root@192.168.3.104:22/usr/local/miniconda3/bin/python)" project-jdk-type="Python SDK" />
<component name="PyCharmProfessionalAdvertiser">
<option name="shown" value="true" />
</component>

BIN
DB_table.xlsx

Binary file not shown.

22
config.yaml

@ -23,19 +23,37 @@ pw: zfkj_123!@#
MAX_CONTENT_LENGTH : 100 # 100MB
UPLOAD_FOLDER : uploads
ALLOWED_EXTENSIONS : {'zip'}
Model_Plugins: model/plugins
#RTSP
RTSP_Check_Time : 600 #10分钟 -- 2024-7-8 取消使用
#max_channel_num
max_channel_num : 8 #最大视频通道数量
encode_param : 80 #无参数默认是95
mywidth: 640
myheight: 480
#model
model_platform : acl #acl gpu cpu
device_id : 0 #单设备配置
weight_path: /model/weights
yolov5_path: D:/Project/FristProject/model/base_model/yolov5 #使用绝对路径,不同的部署环境需要修改!
cap_sleep_time: 120 #5分钟
cap_sleep_time: 120 #单位秒 -- 5分钟
buffer_len: 100 #分析后画面缓冲区帧数 -- 可以与验证帧率结合确定缓冲区大小
RESET_INTERVAL : 100000 #帧数重置上限
frame_rate : 20 #帧率参考值 -- 后续作用主要基于verify_rate进行帧率控制
verify_rate : 10 #验证帧率--- 也就是视频输出的帧率
verify_rate : 5 #验证帧率--- 也就是视频输出的帧率
warn_video_path: /mnt/zfbox/model/warn/
warn_interval: 120 #报警间隔--单位秒
video_error_count: 10 #单位秒 ---根据验 证帧率,判断10秒内都是空帧的话,视频源链接有问题。
reconnect_attempts: 5 #cap 读取帧失败几次后进行重连
#system --- 指定网卡
wired_interface : eth0
wireless_interface : WLAN
#独立模型线程相关
workType : 2 # 1--一通道一线程。2--模型独立线程
maxCount : 2 #单个进程最大通道数量

55
core/ACLModelManager.py

@ -4,7 +4,13 @@ if myCongif.get_data("model_platform") == "acl":
SUCCESS = 0 # 成功状态值
FAILED = 1 # 失败状态值
'''
#acl.rt.get_device_count() 获取可用Device数量
# 需先调用acl.rt.get_run_mode接口获取软件栈的运行模式。
#
# 当查询结果为ACL_HOST = 1,则数据传输时涉及申请Host上的内存。
# 当查询结果为ACL_DEVICE = 0 ,则数据传输时不涉及申请Host上的内存,仅需申请Device上的内存。
'''
class ACLModeManger:
def __init__(self,):
self.acl_ok = False
@ -19,7 +25,6 @@ class ACLModeManger:
ret = acl.init() # 0-成功,其它失败
if ret:
raise RuntimeError(ret)
ret = acl.rt.set_device(device_id) # 指定当前进程或线程中用于运算的Device。可以进程或线程中指定。*多设备时可以放线程*
# 在某一进程中指定Device,该进程内的多个线程可共用此Device显式创建Context(acl.rt.create_context接口)。
if ret:
@ -61,3 +66,49 @@ class ACLModeManger:
return True
@staticmethod
def pro_init_acl(device_id):
'''
独立进程初始化acl资源
:param device_id:
:return:
'''
# '''acl初始化函数'''
ret = acl.init() # 0-成功,其它失败
if ret:
raise RuntimeError(ret)
ret = acl.rt.set_device(device_id) # 指定当前进程或线程中用于运算的Device。可以进程或线程中指定。*多设备时可以放线程*
# 在某一进程中指定Device,该进程内的多个线程可共用此Device显式创建Context(acl.rt.create_context接口)。
if ret:
raise RuntimeError(ret)
print('ACL init Device Successfully')
#显示创建context
context, ret = acl.rt.create_context(device_id) # 显式创建一个Context
if ret:
raise RuntimeError(ret)
print('Init TH-Context Successfully')
return context
@staticmethod
def pro_del_acl(device_id,context):
'''
独立进程反初始化acl资源
:param device_id:
:param context:
:return:
'''
# 释放context
if context:
ret = acl.rt.destroy_context(context) # 释放 Context
if ret:
raise RuntimeError(ret)
#acl去初始化
ret = acl.rt.reset_device(device_id) # 释放Device
if ret:
raise RuntimeError(ret)
ret = acl.finalize() # 去初始化 0-成功,其它失败 --官方文档不建议放析构函数中执行
if ret:
raise RuntimeError(ret)
print('ACL finalize Successfully')
return True

197
core/CapManager.py

@ -0,0 +1,197 @@
import math
import cv2
import threading
import time
from myutils.ConfigManager import myCongif
from myutils.MyDeque import MyDeque
from myutils.MyLogger_logger import LogHandler
class CapManager:
def __init__(self):
self.logger = LogHandler().get_logger("CapManager")
self.mycap_map = {} #source,VideoCaptureWithFPS
self.lock = threading.Lock()
def __del__(self):
pass
def start_get_video(self,source,type=1):
vcf = None
with self.lock:
if source in self.mycap_map:
vcf = self.mycap_map[source]
vcf.addcount()
else:
vcf = VideoCaptureWithFPS(source,type)
self.mycap_map[source] = vcf
return vcf
def stop_get_video(self,source):
with self.lock:
if source in self.mycap_map:
vcf = self.mycap_map[source]
vcf.delcount()
if vcf.icount == 0:
del self.mycap_map[source]
else:
self.logger.error("数据存在问题!")
mCap = CapManager()
class VideoCaptureWithFPS:
'''视频捕获的封装类,是一个通道一个
打开摄像头 0--USB摄像头1-RTSP,2-海康SDK
'''
def __init__(self, source,type=1):
self.source = self.ensure_udp_transport(source)
self.width = None
self.height = None
self.bok = False
self.icount = 1 #引用次数
# GStreamer --- 内存占用太高,且工作环境的部署也不简单
# self.pipeline = (
# "rtspsrc location=rtsp://192.168.3.102/live1 protocols=udp latency=100 ! "
# "rtph264depay !"
# " h264parse !"
# " avdec_h264 !"
# " videoconvert !"
# " appsink"
# )
#self.cap = cv2.VideoCapture(self.pipeline, cv2.CAP_GSTREAMER)
# opencv -- 后端默认使用的就是FFmpeg -- 不支持UDP
self.running = True
#self.frame_queue = queue.Queue(maxsize=1)
self.frame_queue = MyDeque(5)
self.frame = None
self.read_lock = threading.Lock()
self.thread = threading.Thread(target=self.update)
self.thread.start()
def addcount(self):
self.icount += 1
def delcount(self):
self.icount -= 1
if self.icount ==0: #结束线程
self.release()
def openViedo_opencv(self,source):
self.cap = cv2.VideoCapture(source,cv2.CAP_FFMPEG)
# self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 3)
if self.cap.isOpened(): # 若没有打开成功,在读取画面的时候,已有判断和处理 -- 这里也要检查下内存的释放情况
self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# self.fps = fps # 线程保持最大帧率的刷新画面---过高的帧率会影响CPU性能,但过地的帧率会造成帧积压
self.fps = math.ceil(
self.cap.get(cv2.CAP_PROP_FPS) / float(myCongif.get_data("verify_rate"))) - 1 # 向上取整。
#print(self.width, self.height, self.fps)
else:
raise ValueError("无法打开视频源")
def ensure_udp_transport(self,source): #使用udp拉流时使用
# 检查 source 是否已经包含 '?transport=udp'
# if not source.endswith("?transport=udp"):
# # 如果没有,则添加 '?transport=udp'
# if "?" in source:
# # 如果已有其他查询参数,用 '&' 拼接
# source += "&transport=udp"
# else:
# # 否则直接添加 '?transport=udp'
# source += "?transport=udp"
return source
def update(self):
sleep_time = myCongif.get_data("cap_sleep_time")
reconnect_attempts = myCongif.get_data("reconnect_attempts")
frame_interval = 1 / (myCongif.get_data("verify_rate")+1)
last_frame_time = time.time()
while self.running:
try:
# ffmpeg_process = subprocess.Popen(
# ['ffmpeg', '-i', self.source, '-f', 'image2pipe', '-pix_fmt', 'bgr24', '-vcodec', 'rawvideo', '-'],
# stdout=subprocess.PIPE, stderr=subprocess.PIPE
# )
#读取帧后,对帧数据进行处理
# frame = np.frombuffer(raw_frame, np.uint8).reshape((480, 640, 3))
# frame = np.copy(frame) # 创建一个可写的副本
self.openViedo_opencv(self.source)
if not self.cap.isOpened():
raise RuntimeError("视频源打开失败")
failure_count = 0
self.bok = True
while self.running:
#subprocess-udp 拉流
#raw_frame = ffmpeg_process.stdout.read(640 * 480 * 3)
if self.cap.grab():
current_time = time.time()
if current_time - last_frame_time > frame_interval:
last_frame_time = current_time
ret, frame = self.cap.retrieve()
if ret:
# resized_frame = cv2.resize(frame, (int(self.width / 2), int(self.height / 2)))
#self.frame_queue.myappend(frame)
with self.read_lock:
self.frame = frame
failure_count = 0 # 重置计数
else:
failure_count += 1
time.sleep(0.1) # 休眠一段时间后重试
if failure_count >= reconnect_attempts:
with self.read_lock:
self.frame = None
raise RuntimeError("无法读取视频帧")
continue
#正常结束,关闭进程,释放资源
#ffmpeg_process.terminate()
self.cap.release()
self.bok = False
except Exception as e:
print(f"发生异常:{e}")
#ffmpeg_process.terminate()
self.cap.release()
self.bok = False
print(f"{self.source}视频流,将于{sleep_time}秒后重连!")
# 分段休眠,检测 self.running
total_sleep = 0
while total_sleep < sleep_time:
if not self.running:
return
time.sleep(2)
total_sleep += 2
def read(self):
with self.read_lock:
frame = self.frame.copy() if self.frame is not None else None
if frame is not None:
return True, frame
else:
return False, None
# if not self.frame_queue.empty():
# try:
# frame = self.frame_queue.get(timeout=0.05)
# except queue.Empty:
# #print("cap-frame None")
# return False, None
# else:
# #print("cap-frame None")
# return False, None
# ret = False
# frame = None
# if self.bok: #连接状态再读取
# frame = self.frame_queue.mypopleft()
# if frame is not None:
# ret = True
# else:
# print("____读取cap帧为空,采集速度过慢___")
# return ret, frame
def release(self):
self.running = False
self.thread.join()
self.cap.release()

673
core/ChannelData.py

@ -0,0 +1,673 @@
import time
import copy
import importlib.util
import datetime
import time
import threading
import cv2
import ffmpeg
import subprocess
import select
import multiprocessing
from collections import deque
from myutils.MyLogger_logger import LogHandler
from core.CapManager import mCap
from core.ACLModelManager import ACLModeManger
from model.plugins.ModelBase import ModelBase
from core.WarnManager import WarnData
from core.DataStruct import ModelinData,ModeloutData
from myutils.MyDeque import MyDeque
from myutils.ConfigManager import myCongif
from myutils.mydvpp import bgr_to_yuv420
class ChannelData:
def __init__(self,channel_id,deque_length,icount_max,warnM):
self.logger = LogHandler().get_logger("ChannelDat")
self.model_platform = myCongif.get_data("model_platform")
self.channel_id = channel_id #该通道的通道ID
self.warnM = warnM #报警线程管理对象--MQ
self.ffprocess = self.start_h264_encoder(myCongif.get_data("mywidth"),myCongif.get_data("myheight"))#基于frame进行编码
#视频采集相关
self.cap = None #该通道视频采集对象 还是vcf对象
self.source = None #rtsp 路径
self.frame_rate = myCongif.get_data("frame_rate")
self.frame_interval = 1.0 / int(myCongif.get_data("verify_rate"))
#模型采集相关
self.model = None #模型对象 -- 一通道只关联一个模型
self.work_th = None #该通道工作线程句柄
self.b_model = False #是否有运行模型线程
self.bool_run = True # 线程运行标识
self.lock = threading.RLock() # 用于保证线程安全
self.icount_max = icount_max # 帧序列号上限
self.max_len = myCongif.get_data("buffer_len")
self.deque_frame = deque(maxlen=self.max_len) #视频缓冲区用于保存录像
self.last_frame = None # 保存图片数据
#self.frame_queue = queue.Queue(maxsize=1)
self.frame_queue = MyDeque(15) #分析画面MQ
self.counter = 0 #帧序列号--保存报警录像使用
#model独立线程相关
self.per_th = None #预处理线程句柄
self.per_status= False #预处理线程状态
self.post_th = None #后处理线程句柄
self.post_status = False #后处理线程状态
self.model_nM = None # 模型管理对象
self.model_node= None #模型对象 -- inmq,outmq
self.out_mq = MyDeque(20) #分析结果存放MQ
#设置JPEG压缩基本
self.encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), myCongif.get_data("encode_param")] #压缩质量(0到100)
#添加一帧图片
def add_deque(self, value):
if len(self.deque_frame) == self.max_len:
removed_frame = self.deque_frame.popleft()
del removed_frame
removed_frame = None
self.deque_frame.append(value) #deque 满了以后会把前面的数据移除
#拷贝一份数据
def copy_deque(self):
return copy.deepcopy(self.deque_frame)
#获取最后一帧图片
def get_last_frame(self):
if self.b_model:
# with self.lock:
# frame = self.last_frame
# return frame
frame = self.frame_queue.mypopleft()
return frame
else: #如果没有运行,直接从cap获取画面
if self.cap:
ret, frame = self.cap.read() # 除了第一帧,其它应该都是有画面的
if not ret:
self.logger.debug(f"{self.channel_id}--web--获取原画失败,队列空")
return None
ret,buffer_bgr_webp = self._encode_frame(frame)
return buffer_bgr_webp
return None
def update_last_frame(self,buffer):
if buffer:
#print(f"{time.time()}--{self.channel_id}--数据入frame_queue队列\r")
self.frame_queue.myappend(buffer)
# with self.lock:
# self.last_frame = None
# self.last_frame = buffer
#------------h264编码相关---------------
def start_h264_encoder(self,width, height): #宽高一样,初步定全进程一个 libx264 h264_ascend
process = subprocess.Popen(
['ffmpeg',
'-f', 'rawvideo',
'-pix_fmt', 'yuv420p',
'-s', f'{width}x{height}',
'-i', '-', # Take input from stdin
'-an', # No audio
'-vcodec', 'libx264',
'-f', 'flv',
'-'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
return process
def close_h264_encoder(self):
self.ffprocess.stdin.close()
self.ffprocess.wait()
def encode_frame_h264_bak(self,frame):
try:
process = (
ffmpeg
.input('pipe:', format='rawvideo', pix_fmt='bgr24', s=f'{frame.shape[1]}x{frame.shape[0]}')
.output('pipe:', format='flv',vcodec='h264_ascend')
.run_async(pipe_stdin=True, pipe_stdout=True, pipe_stderr=True)
)
out, err = process.communicate(input=frame.tobytes())
if process.returncode != 0:
raise RuntimeError(f"FFmpeg encoding failed: {err.decode('utf-8')}")
return out
except Exception as e:
print(f"Error during frame encoding: {e}")
return None
def encode_frame_h264(self, frame,timeout=1):
yuv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_I420)
if self.ffprocess.poll() is not None:
raise RuntimeError("FFmpeg process has exited unexpectedly.")
# Write frame to stdin of the FFmpeg process
try:
self.ffprocess.stdin.write(yuv_frame.tobytes())
self.ffprocess.stdin.flush()
# Capture the encoded output
buffer_size = 1024 * 1 # Adjust this based on the size of the encoded frame
encoded_frame = bytearray()
start_time = time.time()
while True:
# Use select to handle non-blocking reads from both stdout and stderr
#ready_to_read, _, _ = select.select([self.ffprocess.stdout, self.ffprocess.stderr], [], [], timeout)
ready_to_read, _, _ = select.select([self.ffprocess.stdout.fileno(), self.ffprocess.stderr.fileno()],
[], [], timeout)
# Check if there's data in stdout (encoded frame)
if self.ffprocess.stdout.fileno() in ready_to_read:
chunk = self.ffprocess.stdout.read(buffer_size)
if chunk:
encoded_frame.extend(chunk)
else:
break # No more data to read from stdout
# Check if there's an error in stderr
if self.ffprocess.stderr.fileno() in ready_to_read:
error = self.ffprocess.stderr.read(buffer_size).decode('utf-8')
raise RuntimeError(f"FFmpeg error: {error}")
# Timeout handling to avoid infinite blocking
if time.time() - start_time > timeout:
raise RuntimeError("FFmpeg encoding timed out.")
if not encoded_frame:
raise RuntimeError("No encoded data received from FFmpeg.")
# Optional: Check for errors in stderr
# stderr_output = self.process.stderr.read()
# if "error" in stderr_output.lower():
# raise RuntimeError(f"FFmpeg error: {stderr_output}")
return bytes(encoded_frame)
except Exception as e:
print(f"Error during frame encoding: {e}")
return None
def _frame_pre_work(self, frame):
'''
对采集到的图片数据进行预处理需要确保是在原图上进行的修改
:param frame:
:return:
'''
# ----------添加时间戳-------------
# 获取当前时间
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 设置字体和位置
font = cv2.FONT_HERSHEY_SIMPLEX
position = (10, 30) # 时间戳在左上角
font_scale = 1
color = (255, 255, 255) # 白色
thickness = 2
# 在帧上绘制时间戳
cv2.putText(frame, current_time, position, font, font_scale, color, thickness, cv2.LINE_AA)
return frame
def _encode_frame(self,frame,itype=0):
ret = False
buffer_bgr_webp = None
if frame is not None:
if itype == 0: #jpg
self._frame_pre_work(frame) #对图片添加一些信息,目前是添加时间戳(model是入队列的时间,cap是发送前取帧的时间)
ret, frame_bgr_webp = cv2.imencode('.jpg', frame, self.encode_param)
if ret:
buffer_bgr_webp = frame_bgr_webp.tobytes()
elif itype == 1: #H264
try:
buffer_bgr_webp = self.encode_frame_h264(frame)
ret = True
except Exception as e:
print(e)
else:
print("错误的参数!!")
return ret,buffer_bgr_webp
#帧序列号自增 一个线程中处理,不用加锁
def increment_counter(self):
self.counter += 1
if self.counter > self.icount_max:
self.counter = 0
def get_counter(self):
return self.counter
def _start_cap_th(self,source,type=1):
'''开始cap采集线程
type = 打开摄像头 0--USB摄像头1-RTSP,2-海康SDK
'''
ret = False
if self.cap:
mCap.stop_get_video(self.source)
self.cap = None
self.cap = mCap.start_get_video(source,type)
self.source = source
if self.cap:
ret = True
return ret
def _stop_cap_th(self):
'''停止cap采集线程
重要约束停止cap线程前必须先停止model线程
'''
if self.b_model:
self.logger.error("停止采集线程前,请先停止model线程")
return False
else:
if self.cap:
mCap.stop_get_video(self.source)
self.cap = None
return True #一般不会没有cap
def _pre_work_th(self,schedule):
'''一个通道一个线程,关联的模型在一个线程检测,局部变量都是一个通道独有'''
if not self.cap:
self.logger.error("采集线程未正常启动,不进行工作")
return
while self.model_node.m_p_status.value == 0: #避免模型没启动成功,模型线程在运行
time.sleep(1)
if self.model_node.m_p_status.value == 1:
# 开始循环处理业务
last_frame_time = time.time() # 初始化个读帧时间
self.per_status = True
self.b_model = True
while self.bool_run: # 基于tag 作为运行标识。 线程里只是读,住线程更新,最多晚一轮,应该不用线程锁。需验证
# 帧率控制帧率
current_time = time.time()
elapsed_time = current_time - last_frame_time
if elapsed_time < self.frame_interval:
time.sleep(self.frame_interval - elapsed_time) # 若小于间隔时间则休眠
last_frame_time = time.time()
# *********取画面*************
ret, frame = self.cap.read() # 除了第一帧,其它应该都是有画面的
if not ret:
self.logger.debug(f"{self.channel_id}--model--获取cap画面失败,队列空")
continue # 没读到画面继续
# 验证检测计划,是否在布防时间内
now = datetime.datetime.now() # 获取当前日期和时间
weekday = now.weekday() # 获取星期几,星期一是0,星期天是6
hour = now.hour
if schedule[weekday][hour] == 1:
#图片预处理
img,scale_ratio, pad_size = self.model_node.model.prework(frame)
indata = ModelinData(self.channel_id,img,frame,scale_ratio, pad_size)
self.model_node.pro_add_data(indata) #数据入队列
else:# 不在计划则不进行验证,直接返回图片 --存在问题是:result 漏数据
ret, frame_bgr_webp = cv2.imencode('.jpg', frame,self.encode_param)
if not ret:
buffer_bgr_webp = None
else:
buffer_bgr_webp = frame_bgr_webp.tobytes()
self.update_last_frame(buffer_bgr_webp)
else:
self.logger.error("模型线程为启动成功,不进行工作")
return
self.b_model = False
self.per_status = False
def _post_work_th(self,duration_time,proportion,verify_rate,warn_interval,model_name,check_area,polygon,conf_threshold,iou_thres):
# 初始化业务数据
result = [0 for _ in range(duration_time * verify_rate)] # 初始化时间*验证帧率数量的结果list
warn_last_time = time.time()
tmpcount = 0
while self.bool_run:
out_data = self.out_mq.mypopleft() #(image,scale_ratio, pad_size,outputs):
if not out_data:
tmpcount += 1
if tmpcount == 10:
print(f"{time.time()}--{self.channel_id}--model-outmq 连续10次没有数据\r")
time.sleep(1)
continue
tmpcount = 0
#开始后处理
bwarn, warn_text = self.model_node.model.postwork(out_data.image,out_data.outputs,out_data.scale_ratio,out_data.pad_size,
check_area,polygon,conf_threshold,iou_thres)
# 对识别结果要部要进行处理
if bwarn:
# 绘制报警文本
cv2.putText(out_data.image, warn_text, (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
result.append(1) # 要验证数组修改,是地址修改吗?
else: # 没有产生报警也需要记录,统一计算占比
result.append(0)
#分析画面保存
# ret, frame_bgr_webp = cv2.imencode('.jpg', out_data.image,self.encode_param)
# buffer_bgr_webp = None
# if ret:
# buffer_bgr_webp = frame_bgr_webp.tobytes()
ret, buffer_bgr_webp = self._encode_frame(out_data.image)
# 分析图片放入缓冲区内存中
self.add_deque(out_data.image) # 缓冲区大小由maxlen控制 超上限后,删除最前的数据
# 分析画面一直更新最新帧,提供网页端显示
self.update_last_frame(buffer_bgr_webp)
if bwarn:
# 验证result -是否触发报警要求 --遍历每个模型执行的result
count_one = float(sum(result)) # 1,0 把1累加的和就是1的数量
ratio_of_ones = count_one / len(result)
# self.logger.debug(result)
if ratio_of_ones >= proportion: # 触发报警
# 基于时间间隔判断
current_time = time.time()
elapsed_time = current_time - warn_last_time
if elapsed_time < warn_interval:
continue
warn_last_time = current_time
# 处理报警
warn_data = WarnData()
warn_data.model_name = model_name
warn_data.warn_text = warn_text
warn_data.img_buffer = self.copy_deque() # 深度复制缓冲区
warn_data.width = self.cap.width
warn_data.height = self.cap.height
warn_data.channel_id = self.channel_id
self.warnM.add_warn_data(warn_data)
# 结果记录要清空
for i in range(len(result)):
result[i] = 0
def _verify(self,frame,model,model_data,schedule,result,isdraw=1):
'''验证执行主函数,实现遍历通道关联的模型,调用对应模型执行验证'''
#img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = frame
#验证检测计划,是否在布防时间内
now = datetime.datetime.now() # 获取当前日期和时间
weekday = now.weekday() # 获取星期几,星期一是0,星期天是6
hour = now.hour
result.pop(0) # 保障结果数组定长 --先把最早的结果推出数组
warntext = ""
if model and schedule[weekday][hour] == 1: #不在计划则不进行验证,直接返回图片
# 调用模型,进行检测,model是动态加载的,具体的判断标准由模型内执行 ---- *********
# bwarn = False
# warntext = ""
# time.sleep(2)
bwarn, warntext = model.verify(img, model_data,isdraw) #****************重要
# 对识别结果要部要进行处理
if bwarn:
# 绘制报警文本
cv2.putText(img, warntext, (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
result.append(1) #要验证数组修改,是地址修改吗?
else: #没有产生报警也需要记录,统一计算占比
warntext = ""
result.append(0)
else:
result.append(0)
# 将检测结果图像转换为帧--暂时用不到AVFrame--2024-7-5
# new_frame_rgb_avframe = av.VideoFrame.from_ndarray(img, format="rgb24") # AVFrame
# new_frame_rgb_avframe.pts = None # 添加此行确保有pts属性
# if isinstance(img, np.ndarray): -- 留个纪念
#处理完的图片后返回-bgr模式
#img_bgr_ndarray = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
ret,buffer_bgr_webp = self._encode_frame(img)
#buffer_bgr_webp = self.encode_frame_to_flv(img)
return buffer_bgr_webp,img,warntext
def _dowork_thread(self,channel_id,model_data,schedule,verify_rate,warn_interval):
'''一个通道一个线程,关联的模型在一个线程检测,局部变量都是一个通道独有'''
if not self.cap:
self.logger.error("采集线程未正常启动,退出model线程")
return
#加载自定义模型文件
model = self._import_model(str(channel_id), model_data[5], model_data[8], model_data[9]) # 动态加载模型处理文件py
if not model:
self.logger.error("自定义模型文件加载失败,退出model线程")
return
#初始化模型运行资源
context = None
device_id = myCongif.get_data("device_id")
if self.model_platform == "acl": # ACL线程中初始化内容
context = ACLModeManger.th_inti_acl(device_id) #创建context
#初始化模型资源 -- 加载模型文件
ret = model.init_acl_resource() #加载和初始化离线模型文件--om文件
if not ret:
print("初始化模型资源出错,退出线程!")
return
#初始化业务数据
result = [0 for _ in range(model_data[3] * verify_rate)] # 初始化时间*验证帧率数量的结果list
proportion = model_data[4] # 判断是否报警的占比
warn_last_time = time.time()
#warn_save_count = 0 #保存录像的最新帧初始化为0
#开始循环处理业务
last_frame_time = time.time() #初始化个读帧时间
self.b_model = True
while self.bool_run: #基于tag 作为运行标识。 线程里只是读,住线程更新,最多晚一轮,应该不用线程锁。需验证
# 帧率控制帧率
current_time = time.time()
elapsed_time = current_time - last_frame_time
if elapsed_time < self.frame_interval:
time.sleep(self.frame_interval - elapsed_time) #若小于间隔时间则休眠
last_frame_time = time.time()
#*********取画面*************
ret,frame = self.cap.read() #除了第一帧,其它应该都是有画面的
if not ret:
#self.logger.debug(f"{self.channel_id}--model--获取cap画面失败,队列空")
continue #没读到画面继续
#执行图片推理
buffer_bgr_webp,img_bgr_ndarray,warn_text = self._verify(frame,model,model_data,schedule,result)
#分析图片放入内存中
self.add_deque(img_bgr_ndarray) # 缓冲区大小由maxlen控制 超上限后,删除最前的数据
# 分析画面一直更新最新帧,提供网页端显示
self.update_last_frame(buffer_bgr_webp)
if warn_text:
#验证result -是否触发报警要求 --遍历每个模型执行的result
count_one = float(sum(result)) #1,0 把1累加的和就是1的数量
ratio_of_ones = count_one / len(result)
#self.logger.debug(result)
if ratio_of_ones >= proportion: #触发报警
# 基于时间间隔判断
current_time = time.time()
elapsed_time = current_time - warn_last_time
if elapsed_time < warn_interval:
continue
warn_last_time = current_time
# 处理报警
warn_data = WarnData()
warn_data.model_name = model_data[7]
warn_data.warn_text = warn_text
warn_data.img_buffer = self.copy_deque() # 深度复制缓冲区
warn_data.width = self.cap.width
warn_data.height = self.cap.height
warn_data.channel_id = channel_id
self.warnM.add_warn_data(warn_data)
#结果记录要清空
for i in range(len(result)):
result[i] = 0
# end_time = time.time() # 结束时间
# print(f"Processing time: {end_time - start_time} seconds")
# 本地显示---测试使用
# if channel_id == 2:
# cv2.imshow(str(channel_id), img)
# if cv2.waitKey(1) & 0xFF == ord('q'):
# break
#结束线程
print("开始结束工作线程")
self.b_model = False
#反初始化
if self.model_platform == "acl":
try:
model.release() #释放模型资源资源
# 删除模型对象
del model
#释放context
if context: # ACL线程中反初始化内容 -- 若线程异常退出,这些资源就不能正常释放了
# 再释放context
ACLModeManger.th_del_acl(context)
except Exception as e:
print(e)
#cv2.destroyAllWindows()
print("线程结束!!!!")
#2024-9-9 新增兼容独立model线程 根据self.model_node判断,None:1通道1线程,not None:独立线程
#2024-10-14 model调整为独立子进程执行
def _start_model_th(self,model_data,schedule,type=1):
verify_rate = myCongif.get_data("verify_rate")
warn_interval = myCongif.get_data("warn_interval")
self.bool_run = True
if self.model_nM:#要起个预处理线程,和一个后处理线程
#启动后处理线程
self.post_th = threading.Thread(target=self._post_work_th,
args=(model_data[3],model_data[4],verify_rate,warn_interval,model_data[7],
model_data[1],model_data[2],model_data[8],model_data[9]))
self.post_th.start()
# 启动模型线程,若线程已启动,则+1
self.model_nM.start_model_th(self.channel_id,self.out_mq)
self.model_node = self.model_nM.getModle_Nodel(self.channel_id)
if not self.model_node:
self.logger.error("model_node 不应该为空!!")
self.bool_run = False
return
#启动预处理线程
self.per_th = threading.Thread(target=self._pre_work_th,args=(schedule,))
self.per_th.start()
else:
self.work_th = threading.Thread(target=self._dowork_thread,
args=(self.channel_id, model_data, schedule, verify_rate,
warn_interval)) # 一个视频通道一个线程
self.work_th.start()
def _stop_model_th(self):
if self.model_nM: #独立线程,需要停止预处理线程,和后处理线程
self.bool_run = False
#停止预处理线程
if self.per_th:
self.per_th.join()
self.per_th = None
#停止model线程 -1
self.model_nM.stop_model_th(self.channel_id)
#停止后处理线程
if self.post_th:
self.post_th.join()
self.post_th = None
#清空MQ
self.out_mq.myclear()#清空后处理mq中未处理的数据
else:
if self.work_th:
if self.b_model:
self.bool_run = False
self.work_th.join() #线程结束时,会把b_model置False
self.logger.debug(f"{self.channel_id}停止工作线程")
self.work_th = None
def _import_model(self,model_name,model_path,threshold,iou_thres):
'''
根据路径动态导入模块
:param model_name: 模块名称 --用通道ID代替
:param model_path: 模块路径
:param threshold: 置信阈值
:param iou_thres: iou阈值
:return:
'''
try:
module_path = model_path.replace("/", ".").rsplit(".", 1)[0]
print(module_path)
# 动态导入模块
module = importlib.import_module(module_path)
# 从模块中获取指定的类
Model = getattr(module, "Model")
# 使用 Model 类
model_instance = Model(model_path,threshold,iou_thres)
return model_instance
except ModuleNotFoundError as e:
print(f"Module not found: {e}")
return None
except AttributeError as e:
print(f"Class not found in module: {e}")
return None
except Exception as e:
print(f"An unexpected error occurred: {e}")
return None
# if os.path.exists(model_path):
# module_spec = importlib.util.spec_from_file_location(model_name, model_path)
# if module_spec is None:
# self.logger.error(f"{model_path} 加载错误")
# return None
# module = importlib.util.module_from_spec(module_spec)
# start_time = time.time()
# print(f"通道{self.channel_id},开始exec_module自定义模型文件")
# module_spec.loader.exec_module(module)
# end_time = time.time()
# print(f"通道{self.channel_id},完成exec_module模型文件实例化耗时{end_time - start_time}")
#
# try:
# md = getattr(module, "Model")(model_path,threshold,iou_thres) #实例化类
# except Exception as e:
# self.logger.error(f"{model_path} 实例化错误,退出模型线程")
# return None
#
# if not isinstance(md, ModelBase):
# self.logger.error("{} not zf_model".format(md))
# return None
# else:
# self.logger.error("{}文件不存在".format(model_path))
# return None
# self.logger.debug(f"{model_path} 加载成功!!!!")
# return md
def start_work(self,cap_data,model_data,schedule,type,model_NodeM=None):
'''
开始工作线程包括视频通道采集和模型处理
:param cap_data: [source,type]
:param model_data: 跟通道关联的模型数据
strsql = (
f"select t1.model_id,t1.check_area,t1.polygon ,t2.duration_time,t2.proportion,t2.model_path,t1.ID,"
f"t2.model_name,t1.conf_thres,t1.iou_thres "
f"from channel2model t1 left join model t2 on t1.model_id = t2.ID where t1.channel_id ={channel_id};")
:param schedule
:param type: 0-启动所有线程1-只启动cap采集线程2-只启动model模型处理线程
:return: True,False
'''
ret = False
self.model_nM = model_NodeM
if type==0:
self._start_cap_th(cap_data[0],cap_data[1]) #先cap,再model
self._start_model_th(model_data,schedule)
ret = True
elif type == 1:
self._start_cap_th(cap_data[0],cap_data[1])
ret = True
elif type == 2:
self._start_model_th(model_data,schedule)
ret = True
else:
self.logger.error("暂时还不支持该类型工作!")
return ret
def stop_work(self,type=0):
'''
清空数据停止工作线程若有 并删除deque last_frame
:param type: 0-停止所有线程1-只停止cap采集线程2-只停止model模型处理线程
:return: True,False
'''
ret = False
if type == 0:
self._stop_model_th()
self._stop_cap_th()
ret = True
elif type == 1:
self._stop_cap_th()
ret = True
elif type == 2:
self.logger.debug("单独停止工作线程")
self._stop_model_th()
ret = True
else:
self.logger.error("暂时还不支持该类型工作!")
return ret

252
core/ChannelManager.py

@ -1,120 +1,156 @@
import cv2
import threading
from collections import deque
import numpy as np
import time
import copy
import queue
class ChannelData:
def __init__(self, str_url, int_type, bool_run, deque_length,icount_max):
self.str_url = str_url #视频源地址
self.int_type = int_type #视频源类型,0-usb,1-rtsp,2-hksdk
self.bool_run = bool_run #线程运行标识
self.deque_frame = deque(maxlen=deque_length)
self.last_frame = None # 保存图片数据
self.frame_queue = queue.Queue(maxsize=1)
self.counter = 0 #帧序列号--保存报警录像使用
self.icount_max = icount_max #帧序列号上限
self.lock = threading.RLock() # 用于保证线程安全
#添加一帧图片
def add_deque(self, value):
self.deque_frame.append(value) #deque 满了以后会把前面的数据移除
#拷贝一份数据
def copy_deque(self):
return copy.deepcopy(self.deque_frame)
#获取最后一帧图片
def get_last_frame(self):
with self.lock:
frame = self.last_frame
return frame
# if not self.frame_queue.empty():
# return self.frame_queue.get()
# else:
# return None
def update_last_frame(self,buffer):
if buffer:
with self.lock:
self.last_frame = None
self.last_frame = buffer
# if not self.frame_queue.full():
# self.frame_queue.put(buffer)
# else:
# self.frame_queue.get() # 丢弃最旧的帧
# self.frame_queue.put(buffer)
#帧序列号自增 一个线程中处理,不用加锁
def increment_counter(self):
self.counter += 1
if self.counter > self.icount_max:
self.counter = 0
def get_counter(self):
return self.counter
#清空数据,主要是删除deque 和 last_frame
def clear(self):
with self.lock:
self.bool_run = False
time.sleep(1) #休眠一秒,等待通道对应的子线程,停止工作。
self.deque_frame.clear()
self.last_frame = None
def stop_run(self):
self.bool_run = False
import base64
from myutils.ConfigManager import myCongif
from myutils.MyLogger_logger import LogHandler
#独立模型线程
from core.ModelNodeManager import ModelNodeManger
#from core.ModelNode import ModelNode
from core.ChannelData import ChannelData #其实ChannelNode会更加贴切一些
'''
通道对象管理类只针对通道节点的维护和工作线程的开启和停止 ChannelData的操作必须维护在ChannelManager里面不能输出ChannelData对象
'''
class ChannelManager:
def __init__(self):
self.channels = {}
self.lock = threading.RLock() # 用于保证字典操作的线程安全
self._channels = {} #channel_id ChannelData(C_Node)
self.cm_lock = threading.RLock() # 用于保证字典操作的线程安全
self.logger = LogHandler().get_logger("ChannelManager")
# 独立Model_th相关参数 --- modelNode 用一个类封装下model线程和其相关参数
self.model_list = {} # model_id -- modelNode
self.workType = int(myCongif.get_data("workType"))
self.device_id = myCongif.get_data("device_id")
#增加节点
def add_channel(self, channel_id, str_url, int_type, bool_run, deque_length=10,icount_max=100000):
with self.lock:
if channel_id in self.channels: #若已经有数据,先删除后再增加
self.channels[channel_id].clear() # 手动清理资源
del self.channels[channel_id]
self.channels[channel_id] = ChannelData(str_url, int_type, bool_run, deque_length,icount_max)
def add_channel(self, channel_id,deque_length,icount_max,warnM):
ret = False
with self.cm_lock:
if channel_id in self._channels: #若已经有数据,先删除后再增加
self._channels[channel_id].stop_work(0) # 停止工作
del self._channels[channel_id]
if self.workType == 2: # 若有model线程停止了,则删除该model节点
self.delModelNode()
#channel_id,deque_length,icount_max,warnM
ch_data = ChannelData(channel_id, deque_length, icount_max,warnM)
self._channels[channel_id] = ch_data
ret = True
return ret
#删除节点
def delete_channel(self, channel_id):
with self.lock:
if channel_id in self.channels:
self.channels[channel_id].clear() # 手动清理资源
del self.channels[channel_id]
#获取节点
def get_channel(self, channel_id):
with self.lock:
return self.channels.get(channel_id)
#停止工作线程
def stop_channel(self,channel_id):
with self.lock:
def delete_channel(self, channel_id): #需要验证资源的释放清空
'''删除节点,包含了停止该节点工作线程'''
ret = True
with self.cm_lock:
if channel_id == 0:
for clannel_data in self._channels:
clannel_data.stop_work(0)
self._channels.clear() #清空节点
else:
if channel_id in self._channels:
self._channels[channel_id].stop_work(0) #停止工作
del self._channels[channel_id]
if self.workType == 2: #若有model线程停止了,则删除该model节点
self.delModelNode()
return ret
#开始工作线程
def start_channel(self,channel_id,cap_data,model_data,schedule,type):
'''
启动通道的工作线程 -- 启动应该没有一下子启动所有
:param channel_id: 启动通道的ID channel_id == 0的情况已经在上一层处理了这里不会有0
:param cap_data: [source,type]
:param model_data: 跟该通道关联的模型数据
:param schedule
:param type: 0-启动所有工作线程1-启动CAP采集线程2-启动model工资线程
:return:
'''
ret = False
with self.cm_lock:
if channel_id in self._channels:
c_node = self._channels[channel_id]
model_nodeM = None
if self.workType == 2 and type !=1: #需要确保当type!=1时,model_data必须有数据 -- 调用时已经有判断
model_nodeM = self.CreateModelNode(model_data[0], model_data[5], channel_id)
ret = c_node.start_work(cap_data,model_data,schedule,type,model_nodeM)
return ret
#停止工作线程---要把视频采集线程停止掉
def stop_channel(self,channel_id,type): #9-10截止目前就重启模型线程时用到该函数(channel_id,2)
'''
停止通道的工作线程
:param channel_id: 0-停止所有通道的工作线程其他值为具体停止哪个工作线程
:param type: 0-停止所有工作线程1-停止CAP采集线程2-停止model工资线程
:return:
'''
with self.cm_lock:
ret = False
if channel_id == 0:
for clannel_id,clannel_data in self.channels.items():
clannel_data.clear()
del self.channels
# for clannel_id,clannel_data in self.channels.items():
for clannel_data in self._channels:
clannel_data.stop_work(type)
ret = True
else:
if channel_id in self.channels:
self.channels[channel_id].clear() # 手动清理资源
del self.channels[channel_id]
if channel_id in self._channels:
self._channels[channel_id].stop_work(type)
ret =True
if self.workType == 2: #若有model线程停止了,则删除该model节点
self.delModelNode()
return ret
def get_channel_data(self,channel_id):
cdata = None
if channel_id in self._channels:
cdata = self._channels[channel_id]
return cdata
def cm_get_last_frame(self,channel_id): #这里如果加锁的话,阻塞会比较厉害,但具体程度也需要验证。
frame = None
if channel_id in self._channels:
try:
frame = self._channels[channel_id].get_last_frame()
except Exception as e:
print(e)
return frame
if __name__ == "__main__":
# 示例使用
manager = ChannelManager()
manager.add_channel('channel_1', 'test', 123, True, deque_length=5)
def cm_get_cap_frame(self,channel_id):
img_base64 = None
if channel_id in self._channels:
channel_data = self._channels[channel_id]
if channel_data.cap:
try:
for i in range(5):
ret, frame = channel_data.cap.read()
if ret:
ret, frame_bgr_webp = cv2.imencode('.jpg', frame)
if ret:
# 将图像数据编码为Base64
img_base64 = base64.b64encode(frame_bgr_webp).decode('utf-8')
break
except Exception as e:
print(e)
return img_base64
'''模型独立线程修改2024-9-9,要求是双模式兼容'''
'''2024-10-13修改独立线程为独立进程---acl初始化需要在子进程中初始化 -- 该方案无法兼容旧版本'''
'''2025-10-24修改动态通道数量,cm --> mn_m -->model_nodel'''
def CreateModelNode(self, model_id, model_path, channel_id):
if model_id in self.model_list:
modelNM = self.model_list[model_id]
else:
modelNM = ModelNodeManger(self.device_id,model_id,model_path)
self.model_list[model_id] = modelNM
#modelN = ModelNode(self.device_id, model_path,channel_id)
return modelNM
def delModelNode(self): #关于modelnodel :1.考虑modelnode是否可以不删除,清空inmq即可,2.mdel_list是否需要加锁。#?
#return
for model_id, modelNodeM in self.model_list.items():
if modelNodeM.ch_count == 0:
del self.model_list[model_id]
# 更新和读取操作
manager.update_channel_deque('channel_1', 'data1')
manager.update_channel_buffer('channel_1', np.array([[1, 2], [3, 4]]))
manager.increment_channel_counter('channel_1')
channel_data = manager.get_channel_data('channel_1')
print(channel_data)
if __name__ == "__main__":
# 示例使用
pass

157
core/DBManager.py

@ -104,39 +104,38 @@ class DBManager():
return bok
#---------------------特定数据库操作函数---------------------
#根据通道ID或者模型ID删除通道和模型间的关联数据 1-通道ID,2-模型ID
def delC2M(self,ID,itype):
'''
#根据通道ID或者模型ID删除通道和模型间的关联数据 1-通道ID,2-模型ID ,注意会有删除没有数据的情况
:param ID:
:param itype:1-通道ID2-模型ID
:return: 删除数据库记录没做特别的判断
'''
#channel2model
col_name = ""
if itype ==1:
strsql = f"select ID from channel2model where channel_id={ID};"
datas = self.do_select(strsql)
strsql = f"delete from channel2model where channel_id={ID};"
ret = self.do_sql(strsql)
if ret == False:
return False
col_name = "channel_id"
elif itype ==2:
strsql = f"select ID from channel2model where model_id={ID};"
datas = self.do_select(strsql)
strsql = f"delete from channel2model where model_id={ID};"
ret = self.do_sql(strsql)
if ret == False:
return False
col_name = "model_id"
else:
return False
#schedule
for data in datas:
return False
strsql = f"select ID from channel2model where {col_name}={ID};"
data = self.do_select(strsql,1)
if data:
c2m_id = data[0]
strsql = f"delete from channel2model where {col_name}={ID};"
ret = self.do_sql(strsql)
# schedule --- 调整后一个通道就一个mode
strsql = f"delete from schedule where channel2model_id={c2m_id};"
ret = self.do_sql(strsql)
if ret == False:
return False
return True
#删除通道,需要关联删除布防时间,通道和算法的关联表
def delchannel(self,ID):
ret = self.delC2M(ID)
ret = self.delC2M(ID,1)
if ret == False:
return False
#channel
@ -149,56 +148,82 @@ class DBManager():
#修改视频通道和算法间的关联关系
#channel_id 通道ID
#modell_list 最新配置的模型id list
def updateC2M(self,channel_id,model_list):
strsql = f"select model_id from channel2model where channel_id={channel_id};"
datas = set(self.do_select(strsql))
data_new = set(model_list)
#计算要新增和修改的
need_add = data_new - datas
need_del = datas-data_new
#新增
for one in need_add:
strsql = f"insert into channel2model (channel_id,model_id) values ({channel_id},{one});"
if self.do_sql(strsql) == False:
return False
#初始化布防时间 -- 全1
strsql = f"select ID from channel2model where channel_id={channel_id} and model_id={one};"
data = mDBM.do_select(strsql,1)
schedule_data_str = ("{'6': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "
"'0': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "
"'1': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "
"'2': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "
"'3': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],"
"'4': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],"
"'5': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}")
schedule_data = json.loads(schedule_data_str.replace("'", '"'))
for day, hours in schedule_data.items():
for hour, status in enumerate(hours):
strsql = (
f"insert into schedule (channel2model_id,day,hour,status) values ({ID},'{day}',{hour},{status})"
f" on conflict(channel2model_id,day,hour) do update set status=excluded.status;")
ret = mDBM.do_sql(strsql)
if not ret:
return ret
#差删除
for one in need_del:
strsql = f"select ID from channel2model where channel_id={channel_id} and model_id={one};"
c2m_id = mDBM.do_select(strsql,1)[0]
#删除布防计划数据
strsql = f"delete from schedule where channel2model_id={c2m_id};"
if self.do_sql(strsql) == False:
return False
#删除关联记录
strsql = f"delete from channel2model where ID = {c2m_id};"
if self.do_sql(strsql) == False:
return False
return True
# 0--失败,其他值成功
def updateC2M(self,channel_id,model_id,check_area,polygon_str,conf_thres,iou_thres):
c2m_id = 0
strsql = f"select ID from channel2model where channel_id={channel_id};"
data = self.do_select(strsql,1) #c2m_id
if data: #修改数据
strsql = (f"update channel2model set model_id = {model_id},check_area={check_area},"
f"polygon='{polygon_str}',conf_thres={conf_thres},iou_thres={iou_thres} "
f"where channel_id={channel_id};")
else: #插入数据
strsql = (f"insert into channel2model (channel_id,model_id,check_area,polygon,conf_thres,iou_thres) "
f"values ({channel_id},{model_id},{check_area},'{polygon_str}',{conf_thres},{iou_thres});")
ret = self.do_sql(strsql)
if not ret:
return c2m_id
else:
if data:
return data[0]
else:
strsql = f"select ID from channel2model where channel_id={channel_id};"
new_c2m_ids = self.do_select(strsql,1)
if new_c2m_ids:
return new_c2m_ids[0]
else:
print("正常不会没有值!!")
return 0
def getschedule(self,c2m_id):
'''
根据c2mID 查询该算法的布防时间
:param c2m_id:
:return: 以day为行hour作为列的布防标识值二维list
'''
strsql = f"select day,hour,status from schedule where channel2model_id ={c2m_id} order by hour asc,day asc;"
datas = self.do_select(strsql)
onelist = []
twolist = []
threelist = []
fourlist = []
fivelist = []
sixlist = []
sevenlist = []
if datas:
for i in range(24):
onelist.append(datas[i*7 + 0][2])
twolist.append(datas[i*7 + 1][2])
threelist.append(datas[i*7 + 2][2])
fourlist.append(datas[i*7 + 3][2])
fivelist.append(datas[i*7 + 4][2])
sixlist.append(datas[i*7 + 5][2])
sevenlist.append(datas[i*7 + 6][2])
else:
self.logger.debug(f"没有数据--{c2m_id}")
onelist = [1]*24
twolist = [1]*24
threelist = [1]*24
fourlist = [1]*24
fivelist = [1]*24
sixlist = [1]*24
sevenlist = [1]*24
schedule_list = []
schedule_list.append(onelist)
schedule_list.append(twolist)
schedule_list.append(threelist)
schedule_list.append(fourlist)
schedule_list.append(fivelist)
schedule_list.append(sixlist)
schedule_list.append(sevenlist)
return schedule_list
#检查设备ID是否在数据库?
def checkDevID(self,cID):
pass
def test(self):
# 建立数据库连接
conn = pymysql.connect(

20
core/DataStruct.py

@ -22,4 +22,24 @@ class CSAPPLogin_Data(ctypes.Structure):
('passwd', ctypes.c_char * 32)
]
class ModelinData:
def __init__(self,channel_id,img,image,scale_ratio, pad_size):
self.channel_id = channel_id #通道ID
self.img = img #预处理后的图片数据
self.image = image #原图的数据
self.scale_ratio = scale_ratio
self.pad_size = pad_size
def __del__(self):
pass
class ModeloutData:
def __init__(self,image,scale_ratio, pad_size,outputs,channel_id):
self.image = image #原图
self.outputs = outputs #模型推理后结果
self.scale_ratio = scale_ratio
self.pad_size = pad_size
self.channel_id = channel_id
def __del__(self):
pass

552
core/ModelManager.py

@ -1,439 +1,38 @@
# 导入代码依赖
import time
import av
import os
import cv2
import numpy as np
import threading
import importlib.util
import datetime
import math
import queue
from collections import deque
from core.DBManager import mDBM,DBManager
from core.DBManager import mDBM
from myutils.MyLogger_logger import LogHandler
from myutils.ConfigManager import myCongif
from model.plugins.ModelBase import ModelBase
from core.ChannelManager import ChannelManager
from core.ACLModelManager import ACLModeManger
from PIL import Image
class VideoCaptureWithFPS:
'''视频捕获的封装类,是一个通道一个'''
def __init__(self, source):
self.source = source
self.width = None
self.height = None
self.cap = cv2.VideoCapture(self.source)
if self.cap.isOpened(): #若没有打开成功,在读取画面的时候,已有判断和处理 -- 这里也要检查下内存的释放情况
self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(self.width,self.height)
#self.fps = fps # 线程保持最大帧率的刷新画面---过高的帧率会影响CPU性能,但过地的帧率会造成帧积压
self.fps = math.ceil(self.cap.get(cv2.CAP_PROP_FPS)/float(myCongif.get_data("verify_rate"))) #向上取整。
#print(self.fps)
self.running = True
#self.frame_queue = queue.Queue(maxsize=1)
self.frame = None
self.read_lock = threading.Lock()
self.thread = threading.Thread(target=self.update)
self.thread.start()
def update(self):
icount = 0
while self.running:
ret, frame = self.cap.read()
if not ret:
icount += 1
if icount > 5: #重连
self.cap.release()
self.cap = cv2.VideoCapture(self.source)
if self.cap.isOpened():
self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# self.fps = fps # 线程保持最大帧率的刷新画面---过高的帧率会影响CPU性能,但过地的帧率会造成帧积压
self.fps = math.ceil(
self.cap.get(cv2.CAP_PROP_FPS) / float(myCongif.get_data("verify_rate"))) # 向上取整。
icount = 0
else:
time.sleep(1)
continue
#resized_frame = cv2.resize(frame, (int(self.width / 2), int(self.height / 2)))
with self.read_lock:
self.frame = frame
# if not self.frame_queue.full():
# self.frame_queue.put(resized_frame)
# 跳过指定数量的帧以避免积压
for _ in range(self.fps):
self.cap.grab()
# time.sleep(self.fps) #按照视频源的帧率进行休眠
#print("Frame updated at:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
def read(self):
with self.read_lock:
frame = self.frame.copy() if self.frame is not None else None
if frame is not None:
return True, frame
else:
return False, None
# if not self.frame_queue.empty():
# return True, self.frame_queue.get()
# else:
# return False, None
def release(self):
self.running = False
self.thread.join()
self.cap.release()
from core.WarnManager import WarnManager
class ModelManager:
def __init__(self):
self.verify_list = ChannelManager() #模型的主要数据 -- 2024-7-5修改为类管理通道数据
self.bRun = True
self.logger = LogHandler().get_logger("ModelManager")
# 本地YOLOv5仓库路径
self.yolov5_path = myCongif.get_data("yolov5_path")
#self.buflen = myCongif.get_data("buffer_len")
self.icout_max = myCongif.get_data("RESET_INTERVAL") #跟视频帧序用一个变量
self.frame_rate = myCongif.get_data("frame_rate")
self.frame_interval = 1.0 / int(myCongif.get_data("verify_rate"))
#保存视频相关内容
self.FPS = myCongif.get_data("verify_rate") # 视频帧率--是否能实现动态帧率
self.fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 使用 mp4 编码
#基于模型运行环境进行相应初始化工作
# 报警处理线程-全进程独立一个线程处理
self.warnM = None
# acl初始化 -- 一个进程一个
self.model_platform = myCongif.get_data("model_platform")
self.device_id = myCongif.get_data("device_id")
# acl初始化 -- 一个线程一个 -- 需要验证
if self.model_platform == "acl":
ACLModeManger.init_acl(self.device_id) #acl -- 全程序初始化
if myCongif.get_data("workType") == 1:
self.device_id = myCongif.get_data("device_id")
ACLModeManger.init_acl(self.device_id) #acl -- 全程序初始化
self.model_dic = {} # model_id model
def __del__(self):
self.logger.debug("释放资源")
self.stop_work(0) #停止所有工作
del self.verify_list #应该需要深入的删除--待完善
if self.model_platform == "acl":
ACLModeManger.del_acl(self.device_id) #acl -- 全程序反初始化 需要确保在执行析构前,其它资源已释放
def _open_view(self,url,itype): #打开摄像头 0--USB摄像头,1-RTSP,2-海康SDK
if itype == 0:
cap = VideoCaptureWithFPS(int(url))
elif itype == 1:
cap = VideoCaptureWithFPS(url)
else:
raise Exception("视频参数错误!")
return cap
def _import_model(self,model_name,model_path,threshold):
'''
根据路径动态导入模块
:param model_name: 模块名称
:param model_path: 模块路径
:param threshold: 置信阈值
:return:
'''
if os.path.exists(model_path):
module_spec = importlib.util.spec_from_file_location(model_name, model_path)
if module_spec is None:
self.logger.error(f"{model_path} 加载错误")
return None
module = importlib.util.module_from_spec(module_spec)
module_spec.loader.exec_module(module)
md = getattr(module, "Model")(model_path,threshold) #实例化类
if not isinstance(md, ModelBase):
self.logger.error("{} not zf_model".format(md))
return None
if md.init_ok == False:
self.logger.error("离线模型加载初始化失败!")
return None
else:
self.logger.error("{}文件不存在".format(model_path))
return None
return md
def getschedule(self,c2m_id,myDBM):
'''
根据c2mID 查询该算法的布防时间
:param c2m_id:
:return: 以day为行hour作为列的布防标识值二维list
'''
strsql = f"select day,hour,status from schedule where channel2model_id ={c2m_id} order by hour asc,day asc;"
datas = myDBM.do_select(strsql)
onelist = []
twolist = []
threelist = []
fourlist = []
fivelist = []
sixlist = []
sevenlist = []
if datas:
for i in range(24):
onelist.append(datas[i*7 + 0][2])
twolist.append(datas[i*7 + 1][2])
threelist.append(datas[i*7 + 2][2])
fourlist.append(datas[i*7 + 3][2])
fivelist.append(datas[i*7 + 4][2])
sixlist.append(datas[i*7 + 5][2])
sevenlist.append(datas[i*7 + 6][2])
else:
self.logger.debug(f"没有数据--{c2m_id}")
onelist = [1]*24
twolist = [1]*24
threelist = [1]*24
fourlist = [1]*24
fivelist = [1]*24
sixlist = [1]*24
sevenlist = [1]*24
schedule_list = []
schedule_list.append(onelist)
schedule_list.append(twolist)
schedule_list.append(threelist)
schedule_list.append(fourlist)
schedule_list.append(fivelist)
schedule_list.append(sixlist)
schedule_list.append(sevenlist)
return schedule_list
def set_last_img(self,):
pass
def verify(self,frame,myModle_list,myModle_data,channel_id,schedule_list,result_list,isdraw=1):
'''验证执行主函数,实现遍历通道关联的模型,调用对应模型执行验证,模型文件遍历执行'''
img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
#img = np.ascontiguousarray(img, dtype=np.float32) / 255.0 # 转换为内存连续存储的数组 --该函数可以待定下是不是所有模型都可以做
# img = frame.to_ndarray(format="bgr24")
#img = frame
# 使用 模型 进行目标检测
i_warn_count = 0 #报警标签
#isverify = False
for i in range(len(myModle_list)): # 遍历通道关联的算法进行检测,若不控制模型数量,有可能需要考虑多线程执行。
model = myModle_list[i]
data = myModle_data[i]
schedule = schedule_list[i]
result = result_list[i]
#验证检测计划,是否在布防时间内
now = datetime.datetime.now() # 获取当前日期和时间
weekday = now.weekday() # 获取星期几,星期一是0,星期天是6
hour = now.hour
result.pop(0) # 保障结果数组定长 --先把最早的结果推出数组
if schedule[weekday][hour] == 1: #不在计划则不进行验证,直接返回图片
# 调用模型,进行检测,model是动态加载的,具体的判断标准由模型内执行 ---- *********
#isverify = True
detections, bwarn, warntext = model.verify(img, data,isdraw) #****************重要
# 对识别结果要部要进行处理
if bwarn: # 整个识别有产生报警
#根据模型设定的时间和占比判断是否
# 绘制报警文本
cv2.putText(img, 'Intruder detected!', (50, (i_warn_count + 1) * 50),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
i_warn_count += 1
result.append(1) #要验证数组修改,是地址修改吗?
else: #没有产生报警也需要记录,统一计算占比
result.append(0)
else:
result.append(0)
# if not isverify: #没做处理,直接返回的,需要控制下帧率,太快读取没有意义。 --2024-7-5 取消休眠,帧率控制在dowork_thread完成
# time.sleep(1.0/self.frame_rate) #给个默认帧率,不超过30帧,---若经过模型计算,CPU下单模型也就12帧这样
# 将检测结果图像转换为帧--暂时用不到AVFrame--2024-7-5
# new_frame_rgb_avframe = av.VideoFrame.from_ndarray(img, format="rgb24") # AVFrame
# new_frame_rgb_avframe.pts = None # 添加此行确保有pts属性
# if isinstance(img, np.ndarray): -- 留个纪念
#处理完的图片后返回-bgr模式
img_bgr_ndarray = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
# 将检查结果转换为WebP格式图片 --在线程里面完成应该可以减少网页端处理时间
ret,frame_bgr_webp=cv2.imencode('.jpg', img_bgr_ndarray)
if not ret:
buffer_bgr_webp = None
else:
buffer_bgr_webp = frame_bgr_webp.tobytes()
return buffer_bgr_webp,img_bgr_ndarray
def dowork_thread(self,channel_id):
'''一个通道一个线程,关联的模型在一个线程检测,局部变量都是一个通道独有'''
channel_data = self.verify_list.get_channel(channel_id) #是对ChannelData 对象的引用
context = None
# 线程ACL初始化
if self.model_platform == "acl": # ACL线程中初始化内容
context = ACLModeManger.th_inti_acl(self.device_id)
#查询关联的模型 --- 在循环运行前把基础数据都准备好
myDBM = DBManager()
myDBM.connect()
strsql = (f"select t1.model_id,t1.check_area,t1.polygon ,t2.duration_time,t2.proportion,t2.model_path,t1.ID,"
f"t2.model_name,t1.conf_threshold "
f"from channel2model t1 left join model t2 on t1.model_id = t2.ID where t1.channel_id ={channel_id};")
#print(strsql)
myModels = myDBM.do_select(strsql)
#加载模型 --- 是不是要做个限制,一个视频通道关联算法模块的上限 --- 关联多了一个线程执行耗时较多,造成帧率太低,或者再多线程并发 #?
myModle_list = [] #存放模型对象List 一个模型一个
myModle_data = [] #存放检测参数 一个模型一个
schedule_list = [] #布防策略 -一个模型一个
result_list = [] #检测结果记录 -一个模型一个
warn_last_time =[] #最新的报警时间记录 -一个模型一个
proportion_list = []#占比设定 -一个模型一个
warn_save_count = []#没个模型触发报警后,保存录像的最新帧序号 -一个模型一个
#获取视频通道的模型相关数据-list
for model in myModels:
#基于基类实例化模块类
m = self._import_model("",model[5],model[8]) #动态加载模型处理文件py --需要验证模型文件是否能加载
#m = None
if m:
myModle_list.append(m) #没有成功加载的模型原画输出
myModle_data.append(model)
#model[6] -- c2m_id --布防计划 0-周一,6-周日
schedule_list.append(self.getschedule(model[6],myDBM))
result = [0 for _ in range(model[3] * myCongif.get_data("verify_rate"))] #初始化时间*验证帧率数量的结果list
result_list.append(result)
warn_last_time.append(time.time())
proportion_list.append(model[4]) #判断是否报警的占比
warn_save_count.append(0) #保存录像的最新帧初始化为0
#开始拉取画面循环检测
cap = None
#iread_count =0 #失败读取的次数
last_frame_time = time.time() #初始化个读帧时间
cap_sleep_time = myCongif.get_data("cap_sleep_time")
#可以释放数据库资源
del myDBM
warn_interval = myCongif.get_data("warn_interval")
while channel_data.bool_run: #基于tag 作为运行标识。 线程里只是读,住线程更新,最多晚一轮,应该不用线程锁。需验证
# 帧率控制帧率
current_time = time.time()
elapsed_time = current_time - last_frame_time
if elapsed_time < self.frame_interval:
time.sleep(self.frame_interval - elapsed_time) #若小于间隔时间则休眠
last_frame_time = time.time()
#*********取画面*************
if not cap: #第一次需要打开视频流
try:
cap = self._open_view(channel_data.str_url,channel_data.int_type) #创建子线程读画面
except:
self.logger.error("打开视频参数错误,终止线程!")
return
ret,frame = cap.read() #除了第一帧,其它应该都是有画面的
if not ret:
# if iread_count > 30: #2024-7-8 重连接机制放VideoCaptureWithFPS
# self.logger.warning(f"通道-{channel_id}:view disconnected. Reconnecting...")
# cap.release()
# cap = None
# time.sleep(cap_sleep_time)
# else:
# iread_count += 1
continue #没读到画面继续
#执行图片推理 -- 如何没有模型或不在工作时间,返回的是原画,要不要控制下帧率? -- 在verify中做了sleep
buffer_bgr_webp,img_bgr_ndarray = self.verify(frame,myModle_list,myModle_data,channel_id,schedule_list,result_list)
#分析图片放入内存中
channel_data.add_deque(img_bgr_ndarray) # 缓冲区大小由maxlen控制 超上限后,删除最前的数据
channel_data.increment_counter() #帧序列加一
# 一直更新最新帧,提供网页端显示
channel_data.update_last_frame(buffer_bgr_webp)
#print(f"{channel_id}--Frame updated at:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
#验证result_list -是否触发报警要求 --遍历每个模型执行的result
for i in range(len(result_list)):
result = result_list[i]
proportion = proportion_list[i]
count_one = float(sum(result)) #1,0 把1累加的和就是1的数量
ratio_of_ones = count_one / len(result)
#self.logger.debug(result)
if ratio_of_ones >= proportion: #触发报警
# 基于时间间隔判断
current_time = time.time()
elapsed_time = current_time - warn_last_time[i]
if elapsed_time < warn_interval:
continue
warn_last_time[i] = current_time
model_name = myModle_data[i][7]
w_s_count = warn_save_count[i]
buffer_count = channel_data.get_counter()
self.save_warn(model_name,w_s_count,buffer_count,channel_data.copy_deque(),
cap.width,cap.height,channel_id,None,self.FPS,self.fourcc)
self.send_warn()
#更新帧序列号
warn_save_count[i] = buffer_count
#结果记录要清空
for i in range(len(result)):
result[i] = 0
# end_time = time.time() # 结束时间
# print(f"Processing time: {end_time - start_time} seconds")
# 本地显示---测试使用
# if channel_id == 2:
# cv2.imshow(str(channel_id), img)
# if cv2.waitKey(1) & 0xFF == ord('q'):
# break
#结束线程
cap.release() #视频采集线程结束
if context:#ACL线程中反初始化内容 -- 若线程异常退出,这些资源就不能正常释放了
#先释放每个模型资源
for model in myModle_list:
del model
#再释放context
ACLModeManger.th_del_acl(context)
#cv2.destroyAllWindows()
def save_warn(self,model_name,w_s_count,buffer_count,buffer,width,height,channnel_id,myDBM,FPS,fourcc):
'''
保存报警信息 --- 涉及到I/O操作可以通过线程取执行 -- 避免主线程阻塞 --还未验证-2024-7-6
:param model_name: 模型名称如人员入侵
:param w_s_count: 报警已存储的最新帧序列
:param buffer_count: 当前视频缓冲区的最新帧序列
:param buffer: 视频缓存区
:param width: 视频画面的width
:param height: 视频画面的height
:param channnel_id: 视频通道ID
:return: ret 数据库操作记录
'''
return
def save_warn_th(model_name,w_s_count,buffer_count,buffer,width,height,channnel_id,myDBM,FPS,fourcc):
now = datetime.datetime.now() # 获取当前日期和时间
current_time_str = now.strftime("%Y-%m-%d_%H-%M-%S")
filename = f"{channnel_id}_{current_time_str}"
save_path = myCongif.get_data("warn_video_path")
#保存视频
video_writer = cv2.VideoWriter(f"{save_path}{filename}.mp4", fourcc, FPS, (width, height))
if not video_writer.isOpened():
print(f"Failed to open video writer for model/warn/{filename}.mp4")
return False
ilen = len(buffer)
istart = 0;
iend = ilen
if buffer_count < w_s_count or (buffer_count-w_s_count) > ilen: #buffer_count重置过
#buffer区,都保存为视频
istart = 0
else:#只取差异的缓冲区大小
istart = ilen - (buffer_count-w_s_count)
for i in range(istart,iend):
video_writer.write(buffer[i])
video_writer.release()
#保存图片
ret = cv2.imwrite(f"model/warn/{filename}.png",buffer[-1])
#buffer使用完后删除
del buffer
if not ret:
print("保存图片失败")
return False
#保存数据库
myDBM = DBManager()
myDBM.connect()
strsql = (f"INSERT INTO warn (model_name ,video_path ,img_path ,creat_time,channel_id ) "
f"Values ('{model_name}','model/warn/{filename}.mp4','model/warn/{filename}.png',"
f"'{current_time_str}','{channnel_id}');")
ret = myDBM.do_sql(strsql)
del myDBM #释放数据库连接资源
return ret
th_chn = threading.Thread(target=save_warn_th,
args=(model_name,w_s_count,buffer_count,buffer,width,height,channnel_id,None,FPS,fourcc,)) # 一个视频通道一个线程,线程句柄暂时部保留
th_chn.start()
if self.model_platform == "acl": #去初始化
if myCongif.get_data("workType") == 1:
ACLModeManger.del_acl(self.device_id) #acl -- 全程序反初始化 需要确保在执行析构前,其它资源已释放
def send_warn(self):
'''发送报警信息'''
@ -448,53 +47,106 @@ class ModelManager:
1.布防开关需要触发通道关闭和开启
2.布防策略的调整也需要关闭和重启工作
'''
# 启动告警线程
if self.warnM is None:
self.warnM = WarnManager()
self.warnM.start_warnmanager_th()
#工作线程:cap+model
if channel_id ==0:
strsql = "select id,ulr,type from channel where is_work = 1;" #执行所有通道
else:
strsql = f"select id,ulr,type from channel where is_work = 1 and id = {channel_id};" #单通道启动检测线程
datas = mDBM.do_select(strsql)
deque_length = myCongif.get_data("buffer_len")
icount_max = myCongif.get_data("RESET_INTERVAL")
for data in datas:
# img_buffer = deque(maxlen=myCongif.get_data("buffer_len")) #创建个定长的视频buffer
# img = None
# icout = 0 #跟img_buffer对应,记录进入缓冲区的帧序列号
# run_data = [data[1],data[2],True,img_buffer,img,icout]
# self.verify_list[data[0]] = run_data #需要验证重复情况#? channel_id, str_url, int_type, bool_run, deque_length
self.verify_list.add_channel(data[0],data[1],data[2],True,myCongif.get_data("buffer_len"),myCongif.get_data("RESET_INTERVAL"))
th_chn = threading.Thread(target=self.dowork_thread, args=(data[0],)) #一个视频通道一个线程,线程句柄暂时部保留
th_chn.start()
def stop_work(self,channel_id=0):
'''停止工作线程,0-停止所有,非0停止对应通道ID的线程'''
self.verify_list.stop_channel(channel_id)
channel_id = data[0]
#1.创建channel对象 #channel_id,deque_length,icount_max,warnM
ret = self.verify_list.add_channel(channel_id,deque_length,icount_max,self.warnM)
if ret:
# 2.启动工作线程
strsql = (
f"select t1.model_id,t1.check_area,t1.polygon ,t2.duration_time,t2.proportion,t2.model_path,t1.ID,"
f"t2.model_name,t1.conf_thres,t1.iou_thres "
f"from channel2model t1 left join model t2 on t1.model_id = t2.ID where t1.channel_id ={channel_id};")
model_data = mDBM.do_select(strsql, 1) # 2024-7-12调整规则,一个通道只关联一个模型,表结构暂时不动
cap_data = [data[1], data[2]] # cap_data[source,type]
if model_data and model_data[0]: # 如果该通道关联了模型
schedule = mDBM.getschedule(model_data[6]) # 获取布防计划
#启动通道线程
self.verify_list.start_channel(channel_id,cap_data,model_data,schedule,0) #cap + model
else:
self.logger.debug(f"{channel_id}通道没有关联模型,只运行cap采集线程")
# 启动
self.verify_list.start_channel(channel_id, cap_data, None,None, 1) # cap
else:
print("*****有错误********")
def stop_work(self,channel_id=0): #全停 要对应start_work 1.停止model线程,2.停止cap线程。3.删除c_data
'''停止工作线程(包括采集线程,并删除通道数据对象),0-停止所有,非0停止对应通道ID的线程'''
try:
self.verify_list.delete_channel(channel_id)
except Exception as e:
print(e)
if channel_id == 0:
#停止告警线程
self.warnM.brun = False
del self.warnM
self.warnM = None
def restartC2M(self,channel_id):
'''
修改通道管理的算法模型后需要对该通道算法执行部分重新加载执行 -- 只重启model线程
:param channel_id:
:return:
'''
#停止该通道的工作线程 -- 不停cap
self.verify_list.stop_channel(channel_id,2)
#重新读取工作线程数据,重启该通道的工作线程
self.startModelWork(channel_id)
def startModelWork(self,channel_id):
strsql = (
f"select t1.model_id,t1.check_area,t1.polygon ,t2.duration_time,t2.proportion,t2.model_path,t1.ID,"
f"t2.model_name,t1.conf_thres,t1.iou_thres "
f"from channel2model t1 left join model t2 on t1.model_id = t2.ID where t1.channel_id ={channel_id};")
model_data = mDBM.do_select(strsql, 1) # 2024-7-12调整规则,一个通道只关联一个模型,表结构暂时不动
if model_data and model_data[0]: # 如果该通道关联了模型
schedule = mDBM.getschedule(model_data[6]) # 获取布防计划
cap_data = None # cap_data[source,type]
# 启动
self.logger.debug(f"通道{channel_id}重新启动model线程")
self.verify_list.start_channel(channel_id, cap_data, model_data, schedule, 2) # model
else:
self.logger.debug(f"通道{channel_id}没有关联模型,不需要启动model线程")
def test1(self):
# from model.plugins.RYRQ_Model_ACL.RYRQ_Model_ACL import Model
# mymodel = Model("")
# mymodel.testRun()
import importlib
# 需要导入的模块路径
module_path = "model.plugins.RYRQ_Model_ACL.RYRQ_Model_ACL"
# 动态导入模块
module_name = importlib.import_module(module_path)
# 从模块中加载指定的类
Model = getattr(module_name, "Model")
# 使用 Model 类
model_instance = Model("")
model_instance.testRun()
#print(f"Current working directory (ModelManager.py): {os.getcwd()}")
mMM = ModelManager()
def test1():
print(cv2.getBuildInformation())
source = 'rtsp://192.168.3.44/live1'
gstreamer_pipeline = (
f"rtspsrc location={source} protocols=udp latency=0 ! "
"rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! appsink"
)
cap = cv2.VideoCapture(gstreamer_pipeline, cv2.CAP_GSTREAMER)
if not cap.isOpened():
print("Error: Unable to open the video source.")
return
else:
print("Successfully opened the video source.")
ret, frame = cap.read()
if ret:
cv2.imshow('Frame', frame)
cv2.waitKey(0)
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
mMM.start_work()
#test1()
print("111")
# name = acl.get_soc_name()
# count, ret = acl.rt.get_device_count()

221
core/ModelNode.py

@ -0,0 +1,221 @@
import threading
import time
import multiprocessing
import importlib.util
from multiprocessing.managers import BaseManager
from myutils.ConfigManager import myCongif
from myutils.MyLogger_logger import LogHandler
from core.ACLModelManager import ACLModeManger
from core.DataStruct import ModelinData,ModeloutData
from threading import Lock
#2024-10-14model处理调整为独立子进程
def model_process(device,model,model_platform,m_p_status,brun,in_mq,out_mq):
# 初始化模型运行资源
context = None
if model_platform == "acl": # ACL线程中初始化内容
context = ACLModeManger.pro_init_acl(device) # 初始化acl资源,并创建context
# 初始化模型资源 -- 加载模型文件
ret = model.init_acl_resource() # 加载和初始化离线模型文件--om文件
if not ret:
print("初始化模型资源出错,退出线程!")
m_p_status.value = 2
return
#执行工作
m_p_status.value = 1
use_time = 0
icount = 0
while brun.value:
try:
inData = in_mq.get(timeout=0.1) #空时-block,直到有值 #(self,channel_id,img,image,scale_ratio, pad_size):
except:
#print("in_mq_空")
continue
if inData:
#print(f"{time.time()}--{inData.channel_id}--数据取出进行处理!")
s_time = time.time()
outputs = model.execute([inData.img,])#创建input,执行模型,返回结果 --失败返回None
e_time = time.time()
outdata = ModeloutData(inData.image,inData.scale_ratio,inData.pad_size,outputs,inData.channel_id)
del inData.img
#结果输出
if out_mq.full():
tmp = out_mq.get()
#print("model_输出mq满!")
del tmp
out_mq.put(outdata) # 需要确保out_mq只有在这里put
# else: #正常情况不会执行到该条件
# time.sleep(0.01)
icount += 1
use_time += (e_time - s_time)
if icount == 500:
avg_time = use_time / 500
print(f"model_process耗时--{avg_time}")
use_time = 0
icount = 0
#结束进程,释放资源
m_p_status.value = 0
while not in_mq.empty():
try:
in_mq.get_nowait() # Get without blocking
except Exception as e:
break # In case of any unexpected errors
# 反初始化
if model_platform == "acl":
try:
model.release() # 释放模型资源资源
# 删除模型对象
del model
# 释放ACL资源
ACLModeManger.pro_del_acl(device,context)
except Exception as e:
print(e)
class ModelNode:
def __init__(self,device,model_path,ch_max_count=1):
self.device = device
self.model_path = model_path
self.channel_id = [] #channel_id_list
self.model = None #模型对象
self.ch_max_count = ch_max_count
self.ch_count = 0 #关联启动的通道数量
self.count_Lock = Lock() #count的维护锁
self.model_platform = myCongif.get_data("model_platform")
self.logger = LogHandler().get_logger("ModelNode")
#分发线程相关
self.model_out_th = None
self.channel_dict = {}
self.cdict_Lock = Lock()
self.in_mq_Lock = Lock()
self.last_in_c_id = 0
#独立进程方案--共享参数
self.process = None
self.imq_count = ch_max_count * 20 #一个通道20帧缓冲区间
self.in_mq = multiprocessing.Queue(maxsize=self.imq_count)
self.out_mq = multiprocessing.Queue(maxsize=self.imq_count) #调整结构,多线程(预处理)-》in_mq-子进程-out_mq-》线程分发outdata->多线程(后处理)
self.brun = multiprocessing.Value('b',True) #brun.value = False,brun.value = True
self.m_p_status = multiprocessing.Value('i',0)
def __del__(self):
pass
def _import_model(self, model_path, threshold=0.5, iou_thres=0.5):
'''
根据路径动态导入模块
:param model_path: 模块路径
:param threshold: 置信阈值
:param iou_thres: iou阈值
:return:
'''
try:
module_path = model_path.replace("/", ".").rsplit(".", 1)[0]
print(module_path)
# 动态导入模块
module = importlib.import_module(module_path)
# 从模块中获取指定的类
Model = getattr(module, "Model")
# 使用 Model 类
model_instance = Model(model_path, threshold, iou_thres)
return model_instance
except ModuleNotFoundError as e:
print(f"Module not found: {e}")
return None
except AttributeError as e:
print(f"Class not found in module: {e}")
return None
except Exception as e:
print(f"An unexpected error occurred: {e}")
return None
def pro_add_data(self,data):
# try:
# self.in_mq.put(data,timeout=0.1)
# except multiprocessing.queues.Full:
# print("mdel_inmq输入满!")
# del data
with self.in_mq_Lock:
if self.ch_count>1 and self.last_in_c_id == data.channel_id:
return
self.last_in_c_id = data.channel_id
if self.in_mq.full():
tmp = self.in_mq.get()
#print("mdel_inmq输入满!")
del tmp
self.in_mq.put(data) # 需要确保out_mq只有在这里put
def _modle_th(self):
'''根据channel_id分发out_data到out_mq'''
s_time = time.time()
icount = 0
while self.brun.value:
try:
outdata = self.out_mq.get(timeout=0.1)
except:
continue
with self.cdict_Lock:
if outdata.channel_id in self.channel_dict:
self.channel_dict[outdata.channel_id].myappend(outdata) #后面就交给后处理线程了
else:
print(f"{outdata.channel_id}不在channel_dict里面")
# icount += 1
# if icount ==500:
# e_time = time.time()
# use_time = (e_time-s_time) /500
# print(f"{self.channel_id}_modle_th耗时--{use_time}秒")
# s_time = time.time()
# icount = 0
#2024-10-14调整为独立进程执行 -- 一个线程一个MQ MyDeque
def start_model_th(self,channel_id,out_mq):
with self.count_Lock:
with self.cdict_Lock:
if channel_id in self.channel_dict:
print(f"{channel_id}已经在channel_dict内")
return #这个可以删除老的,新增新的--后续验证,若需要则进行修改
self.channel_dict[channel_id] = out_mq #增加一个记录
print(f"新增一个channel节点--{channel_id}")
if self.ch_count == 0: #第一次启动--需要启动处理线程和进程
#加载自定义模型文件
self.model = self._import_model(self.model_path) # 动态加载模型处理文件py --置信阈值一直没使用
if not self.model:
self.logger.error("自定义模型文件加载失败,不启动model子进程")
self.m_p_status.value = 2
return
self.brun.value = True
#创建outMQ的分发线程
self.model_out_th = threading.Thread(target=self._modle_th)
self.model_out_th.start()
# 创建子进程
self.process = multiprocessing.Process(target=model_process,
args=(self.device,self.model,self.model_platform,
self.m_p_status,self.brun,self.in_mq,self.out_mq))
self.process.start()
self.ch_count += 1 #有通道调用一次就加一
def stop_model_th(self,channel_id):
with self.count_Lock:
with self.cdict_Lock:
if channel_id in self.channel_dict:
del self.channel_dict[channel_id]
self.ch_count -= 1
if self.ch_count == 0: #所有通道结束
self.brun.value = False
self.model_out_th.join() #等待线程结束
self.model_out_th = None
self.process.join() #等待子进程结束
self.process = None

76
core/ModelNodeManager.py

@ -0,0 +1,76 @@
import multiprocessing
from threading import Lock
from core.ModelNode import ModelNode
from myutils.ConfigManager import myCongif
class ModelNodeManger:
def __init__(self,device_id,model_id,model_path,threshold=0.5,iou_thres=0.5):
self.ch_count = 0 #当前模型关联的通道数量
self.channel_list = {} #channel_id modelNodle
self.clist_Lock = Lock() # count的维护锁
self.modelNode_list = [] # model_Node
self.brun = multiprocessing.Value('b',True) #brun.value = False,brun.value = True
self.m_p_status = multiprocessing.Value('i',0)
self.model = None # 模型对象
#-------
self.max_count = myCongif.get_data('maxCount')
self.device_id = device_id
self.model_id = model_id
self.model_path = model_path
self.threshold = threshold
self.iou_thres = iou_thres
# #添加数据
# def pro_add_data(self,channel_id,data):
# pass
# # #加锁? -- 对于多线程这里的耗时会不会有点大。。。 model_nodel 反馈出去?????getModle_Nodel
# # with self.clist_Lock:
# # if channel_id in self.channel_list:
# # self.modelNode_list[channel_id].pro_add_data(data)
#暴露modelNodel -- 避免pro_add_data锁竞争
def getModle_Nodel(self,channel_id):
model_nodel = None
if channel_id in self.channel_list:
model_nodel = self.channel_list[channel_id]
return model_nodel
def start_model_th(self, channel_id, out_mq):
with self.clist_Lock:
if channel_id in self.channel_list: #已经在List 说明已经启动过了,但不应该重复调用
print("不应该重复调用start_model_th")
return True
else: # 还没入list ,查找可以插入的model_node
for model_node in self.modelNode_list:
if model_node.ch_count < self.max_count: # 没满可以插入
model_node.start_model_th(channel_id, out_mq) #+1
self.channel_list[channel_id] = model_node #新增 channel_di 与model_node的对应关系
return True
# 执行到这说明没有空的model_nodel -- 需要新建
model_node = ModelNode(self.device_id,self.model_path,self.max_count)
model_node.start_model_th(channel_id, out_mq) # 启动线程,并+1
#两个数据结构,新增节点
self.modelNode_list.append(model_node) #新增一个model_node节点
self.channel_list[channel_id] = model_node #新增 channel_di 与model_node的对应关系
#行动完更新数量
self.ch_count +=1
return True
def stop_model_th(self, channel_id):
with self.clist_Lock:
if channel_id in self.channel_list:
model_node = self.channel_list[channel_id]
model_node.stop_model_th(channel_id) #减-,根据情况停止工作进程、
# 需要考虑下model_node是否要删除,还是保留后重复利用-
if model_node.ch_count ==0:
self.modelNode_list.remove(model_node) #如何没有关联通道了,侧删除该modelnodel
del model_node #删除对象
del self.channel_list[channel_id] #删除channel_id 与 model_node的对应关心节点
#行动完更新数量
self.ch_count -= 1
return True
else:
print("不在list里面,不应该调用stop_model_th")
return False

122
core/Upload_file.py

@ -1,15 +1,129 @@
from quart import Blueprint, render_template, request, redirect, url_for, flash, current_app
import os
import subprocess
from werkzeug.utils import secure_filename
import platform
import zipfile
import importlib.util
import shutil
from myutils.ConfigManager import myCongif
from model.plugins.ModelBase import ModelBase
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in myCongif.get_data('ALLOWED_EXTENSIONS')
#对上传的系统升级包进行检查 type:1--系统升级包,2--算法升级包
def check_file(filepath,type):
pass
def check_file(filepath,filename_pre,type): #默认路径一般都是uploads/文件名
'''
检查上传文件的合法性若符合要求则移动到正式路径下面
:param filepath: .zip文件路径
:param filename_pre: 去除掉.zip的纯文件名
:param type: 1--系统升级包 2--算法升级包
:return: model_version model_name model_path(相对路径)
'''
model_name = None
model_version = None
model_path = None
system = platform.system()
#path = filepath.rsplit('.', 1)[0] #去掉后缀
path = myCongif.get_data("UPLOAD_FOLDER") # uploads
zip_path = filepath.rsplit('.', 1)[0] # uploads/filenamedir
filepath_py = zip_path + '/' + filename_pre + '.py' #这里就需要约束py文件名,就是zip压缩包的文件名
buzip = False
#解压缩
if system == "Windows":
try:
with zipfile.ZipFile(filepath, 'r') as zip_ref:
zip_ref.extractall(path)
buzip = True
except zipfile.BadZipfile:
print("文件格式错误,解压失败")
except Exception as e:
print(f"解压失败: {e}")
elif system == "Linux":
try:
subprocess.run(['unzip', '-o', filepath, '-d', path], check=True)
buzip = True
except subprocess.CalledProcessError as e:
print(f"解压失败: {e.stderr}")
except Exception as e:
print(f"解压失败: {e}")
else:
raise NotImplementedError(f"Unsupported operating system: {system}")
#加载模型文件,获取模型名称和版本号
if buzip:
if type == 2: #模型升级包
print(filepath_py)
model = import_model("",filepath_py,0)
if model:
#把解压文件移动至正式路径
tag_path = myCongif.get_data("Model_Plugins") #model/plugins
ret = move_dir(zip_path,tag_path,filename_pre)
if ret:
model_name = model.name #算法名
model_version = model.version #算法版本
model_path = tag_path+'/'+ filename_pre +'/'+filename_pre +'.py' #py文件的路径,是相对路径
del model
elif type == 1: #系统升级包
pass
else:
pass #错误值
return model_version,model_name,model_path
def move_dir(source_path,tag_path,filename_pre,type=1):
'''
移动文件夹
:param source_path: 源文件夹 ***/***/filedir
:param tag_path: 目标路径 ***/***/ 不需要带filedir
:param filename_pre: 不带后缀的文件名
:param type: 0-不覆盖移动目标路径存在filedir的话返回 1-覆盖移动删除后再移动
:return: False True
'''
bsuccess = False
#若根目录不在,则创建
if not os.path.exists(tag_path): #model/plugins
os.makedirs(tag_path)
#判断移动后目录是否存在
newpath = tag_path + '/' + filename_pre
if os.path.exists(newpath):
if type == 1:
shutil.rmtree(newpath)
else:
return bsuccess #这个返回失败
# 移动文件夹
try:
shutil.move(source_path, tag_path)
print(f"成功将文件夹移动到 {tag_path}")
bsuccess = True
except Exception as e:
print(f"移动文件夹失败: {e}")
return bsuccess
def import_model(model_name,model_path,threshold):
'''
根据路径动态导入模块
:param model_name: 模块名称
:param model_path: 模块路径
:param threshold: 置信阈值
:return:
'''
if os.path.exists(model_path):
module_spec = importlib.util.spec_from_file_location(model_name, model_path)
if module_spec is None:
print(f"{model_path} 加载错误")
return None
module = importlib.util.module_from_spec(module_spec)
module_spec.loader.exec_module(module)
md = getattr(module, "Model")(model_path,threshold) #实例化类
if not isinstance(md, ModelBase):
print("{} not zf_model".format(md))
return None
else:
print("{}文件不存在".format(model_path))
return None
print(f"{model_path} 加载成功!!!!")
return md
def update_system(filepath): #系统升级
pass

110
core/WarnManager.py

@ -0,0 +1,110 @@
import threading
import queue
import datetime
import cv2
from core.DBManager import DBManager
from myutils.ConfigManager import myCongif
class WarnData:
def __init__(self):
self.width = None #视频画面的width
self.height = None #视频画面的height
self.channel_id = None
self.model_name = None #模型名称,如人员入侵
self.img_buffer = None #视频缓冲区 赋值时要拷贝一个备份
self.warn_text = None
self.channel_name = None
class WarnManager:
def __init__(self):
self.warn_q = queue.Queue() #线程安全
self.brun = True
# 保存视频相关内容
self.FPS = myCongif.get_data("verify_rate") # 视频帧率--是否能实现动态帧率
self.fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 使用 mp4 编码
def __del__(self):
pass
def add_warn_data(self,warn_data):
self.warn_q.put(warn_data)
def th_warnmanager(self):
myDBM = DBManager()
myDBM.connect()
while self.brun:
warn_data = None
try:
warn_data = self.warn_q.get(timeout=5)
except queue.Empty:
continue
if warn_data:
ret = self.save_warn(warn_data.model_name,warn_data.img_buffer,warn_data.width,warn_data.height,
warn_data.channel_id,self.FPS,self.fourcc,myDBM)
self.send_warn()
del warn_data.img_buffer
warn_data.img_buffer = None
del warn_data
warn_data = None
def start_warnmanager_th(self):
th_warn = threading.Thread(target=self.th_warnmanager) # 一个视频通道一个线程,线程句柄暂时部保留
th_warn.start()
def stop_warnmanager_th(self):
self.brun = False
del self.warn_q
def send_warn(self):
'''发送报警信息'''
pass
def save_warn(self,model_name,buffer,width,height,channnel_id,FPS,fourcc,myDBM):
'''
保存报警信息 --- 涉及到I/O操作可以通过线程取执行 -- 避免主线程阻塞 --还未验证-2024-7-6
:param model_name: 模型名称如人员入侵
:param w_s_count: 报警已存储的最新帧序列
:param buffer_count: 当前视频缓冲区的最新帧序列
:param buffer: 视频缓存区
:param width: 视频画面的width
:param height: 视频画面的height
:param channnel_id: 视频通道ID
:return: ret 数据库操作记录
'''
now = datetime.datetime.now() # 获取当前日期和时间
current_time_str = now.strftime("%Y-%m-%d_%H-%M-%S")
filename = f"{channnel_id}_{current_time_str}"
save_path = myCongif.get_data("warn_video_path")
# 保存视频
str_video = f"{save_path}{filename}.mp4"
video_writer = cv2.VideoWriter(str_video, fourcc, FPS, (width, height))
#print(f"File: {str_video}, FourCC: {fourcc}, FPS: {FPS}, Size: ({width}, {height})")
if not video_writer.isOpened():
print(f"Failed to open video writer for model/warn/{filename}.mp4")
return False
ilen = len(buffer)
istart = 0;
iend = ilen
for i in range(len(buffer)):
video_writer.write(buffer[i])
video_writer.release()
# 保存图片
ret = cv2.imwrite(f"model/warn/{filename}.png", buffer[-1])
# buffer使用完后删除
del buffer
if not ret:
print("保存图片失败")
return False
# 保存数据库
strsql = (f"INSERT INTO warn (model_name ,video_path ,img_path ,creat_time,channel_id ) "
f"Values ('{model_name}','model/warn/{filename}.mp4','model/warn/{filename}.png',"
f"'{current_time_str}','{channnel_id}');")
ret = myDBM.do_sql(strsql)
return ret

6
core/logs/2024-06-04.log

@ -1,6 +0,0 @@
2024-06-04_17:10:19-DBManager-ERROR:do_select异常报错:'DBManager' object has no attribute 'cursor'
2024-06-04_17:11:04-DBManager-ERROR:do_select异常报错:'DBManager' object has no attribute 'cursor'
2024-06-04_17:13:06-DBManager-ERROR:do_select异常报错:no such table: user
2024-06-04_17:20:58-DBManager-ERROR:do_select异常报错:no such table: user
2024-06-04_17:23:44-DBManager-ERROR:do_select异常报错:no such table: user
2024-06-04_17:25:04-DBManager-ERROR:do_select异常报错:no such table: user

1
core/logs/2024-06-09.log

@ -1 +0,0 @@
2024-06-09_11:44:21-DBManager-ERROR:do_select异常报错:SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 34308 and this is thread id 24980.

0
core/logs/2024-06-11.log

2
core/logs/2024-06-18.log

@ -1,2 +0,0 @@
2024-06-18_00:01:48-DBManager-ERROR:do_select异常报错:no such column: t1.id
2024-06-18_00:03:02-DBManager-ERROR:do_select异常报错:no such column: t1.id

257
core/logs/2024-06-19.log

@ -1,257 +0,0 @@
2024-06-19_15:55:26-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_15:56:52-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_15:56:54-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_15:56:55-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_15:58:23-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-19_16:06:41-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_16:06:41-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_16:06:41-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_16:06:41-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_16:06:41-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_16:06:41-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_16:10:31-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_16:10:31-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_16:10:31-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_16:10:31-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_16:10:31-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_16:10:31-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_16:23:41-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_16:23:41-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_16:23:41-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_17:48:41-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_17:48:41-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_17:48:41-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_17:48:45-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_17:48:45-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_17:48:45-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_18:00:03-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_18:00:03-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_18:00:03-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_18:00:06-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_18:00:06-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_18:00:06-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_21:47:07-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_21:47:07-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_21:47:07-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_21:47:22-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_21:47:22-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_21:47:22-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_21:50:54-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_21:50:54-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_21:50:54-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_21:50:58-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_21:50:58-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_21:50:58-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_21:52:41-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_21:52:41-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_21:52:41-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_21:52:45-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_21:52:45-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_21:52:45-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:00:09-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:00:09-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:00:09-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:00:12-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:00:12-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:00:12-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:03:44-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:03:44-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:03:44-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:03:47-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:03:47-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:03:47-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:05:40-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:05:40-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:05:40-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:05:43-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:05:43-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:05:43-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:06:01-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:06:01-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:06:01-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:06:04-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:06:04-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:06:04-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:08:14-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:08:14-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:08:14-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:08:18-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:08:18-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:08:18-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:22:23-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:22:23-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:22:23-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:22:28-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:22:28-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:22:28-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:23:20-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:23:20-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:23:20-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:23:25-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:23:25-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:23:25-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:24:02-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:24:02-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:24:02-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:24:05-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:24:05-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:24:05-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:29:54-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:29:54-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:29:54-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:29:58-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:29:58-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:29:58-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:30:03-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:30:03-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:30:03-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:30:08-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:30:08-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:30:08-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:31:09-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:31:09-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:31:09-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:31:14-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:31:14-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:31:14-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:32:15-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:32:15-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:32:15-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:32:19-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:32:19-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:32:19-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:39:04-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:39:04-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:39:04-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:39:08-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:39:08-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:39:08-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:39:08-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-19_22:43:38-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:43:38-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:43:38-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:43:42-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:43:42-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:43:42-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:44:23-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:44:23-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:44:23-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:44:27-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:44:27-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:44:27-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:48:34-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:48:34-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:48:34-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:48:38-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:48:38-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:48:38-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:53:01-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:53:01-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:53:01-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:53:05-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:53:05-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:53:05-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:53:05-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-19_22:54:13-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:54:13-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:54:13-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:54:17-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:54:17-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:54:17-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:55:47-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:55:47-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:55:47-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:55:50-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:55:50-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:55:50-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:57:37-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_22:57:37-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_22:57:37-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_22:57:42-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:57:42-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_22:57:42-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:03:45-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:03:45-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:03:45-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:03:50-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:03:50-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:03:50-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:05:20-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:05:20-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:05:20-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:05:24-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:05:24-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:05:24-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:06:00-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:06:00-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:06:00-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:06:04-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:06:04-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:06:04-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:13:23-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:13:23-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:13:23-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:13:26-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:13:26-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:13:26-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:17:58-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:17:58-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:17:58-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:18:02-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:18:02-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:18:02-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:19:22-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:19:22-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:19:22-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:19:26-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:19:26-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:19:26-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:19:34-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-19_23:19:52-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:19:52-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:19:52-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:19:55-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:19:55-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:19:55-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:21:17-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:21:17-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:21:17-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:21:20-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:21:20-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:21:20-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:25:28-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:25:28-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:25:28-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:25:32-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:25:32-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:25:32-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:26:17-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:26:17-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:26:17-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:26:20-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:26:20-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:26:20-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:27:27-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:27:27-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:27:27-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:27:30-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:27:30-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:27:30-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:28:32-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:28:32-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:28:32-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:28:36-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:28:36-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:28:36-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:30:48-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:30:48-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:30:48-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:30:53-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:30:53-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:30:53-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:33:00-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-19_23:33:00-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-19_23:33:00-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-19_23:33:04-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:33:04-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-19_23:33:04-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在

91
core/logs/2024-06-20.log

@ -1,91 +0,0 @@
2024-06-20_00:19:19-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_00:19:19-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_00:19:19-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_00:19:23-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_00:19:23-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_00:19:23-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_00:21:39-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_00:21:39-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_00:21:39-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_00:21:42-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_00:21:42-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_00:21:42-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_09:10:08-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_09:10:08-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_09:10:08-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_09:10:12-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_09:10:12-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_09:10:12-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_10:23:41-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_10:23:41-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_10:23:41-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_10:23:45-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_10:23:45-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_10:23:45-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_14:13:22-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_14:13:22-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_14:13:22-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_14:13:26-DBManager-ERROR:do_select异常报错:SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 14300 and this is thread id 10436.
2024-06-20_14:24:20-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_14:24:20-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_14:24:20-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_14:24:25-DBManager-ERROR:do_select异常报错:SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 24356 and this is thread id 28584.
2024-06-20_14:24:56-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_14:24:56-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_14:24:56-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_14:25:00-DBManager-ERROR:do_select异常报错:SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 5220 and this is thread id 14932.
2024-06-20_14:28:50-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_14:28:50-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_14:28:50-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_14:28:53-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_14:28:53-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_14:28:53-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_14:50:27-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_14:50:27-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_14:50:27-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_14:50:30-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_14:50:30-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_14:50:30-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_14:51:25-ModelManager-INFO:视频通道:3,未配置算法模块,结束线程!
2024-06-20_14:51:25-ModelManager-INFO:视频通道:4,未配置算法模块,结束线程!
2024-06-20_14:51:25-ModelManager-INFO:视频通道:5,未配置算法模块,结束线程!
2024-06-20_14:51:28-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_14:51:28-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_14:51:28-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_15:29:16-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_15:29:16-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_15:29:16-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_15:29:45-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:29:45-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:30:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:34:48-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:34:48-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:37:21-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:39:51-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:39:51-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:43:55-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:44:54-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:44:55-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:49:58-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:49:58-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:50:30-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:55:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:55:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_15:57:05-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:00:04-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:00:04-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:20:09-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:20:09-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:20:11-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_16:20:11-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_16:20:11-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_16:25:36-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:25:36-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:25:38-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_16:25:38-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_16:25:38-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_17:34:22-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:34:22-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:34:24-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_17:34:24-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-20_17:34:24-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在

3
core/logs/2024-06-24.log

@ -1,3 +0,0 @@
2024-06-24_10:41:16-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-24_10:41:16-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在
2024-06-24_10:41:16-ModelManager-ERROR:model/mode_test/yolov5s.pt文件不存在

4
logs/2024-05-25.log

@ -1,4 +0,0 @@
2024-05-25_09-59-06-INFO-main:info
2024-05-25_10:00:46-INFO-main:info
2024-05-25_10:17:32-main-INFO:info
2024-05-25_16:16:27-main-INFO:info

0
logs/2024-06-04.log

3
logs/2024-06-05.log

@ -1,3 +0,0 @@
2024-06-05_10:56:32-DBManager-ERROR:执行数据库语句INSERT INTO user (username ,password ,status,people,tellnum ) VALUES ('lisi','zfkj_123!@#',1,11,11)出错:'>' not supported between instances of 'sqlite3.Cursor' and 'int'
2024-06-05_10:58:37-DBManager-ERROR:执行数据库语句INSERT INTO user (username ,password ,status,people,tellnum ) VALUES ('wangliu','zfkj_123!@#',1,'11','11')出错:'>' not supported between instances of 'sqlite3.Cursor' and 'int'
2024-06-05_18:04:28-DBManager-ERROR:执行数据库语句update device set dev_ip='192.168.1.23',dev_mask='255.255.255.0',dev_gateway='192.168.1.1'出错:near ",dev_gateway": syntax error

0
logs/2024-06-07.log

6
logs/2024-06-08.log

@ -1,6 +0,0 @@
2024-06-08_15:56:44-DBManager-ERROR:执行数据库语句UPDATE SET channel area_id=1,channel_name='1',ulr='rtsp://11' where ID=1;出错:near "SET": syntax error
2024-06-08_15:58:30-DBManager-ERROR:执行数据库语句UPDATE channel SET area_id=1,channel_name='1',ulr='rtsp://11' where ID=1;出错:no such column: channel_name
2024-06-08_16:13:06-DBManager-ERROR:执行数据库语句delete channel where channel_id=1111;出错:near "channel": syntax error
2024-06-08_16:13:12-DBManager-ERROR:执行数据库语句delete channel where channel_id=1;出错:near "channel": syntax error
2024-06-08_16:14:36-DBManager-ERROR:执行数据库语句delete from channel where channel_id=1111;出错:no such column: channel_id
2024-06-08_16:14:51-DBManager-ERROR:执行数据库语句delete from channel where channel_id=1;出错:no such column: channel_id

0
logs/2024-06-09.log

4
logs/2024-06-10.log

@ -1,4 +0,0 @@
2024-06-10_22:46:09-DBManager-ERROR:do_select异常报错:near ";": syntax error
2024-06-10_22:47:03-DBManager-ERROR:do_select异常报错:near ";": syntax error
2024-06-10_22:47:09-DBManager-ERROR:do_select异常报错:no such column: channecl_id
2024-06-10_23:16:44-DBManager-ERROR:do_select异常报错:near ";": syntax error

5
logs/2024-06-11.log

@ -1,5 +0,0 @@
2024-06-11_00:11:54-DBManager-ERROR:执行数据库语句insert into schedule (channel_id,day,hour,status) values (1,星期日,0,1) on conflict(channel_id,day,hour) do update set status=excluded.status;出错:no such column: 星期日
2024-06-11_00:14:09-DBManager-ERROR:执行数据库语句insert into schedule (channel_id,day,hour,status) values (1,'星期日',0,1) on conflict(channel_id,day,hour) do update set status=excluded.status;出错:ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint
2024-06-11_17:01:36-DBManager-ERROR:do_select异常报错:no such column: t1.model_id
2024-06-11_17:02:18-DBManager-ERROR:do_select异常报错:no such column: t1.model_id
2024-06-11_21:10:48-DBManager-ERROR:do_select异常报错:near ";": syntax error

0
logs/2024-06-14.log

0
logs/2024-06-15.log

0
logs/2024-06-17.log

458
logs/2024-06-20.log

@ -1,458 +0,0 @@
2024-06-20_16:01:43-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:01:43-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:03:14-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:07:11-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:07:11-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:14:34-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:14:34-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:16:05-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:19:37-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:19:37-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:26:37-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:26:37-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:28:08-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:31:40-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:31:40-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:34:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:36:43-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:36:43-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:41:17-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:41:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:41:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:46:50-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:46:50-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:47:51-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:51:53-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:51:53-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:54:25-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:56:56-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_16:56:56-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:01:00-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:01:59-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:01:59-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:07:02-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:07:02-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:07:34-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:12:06-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:12:06-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:14:08-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:17:09-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:17:09-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:20:43-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:22:12-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:22:12-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:27:15-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:27:15-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:27:17-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:32:18-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:32:18-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:35:18-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:35:18-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:35:18-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:35:20-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:35:20-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:37:27-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:37:27-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:37:27-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:37:29-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:37:29-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:39:13-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:39:13-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:39:13-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:39:15-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:39:15-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:40:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:48:21-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:48:21-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:48:21-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_17:48:23-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:48:23-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:49:55-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:53:27-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:53:27-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:56:29-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:58:30-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_17:58:30-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_18:02:46-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_18:02:46-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_18:02:46-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_18:02:49-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_18:02:49-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_18:04:20-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_18:05:37-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_18:05:37-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_18:05:37-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_18:05:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_18:05:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_18:07:13-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:44:00-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:44:00-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:44:00-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:44:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:44:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:44:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:44:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:44:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:44:51-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:44:51-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:46:22-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:48:39-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:48:39-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:48:39-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:48:41-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:48:41-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:49:39-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:49:39-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:49:39-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:49:41-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:49:41-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:54:30-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:54:30-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:54:30-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:54:32-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:54:32-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:56:04-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:56:48-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:56:48-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:56:48-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_20:56:49-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_20:56:49-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:07:27-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:07:27-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:07:27-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:07:29-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:07:29-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:09:00-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:12:36-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:12:36-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:15:38-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:17:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:17:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:22:16-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:22:48-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:22:48-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:27:54-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:27:54-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:28:53-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:33:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:33:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:35:31-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:38:07-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:38:07-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:42:09-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:43:13-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:43:13-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:48:20-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:48:20-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:48:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:49:57-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:49:57-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:49:57-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:49:58-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:49:58-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:51:30-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:57:09-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:57:09-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:57:09-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:57:11-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:57:11-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:58:39-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:58:39-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:58:39-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_21:58:39-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_21:58:39-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:00:10-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:03:45-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:03:45-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:05:32-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:05:32-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:05:32-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:05:33-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:05:33-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:06:57-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:06:57-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:06:57-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:07:00-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:07:00-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:08:31-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:11:28-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:11:28-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:11:28-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:11:29-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:11:29-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:12:56-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:12:56-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:12:56-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:12:56-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:12:56-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:13:54-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:13:54-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:13:54-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:13:55-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:13:55-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:14:19-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:20-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:20-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:20-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:20-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:20-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:20-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:20-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:20-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:20-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:21-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:22-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:22-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:22-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:22-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:22-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:22-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:22-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:22-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:22-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:23-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:23-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:23-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:23-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:23-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:23-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:23-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:24-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:24-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:24-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:24-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:24-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:24-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:24-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:25-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:25-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:25-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:25-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:25-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:25-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:26-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:26-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:26-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:26-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:26-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:26-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:26-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:26-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:27-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:27-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:27-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:27-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:27-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:27-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:27-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:28-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:28-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:28-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:28-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:28-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:28-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:28-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:28-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:29-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:29-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:29-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:29-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:29-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:29-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:29-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:30-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:30-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:30-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:30-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:30-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:30-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:30-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:31-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:31-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:31-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:31-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:31-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:31-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:32-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:32-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:32-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:32-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:32-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:32-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:32-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:33-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:33-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:33-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:33-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:33-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:33-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:33-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:34-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:34-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:34-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:34-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:34-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:34-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:35-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:35-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:35-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:35-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:35-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:35-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:35-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:35-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:36-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:36-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:36-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:36-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:36-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:36-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:36-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:37-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:37-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:37-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:37-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:37-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:37-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:37-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:38-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:38-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:38-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:38-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:38-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:38-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:38-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:38-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:39-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:39-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:39-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:39-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:39-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:39-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:39-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:40-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:40-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:40-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:40-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:40-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:40-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:40-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:41-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:41-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:41-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:41-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:41-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:41-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:41-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:41-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:42-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:42-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:42-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:42-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:42-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:42-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:42-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:43-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:43-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:43-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:43-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:43-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:43-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:45-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:45-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:45-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:45-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:45-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:45-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:45-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:45-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:46-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:46-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:46-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:46-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:46-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:46-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:46-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:46-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:47-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:47-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:47-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:47-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:47-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:47-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:47-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:48-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:48-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:48-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:48-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:48-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:48-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:49-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:49-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:49-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:49-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:49-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:49-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:49-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:49-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:50-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:50-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:50-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:51-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:51-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:51-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:51-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:52-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:52-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:52-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:52-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:53-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:53-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:53-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:53-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:54-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:54-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:54-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:54-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:55-ModelManager-ERROR:img 是np.darry
2024-06-20_22:14:55-ModelManager-ERROR:img 是np.darry
2024-06-20_22:16:06-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:16:06-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:16:06-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:16:08-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:16:08-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:18:00-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:18:00-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:18:00-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:18:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:18:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:19:32-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:22:41-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:22:41-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:22:41-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:22:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:22:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:34:21-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:34:21-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:34:21-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:34:23-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:34:23-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:34:55-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:35:54-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:39:29-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:39:29-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:40:03-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:42:21-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:42:21-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:42:21-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-20_22:42:24-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-20_22:42:24-ModelManager-WARNING:view disconnected. Reconnecting...

356
logs/2024-06-21.log

@ -1,356 +0,0 @@
2024-06-21_09:49:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:49:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:49:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:49:51-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:49:51-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:51:23-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:53:25-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:53:25-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:53:25-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:53:26-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:53:26-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:54:57-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:55:22-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:55:22-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:55:22-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:55:22-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:55:22-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:56:59-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:56:59-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:56:59-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:57:00-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:57:00-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:58:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:58:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_09:58:49-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:58:49-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_09:58:49-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:00:17-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:03:52-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:03:52-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:06:54-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:08:58-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:08:58-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:17:36-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:17:36-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:17:38-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:17:38-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:17:38-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:19:07-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:22:40-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:22:40-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:25:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:27:43-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:27:43-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:32:16-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:32:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:32:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:34:50-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:34:50-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:34:52-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:34:52-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:34:52-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:36:21-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:38:44-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:38:44-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:38:45-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:38:45-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:38:45-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:40:15-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:43:48-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:43:48-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_10:43:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:43:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:43:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_10:45:19-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_11:15:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_11:15:46-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_11:15:48-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_11:15:48-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_11:15:48-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_11:17:17-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_11:18:33-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_11:18:33-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_11:18:34-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_11:18:34-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_11:18:34-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_11:20:04-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_11:21:51-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_11:21:51-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_11:21:53-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_11:21:53-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_11:21:53-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_12:35:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:35:42-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:35:45-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_12:35:45-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_12:35:45-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_12:37:13-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:40:45-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:40:45-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:43:48-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:45:49-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:45:49-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:50:22-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:50:52-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:50:52-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:55:55-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:55:55-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_12:56:56-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:00:58-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:00:58-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:03:30-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:06:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:06:01-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:10:05-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:11:05-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:11:05-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:16:08-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:16:08-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:16:39-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:21:11-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:21:11-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:23:13-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:26:14-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:26:14-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:29:47-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:31:17-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_13:31:17-ModelManager-WARNING:view disconnected. Reconnecting...
2024-06-21_14:45:48-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_14:45:48-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_14:45:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_14:45:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_14:45:50-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_14:47:19-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_15:25:11-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_15:25:12-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_15:25:14-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:25:14-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:25:14-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:25:43-ModelManager-WARNING:通道-2:view disconnected. Reconnecting...
2024-06-21_15:26:42-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_15:27:44-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_15:27:44-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_15:27:46-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:27:46-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:27:46-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:28:16-ModelManager-WARNING:通道-2:view disconnected. Reconnecting...
2024-06-21_15:29:15-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_15:32:47-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_15:32:47-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_15:35:50-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_15:37:51-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_15:37:51-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_15:43:49-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_15:43:49-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_15:43:51-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:43:51-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:43:51-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:45:20-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_15:46:00-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_15:46:00-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_15:46:01-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:46:01-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:46:01-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_15:47:31-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_16:34:33-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_16:34:33-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_16:34:33-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_16:34:34-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_16:34:34-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_16:36:05-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_16:37:11-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_16:37:11-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_16:37:11-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_16:37:17-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_16:37:47-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_16:38:49-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_16:42:29-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_16:42:59-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_16:45:32-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_16:47:41-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_16:48:11-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_16:52:16-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_16:52:54-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_16:53:24-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_16:58:06-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_16:58:36-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_16:58:59-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_17:03:18-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:03:48-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:05:43-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_17:08:30-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:09:00-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:12:26-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_17:13:43-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:14:13-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:18:55-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:19:10-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_17:19:25-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:23:06-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_17:23:06-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_17:23:06-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_17:23:30-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:23:30-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:25:01-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_17:29:01-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:29:01-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:32:02-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_17:34:31-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:34:31-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:39:03-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_17:40:02-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:40:02-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:45:32-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:45:32-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:46:05-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_17:51:03-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:51:03-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_17:53:06-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_17:56:33-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_17:56:33-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:00:07-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_18:02:04-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:02:04-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:07:09-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_18:07:34-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:07:34-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:13:09-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:13:09-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:14:10-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_18:18:39-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:18:39-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:21:11-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_18:24:10-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:24:10-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:28:13-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_18:29:41-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:29:41-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:35:11-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:35:11-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:35:14-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_18:40:42-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:40:42-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:42:15-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_18:46:12-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:46:12-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:49:17-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_18:51:43-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:51:43-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_18:56:18-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_18:57:13-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_18:57:13-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_19:02:44-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:02:44-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_19:03:19-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_19:08:14-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:08:14-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_19:10:21-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_19:13:45-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:13:45-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_19:17:22-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_19:19:15-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:19:15-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_19:24:23-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_19:24:46-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-21_19:24:46-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:26:01-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:26:01-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:26:01-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:26:24-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:27:55-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_19:29:07-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:29:07-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:29:07-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:30:48-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:30:48-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:30:48-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:31:13-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:32:25-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:32:25-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:32:25-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_19:32:49-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:34:20-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_19:38:20-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:41:22-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_19:43:51-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:48:23-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_19:49:21-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:54:52-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_19:55:24-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_20:00:22-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_20:02:26-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_20:05:53-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_20:09:27-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_20:11:23-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_20:40:58-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_20:40:58-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_20:40:58-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_20:41:22-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_20:42:53-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_20:44:45-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_20:44:45-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_20:44:45-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_20:45:10-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_20:45:42-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_20:45:42-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_20:45:42-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_20:46:06-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_20:47:37-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_20:51:37-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_20:54:38-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_20:57:07-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:01:40-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_21:02:38-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:08:08-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:08:41-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_21:13:39-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:15:42-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_21:19:09-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:22:44-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_21:24:40-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:29:45-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_21:30:10-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:35:45-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:36:46-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_21:41:16-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:43:48-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_21:46:46-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:50:49-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_21:52:17-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:57:47-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_21:57:51-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_22:03:18-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:04:52-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_22:08:49-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:11:53-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_22:14:19-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:18:54-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_22:19:50-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:25:20-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:25:56-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_22:30:51-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:32:57-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_22:36:21-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:39:58-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_22:41:52-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:47:00-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_22:47:22-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:53:00-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_22:54:01-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_22:58:31-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_23:01:03-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_23:04:01-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_23:08:04-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_23:09:32-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_23:15:02-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_23:15:05-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_23:20:33-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_23:22:06-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_23:26:03-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_23:29:08-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-21_23:31:34-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-21_23:58:14-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_23:58:14-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_23:58:14-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-21_23:59:09-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...

238
logs/2024-06-22.log

@ -1,238 +0,0 @@
2024-06-22_00:00:10-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:02:52-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:02:52-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:02:52-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:03:15-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:04:46-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:06:02-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:06:02-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:06:02-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:06:24-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:07:55-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:07:55-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:07:55-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:08:17-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:09:48-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:13:47-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:14:09-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:14:09-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:14:09-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_00:14:32-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:16:03-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:20:02-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:23:04-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:25:33-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:30:05-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:31:03-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:36:34-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:37:06-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:42:04-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:44:08-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:47:35-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:51:09-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:53:05-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_00:58:10-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_00:58:36-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:04:11-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:05:12-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_01:09:41-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:12:13-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_01:15:12-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:19:14-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_01:20:42-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:26:13-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:26:16-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_01:31:43-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:33:17-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_01:37:14-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:40:18-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_01:42:44-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:47:20-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_01:48:15-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:53:45-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_01:54:21-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_01:59:16-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:01:22-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_02:04:46-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:08:24-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_02:10:17-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:15:25-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_02:15:47-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:21:25-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:22:26-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_02:26:56-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:29:28-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_02:32:26-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:36:29-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_02:37:57-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:43:27-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:43:30-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_02:48:58-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:50:32-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_02:54:28-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_02:57:33-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_02:59:59-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:04:34-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_03:05:29-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:11:00-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:11:36-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_03:16:31-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:18:37-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_03:22:01-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:25:38-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_03:27:32-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:32:40-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_03:33:02-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:38:40-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:39:41-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_03:44:10-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:46:42-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_03:49:41-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_03:53:44-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_03:55:11-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:00:42-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:00:45-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_04:06:12-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:07:46-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_04:11:43-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:14:47-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_04:17:13-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:21:49-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_04:22:44-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:28:15-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:28:50-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_04:33:45-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:35:51-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_04:39:16-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:42:53-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_04:44:46-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:49:54-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_04:50:17-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:55:54-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_04:56:55-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_05:01:25-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:03:57-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_05:06:55-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:10:58-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_05:12:26-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:17:56-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:17:59-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_05:23:27-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:25:00-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_05:28:57-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:32:02-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_05:34:28-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:39:03-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_05:39:58-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:45:29-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:46:04-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_05:50:59-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_05:53:06-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_05:56:30-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:00:07-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_06:02:00-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:07:08-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_06:07:31-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:13:08-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:14:09-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_06:18:39-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:21:11-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_06:24:09-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:28:12-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_06:29:40-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:35:10-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:35:13-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_06:40:41-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:42:15-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_06:46:12-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:49:16-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_06:51:42-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_06:56:17-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_06:57:13-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:02:43-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:03:19-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_07:08:14-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:10:20-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_07:13:44-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:17:21-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_07:19:15-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:24:22-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_07:24:45-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:30:23-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:31:24-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_07:35:53-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:38:25-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_07:41:24-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:45:26-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_07:46:54-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:52:25-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:52:28-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_07:57:55-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_07:59:29-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_08:03:26-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:06:30-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_08:08:56-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:13:31-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_08:14:27-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:19:57-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:20:33-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_08:25:28-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:27:34-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_08:30:58-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:34:35-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_08:36:29-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:41:37-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_08:41:59-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:47:37-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:48:38-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_08:53:07-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_08:55:39-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_08:58:38-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:02:40-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_09:04:08-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:09:39-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:09:42-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_09:15:09-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:16:43-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_09:20:40-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:23:44-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_09:26:10-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:30:46-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_09:31:41-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:37:11-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:37:47-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_09:42:42-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:44:48-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_09:48:12-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:51:50-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_09:53:43-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_09:58:51-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_09:59:14-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_10:04:51-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_10:05:52-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_10:10:22-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_10:12:53-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_10:15:52-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_10:19:55-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_10:21:23-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_10:26:53-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_10:26:56-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_10:32:24-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_10:33:57-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_10:37:54-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_10:40:59-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_10:43:25-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_10:48:00-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_21:19:51-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_21:19:51-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_21:19:51-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_21:20:10-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_21:20:12-ModelManager-WARNING:通道-3:view disconnected. Reconnecting...
2024-06-22_21:20:40-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_21:20:40-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_21:20:40-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-22_21:21:01-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_21:22:32-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_21:26:31-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-22_21:29:34-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-22_21:32:02-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...

15
logs/2024-06-23.log

@ -1,15 +0,0 @@
2024-06-23_22:51:33-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-23_22:51:33-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-23_22:51:33-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-23_23:00:00-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-23_23:00:00-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-23_23:00:00-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-23_23:00:19-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-23_23:01:49-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-23_23:05:49-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-23_23:08:51-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-23_23:11:20-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-23_23:15:52-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-23_23:16:50-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-23_23:22:21-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-23_23:22:54-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...

190
logs/2024-06-24.log

@ -1,190 +0,0 @@
2024-06-24_15:28:34-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:28:34-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:28:34-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:29:30-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_15:30:11-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:30:11-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:30:11-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:30:36-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_15:32:07-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_15:36:06-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_15:38:40-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:38:40-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:38:40-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:39:37-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_15:40:38-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_15:44:59-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:44:59-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:44:59-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:45:16-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:45:16-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:45:16-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:45:41-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_15:47:12-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_15:51:11-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_15:52:18-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:52:18-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:52:18-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:52:43-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_15:54:26-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:54:26-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:54:26-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:54:51-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_15:56:22-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_15:58:13-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:58:13-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:58:13-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_15:58:37-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_16:00:07-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_16:04:07-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_16:07:11-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:07:11-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:07:11-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:07:34-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_16:09:05-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_16:14:10-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:14:10-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:14:10-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:14:36-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:14:36-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:14:36-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:14:53-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_16:16:24-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_16:18:14-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:18:14-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:18:14-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:19:10-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_16:34:32-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:34:32-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:34:32-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:34:57-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_16:36:28-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_16:51:01-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:51:01-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:51:01-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:51:26-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_16:51:56-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:51:56-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:51:56-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:52:52-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_16:53:15-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:53:15-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:53:15-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_16:53:39-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_16:55:10-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_16:59:09-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_17:04:25-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:04:25-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:04:25-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:05:21-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_17:06:22-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_17:10:52-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_17:13:24-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_17:16:22-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_17:20:25-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_17:21:53-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_17:31:10-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:31:10-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:31:10-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:31:35-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_17:33:47-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:33:47-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:33:47-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:34:32-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:34:32-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:34:32-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_17:34:37-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_17:36:09-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_17:39:50-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_17:42:52-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_17:45:02-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:08:47-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_18:08:47-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_18:08:47-ModelManager-ERROR:model/mode_test/yolov5s.pt 加载错误
2024-06-24_18:09:25-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:10:26-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_18:14:37-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:17:10-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_18:19:49-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:23:53-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_18:25:02-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:30:14-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:30:36-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_18:35:26-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:37:20-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_18:40:38-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:44:03-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_18:45:51-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:50:46-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_18:51:03-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:56:28-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_18:57:30-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:01:41-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:04:13-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:06:53-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:10:56-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:12:05-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:17:17-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:17:40-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:22:30-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:24:23-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:27:42-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:31:06-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:32:54-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:37:50-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:38:06-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:43:32-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:44:33-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:48:44-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:51:16-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:53:56-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_19:58:00-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_19:59:09-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:04:21-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:04:43-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_20:09:33-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:11:26-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_20:14:45-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:18:10-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_20:19:58-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:24:53-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_20:25:10-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:30:35-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:31:37-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_20:35:48-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:38:20-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_20:41:00-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:45:03-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_20:46:12-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:51:24-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:51:47-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_20:56:37-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_20:58:30-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:01:49-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:05:13-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:07:01-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:11:57-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:12:13-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:17:39-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:18:40-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:22:51-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:25:23-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:28:03-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:32:07-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:33:16-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:38:28-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:38:50-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:43:40-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:45:33-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:48:52-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:52:17-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:54:05-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_21:59:00-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_21:59:17-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_22:04:42-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_22:05:44-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_22:09:55-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_22:12:27-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_22:15:07-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...
2024-06-24_22:19:10-ModelManager-WARNING:通道-5:view disconnected. Reconnecting...
2024-06-24_22:20:19-ModelManager-WARNING:通道-4:view disconnected. Reconnecting...

4
logs/app.log

@ -1,4 +0,0 @@
2024-05-25T09:33:17.757522+0800-INFO-main:111
2024-05-25T09:41:26.638770+0800-INFO-main:info
2024-05-25T09:44:17.514570+0800-INFO-main:info
2024-05-25T09:45:10.481132+0800-INFO-main:info

204
model/ModelManager.py

@ -1,204 +0,0 @@
import torch
import cv2
import numpy as np
import torch
import os
import importlib
from model.plugins.ModelBase import ModelBase
from loguru import logger
'''
class ModelManager_tmp():
def __init__(self):
print("ModelInit")
def __del__(self):
print("ModelManager DEL")
def __preprocess_image(self,image, cfg, bgr2rgb=True):
"""图片预处理"""
img, scale_ratio, pad_size = letterbox(image, new_shape=cfg['input_shape'])
if bgr2rgb:
img = img[:, :, ::-1]
img = img.transpose(2, 0, 1) # HWC2CHW
img = np.ascontiguousarray(img, dtype=np.float32)
return img, scale_ratio, pad_size
def __draw_bbox(self,bbox, img0, color, wt, names):
"""在图片上画预测框"""
det_result_str = ''
for idx, class_id in enumerate(bbox[:, 5]):
if float(bbox[idx][4] < float(0.05)):
continue
img0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])),
color, wt)
img0 = cv2.putText(img0, str(idx) + ' ' + names[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] + 16)),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
img0 = cv2.putText(img0, '{:.4f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] + 32)),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
det_result_str += '{} {} {} {} {} {}\n'.format(
names[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3])
return img0
def __get_labels_from_txt(self,path):
"""从txt文件获取图片标签"""
labels_dict = dict()
with open(path) as f:
for cat_id, label in enumerate(f.readlines()):
labels_dict[cat_id] = label.strip()
return labels_dict
def __draw_prediction(self,pred, image, labels):
"""在图片上画出预测框并进行可视化展示"""
imgbox = widgets.Image(format='jpg', height=720, width=1280)
img_dw = self.__draw_bbox(pred, image, (0, 255, 0), 2, labels)
imgbox.value = cv2.imencode('.jpg', img_dw)[1].tobytes()
display(imgbox)
def __infer_image(self,img_path, model, class_names, cfg):
"""图片推理"""
# 图片载入
image = cv2.imread(img_path)
# 数据预处理
img, scale_ratio, pad_size = self.__preprocess_image(image, cfg)
# 模型推理
output = model.infer([img])[0]
output = torch.tensor(output)
# 非极大值抑制后处理
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])
pred_all = boxout[0].numpy()
# 预测坐标转换
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size))
# 图片预测结果可视化
self.__draw_prediction(pred_all, image, class_names)
def __infer_frame_with_vis(self,image, model, labels_dict, cfg, bgr2rgb=True):
# 数据预处理
img, scale_ratio, pad_size = self.__preprocess_image(image, cfg, bgr2rgb)
# 模型推理
output = model.infer([img])[0]
output = torch.tensor(output)
# 非极大值抑制后处理
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])
pred_all = boxout[0].numpy()
# 预测坐标转换
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size))
# 图片预测结果可视化
img_vis = self.__draw_bbox(pred_all, image, (0, 255, 0), 2, labels_dict)
return img_vis
def __img2bytes(self,image):
"""将图片转换为字节码"""
return bytes(cv2.imencode('.jpg', image)[1])
def __infer_camera(self,model, labels_dict, cfg):
"""外设摄像头实时推理"""
def find_camera_index():
max_index_to_check = 10 # Maximum index to check for camera
for index in range(max_index_to_check):
cap = cv2.VideoCapture(index)
if cap.read()[0]:
cap.release()
return index
# If no camera is found
raise ValueError("No camera found.")
# 获取摄像头 --这里可以换成RTSP流
camera_index = find_camera_index()
cap = cv2.VideoCapture(camera_index)
# 初始化可视化对象
image_widget = widgets.Image(format='jpeg', width=1280, height=720)
display(image_widget)
while True:
# 对摄像头每一帧进行推理和可视化
_, img_frame = cap.read()
image_pred = self.__infer_frame_with_vis(img_frame, model, labels_dict, cfg)
image_widget.value = self.__img2bytes(image_pred)
def __infer_video(self,video_path, model, labels_dict, cfg):
"""视频推理"""
image_widget = widgets.Image(format='jpeg', width=800, height=600)
display(image_widget)
# 读入视频
cap = cv2.VideoCapture(video_path)
while True:
ret, img_frame = cap.read()
if not ret:
break
# 对视频帧进行推理
image_pred = self.__infer_frame_with_vis(img_frame, model, labels_dict, cfg, bgr2rgb=True)
image_widget.value = self.__img2bytes(image_pred)
def startWork(self,infer_mode,file_paht = ""):
cfg = {
'conf_thres': 0.4, # 模型置信度阈值,阈值越低,得到的预测框越多
'iou_thres': 0.5, # IOU阈值,高于这个阈值的重叠预测框会被过滤掉
'input_shape': [640, 640], # 模型输入尺寸
}
model_path = 'yolo.om'
label_path = './coco_names.txt'
# 初始化推理模型
model = InferSession(0, model_path)
labels_dict = self.__get_labels_from_txt(label_path)
#执行验证
if infer_mode == 'image':
img_path = 'world_cup.jpg'
self.__infer_image(img_path, model, labels_dict, cfg)
elif infer_mode == 'camera':
self.__infer_camera(model, labels_dict, cfg)
elif infer_mode == 'video':
video_path = 'racing.mp4'
self.__infer_video(video_path, model, labels_dict, cfg)
'''
'''
算法实现类实现算法执行线程根据配内容以线程方式执行算法模块
'''
class ModelManager():
def __init__(self):
print("ModelManager init")
def __del__(self):
print("ModelManager del")
def doWork(self):
pass
#动态导入文件 -- 方法二 -- 相对推荐使用该方法 但spec感觉没什么用
def import_source(spec, plgpath):
module = None
if os.path.exists(plgpath):
module_spec = importlib.util.spec_from_file_location(spec, plgpath)
module = importlib.util.module_from_spec(module_spec)
module_spec.loader.exec_module(module)
else:
logger.error("{}文件不存在".format(plgpath))
return module
#plgpath 为list [poc][file_name][name]
def run_plugin(plgpath, target,copy_flag=True):
module = import_source("", plgpath)
if module:
classname = "Model"
plg = getattr(module, classname)()
if not isinstance(plg, ModelBase):
raise Exception("{} not rx_Model".format(plg))
new_plg = plg
result = new_plg.doWork("","","","") # 执行plugin基类的run, 返回结果
return result
else:
print("模型加载失败")
return None
def test():
run_plugin("plugins/RYRQ_Model_ACL.py","")
if __name__ == "__main__":
test()

9
model/base_model/ascnedcl/classes.py

@ -0,0 +1,9 @@
CLASSES = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
'hair drier', 'toothbrush']

54
model/base_model/ascnedcl/det_utils.py

@ -55,6 +55,7 @@ def letterbox(img, new_shape=(640, 640), color=(114, 114, 114), auto=False, scal
return img, ratio, (dw, dh)
def non_max_suppression(
prediction,
conf_thres=0.25,
@ -63,7 +64,7 @@ def non_max_suppression(
agnostic=False,
multi_label=False,
labels=(),
max_det=300,
max_det=100, #每张图片最低暴力的检测框数量,原本是300,
nm=0, # number of masks
):
"""Non-Maximum Suppression (NMS) on inference results to reject overlapping detections
@ -71,19 +72,21 @@ def non_max_suppression(
Returns:
list of detections, on (n,6) tensor per image [xyxy, conf, cls]
"""
#判断并获取预测结果:如果 prediction 是列表或元组,选择其中的第一个元素作为模型预测输出
if isinstance(prediction, (list, tuple)): # YOLOv5 model in validation model, output = (inference_out, loss_out)
prediction = prediction[0] # select only inference output
#设备检测:检测当前运行设备是否为 Apple MPS,如果是则将预测结果转换为 CPU 进行处理,因为 MPS 尚不完全支持 NMS。
device = prediction.device
mps = 'mps' in device.type # Apple MPS
if mps: # MPS not fully supported yet, convert tensors to CPU before NMS
prediction = prediction.cpu()
# mps = 'mps' in device.type # Apple MPS
# if mps: # MPS not fully supported yet, convert tensors to CPU before NMS
# prediction = prediction.cpu()
#获取批量大小和类数量:bs 表示批量大小,nc 表示类的数量,xc 表示通过置信度阈值的候选框。
bs = prediction.shape[0] # batch size
nc = prediction.shape[2] - nm - 5 # number of classes
xc = prediction[..., 4] > conf_thres # candidates
# Checks
# Checks 参数检查:确保 conf_thres 和 iou_thres 在有效范围内。
assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0'
assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0'
@ -92,17 +95,21 @@ def non_max_suppression(
max_wh = 7680 # (pixels) maximum box width and height
max_nms = 30000 # maximum number of boxes into torchvision.ops.nms()
time_limit = 0.5 + 0.05 * bs # seconds to quit after
multi_label &= nc > 1 # multiple labels per box (adds 0.5ms/img)
multi_label &= nc > 1 # multiple labels per box (adds 0.5ms/img) 如果 nc > 1,则允许每个框有多个标签
#初始化:记录当前时间用于后续的时间限制,mi 表示掩码索引的起始位置,
t = time.time()
mi = 5 + nc # mask start index
output = [torch.zeros((0, 6 + nm), device=prediction.device)] * bs
# output 初始化为一个批次大小的空列表,每个元素是形状为 (0, 6 + nm) 的零张量。
output = [torch.zeros((0, 6 + nm), device=device)] * bs
#逐图像处理:遍历批量中的每一张图像,只保留通过置信度筛选的框
for xi, x in enumerate(prediction): # image index, image inference
# Apply constraints
# x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0 # width-height
x = x[xc[xi]] # confidence
# Cat apriori labels if autolabelling
# Cat apriori labels if autolabelling 自动标签:如果存在标签,按照标签信息构建一个新的检测框,并将其与原有的检测框拼接
if labels and len(labels[xi]):
lb = labels[xi]
v = torch.zeros((len(lb), nc + nm + 5), device=x.device)
@ -110,31 +117,32 @@ def non_max_suppression(
v[:, 4] = 1.0 # conf
v[range(len(lb)), lb[:, 0].long() + 5] = 1.0 # cls
x = torch.cat((x, v), 0)
del v
# If none remain process next image
# If none remain process next image 空检测处理:如果没有剩余检测框,则跳过该图像
if not x.shape[0]:
continue
# Compute conf
# Compute conf 置信度计算:更新置信度,x[:, 5:] 乘以 x[:, 4:5],即置信度等于目标置信度乘以类别置信度
x[:, 5:] *= x[:, 4:5] # conf = obj_conf * cls_conf
# Box/Mask
# Box/Mask 转换框坐标:将框坐标从中心点格式转换为左上角和右下角格式,并获取掩码信息(如果存在)。
box = xywh2xyxy(x[:, :4]) # center_x, center_y, width, height) to (x1, y1, x2, y2)
mask = x[:, mi:] # zero columns if no masks
# Detections matrix nx6 (xyxy, conf, cls)
if multi_label:
if multi_label: #如果允许多标签,选择所有符合阈值的类标签。
i, j = (x[:, 5:mi] > conf_thres).nonzero(as_tuple=False).T
x = torch.cat((box[i], x[i, 5 + j, None], j[:, None].float(), mask[i]), 1)
else: # best class only
else: # best class only 只选择置信度最高的标签。
conf, j = x[:, 5:mi].max(1, keepdim=True)
x = torch.cat((box, conf, j.float(), mask), 1)[conf.view(-1) > conf_thres]
# Filter by class
# Filter by class 按类过滤:如果指定了 classes,则只保留属于这些类的检测框
if classes is not None:
x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)]
# Check shape
# Check shape 如果检测框超过 max_nms,则按置信度排序后只保留前 max_nms 个框
n = x.shape[0] # number of boxes
if not n: # no boxes
continue
@ -143,20 +151,24 @@ def non_max_suppression(
else:
x = x[x[:, 4].argsort(descending=True)] # sort by confidence
# Batched NMS
# Batched NMS 根据类偏移框坐标,对每个类进行非极大值抑制,保留 max_det 个检测框。
c = x[:, 5:6] * (0 if agnostic else max_wh) # classes
boxes, scores = x[:, :4] + c, x[:, 4] # boxes (offset by class), scores
i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS
if i.shape[0] > max_det: # limit detections
i = i[:max_det]
#输出结果:将NMS后的结果保存到 output 中,如果超时则打印警告并终止处理
output[xi] = x[i]
if mps:
output[xi] = output[xi].to(device)
# if mps:
# output[xi] = output[xi].to(device)
if (time.time() - t) > time_limit:
print(f'WARNING ⚠️ NMS time limit {time_limit:.3f}s exceeded')
del c,x,box,mask
break # time limit exceeded
del c, x, box, mask
del device,bs,nc,xc
del prediction
return output

107
model/base_model/ascnedcl/det_utils_v10.py

@ -0,0 +1,107 @@
import cv2
import numpy as np
from model.base_model.ascnedcl.classes import CLASSES
def letterbox(img, new_shape=(640, 640), auto=False, scaleFill=False, scaleup=True, center=True, stride=32):
# Resize and pad image while meeting stride-multiple constraints
shape = img.shape[:2] # current shape [height, width]
if isinstance(new_shape, int):
new_shape = (new_shape, new_shape)
# Scale ratio (new / old)
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
if not scaleup: # only scale down, do not scale up (for better val mAP)
r = min(r, 1.0)
# Compute padding
ratio = r, r # width, height ratios
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding
if auto: # minimum rectangle
dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding
elif scaleFill: # stretch
dw, dh = 0.0, 0.0
new_unpad = (new_shape[1], new_shape[0])
ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios
if center:
dw /= 2 # divide padding into 2 sides
dh /= 2
if shape[::-1] != new_unpad: # resize
img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
top, bottom = int(round(dh - 0.1)) if center else 0, int(round(dh + 0.1))
left, right = int(round(dw - 0.1)) if center else 0, int(round(dw + 0.1))
img = cv2.copyMakeBorder(
img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(114, 114, 114)
) # add border
return img, ratio, dw, dh
def non_max_suppression_v10(prediction,conf_thres,ratio,dw,dh):
result = []
for i in range(prediction.shape[0]):
data = prediction[i]
# 读取类别置信度
confidence = data[4]
# 用阈值进行过滤
if confidence > conf_thres:
# 读取类别索引
label = int(data[5])
# 读取类坐标值,把坐标还原到原始图像
xmin = int((data[0] - int(round(dw - 0.1))) / ratio[0])
ymin = int((data[1] - int(round(dh - 0.1))) / ratio[1])
xmax = int((data[2] - int(round(dw + 0.1))) / ratio[0])
ymax = int((data[3] - int(round(dh + 0.1))) / ratio[1])
result.append([xmin, ymin, xmax, ymax, confidence, label])
return result
def draw_bbox_old(bbox, img0, color, wt):
det_result_str = ''
for idx, class_id in enumerate(bbox[:, 5]):
if float(bbox[idx][4] < float(0.05)):
continue
img0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])), color, wt)
img0 = cv2.putText(img0, str(idx) + ' ' + CLASSES[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] + 16)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
img0 = cv2.putText(img0, '{:.4f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] + 32)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
det_result_str += '{} {} {} {} {} {}\n'.format(CLASSES[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3])
return img0
def draw_box(img,
box, # [xmin, ymin, xmax, ymax]
score,
class_id):
'''Draws a bounding box on the image'''
# Retrieve the color for the class ID
color_palette = np.random.uniform(0, 255, size=(len(CLASSES), 3))
color = color_palette[class_id]
# Draw the bounding box on the image
cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), color, 2)
# Create the label text with class name and score
label = f'{CLASSES[class_id]}: {score:.2f}'
# Calculate the dimensions of the label text
(label_width, label_height), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
# Calculate the position of the label text
label_x = box[0]
label_y = box[1] - 10 if box[1] - 10 > label_height else box[1] + 10
# Draw a filled rectangle as the background for the label text
cv2.rectangle(
img,
(int(label_x), int(label_y - label_height)),
(int(label_x + label_width), int(label_y + label_height)),
color,
cv2.FILLED,
)
# Draw the label text on the image
cv2.putText(img, label, (int(label_x), int(label_y)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
return img

9
model/plugins/AQM_Model.py

@ -1,9 +0,0 @@
from model.plugins.ModelBase import ModelBase
class Model(ModelBase):
def __init__(self):
super().__init__()
pass
def doWork(self,image,mode,class_name,cfg,isdraw_box=False,bgr2rgb=True):
print("AQM_Model")

98
model/plugins/ModelBase.py

@ -22,9 +22,19 @@ class ModelBase(ABC):
:param threshold: 模型的置信阈值
'''
self.mylogger = LogHandler().get_logger("ModelManager")
self.platform = myCongif.get_data("model_platform")
self.name = None #基于name来查询,用户对模型的配置参数,代表着模型名称需要唯一 2024-6-18 -逻辑还需要完善和验证
self.version = None
self.model_type = None # 模型类型 1-图像分类,2-目标检测(yolov5),3-分割模型,4-关键点
self.model_id = None # 模型 id
self.input_dataset = None # 输入数据结构
self.output_dataset = None # 输出数据结构
self.model_desc = None # 模型描述信息
self._input_num = 0 # 输入数据个数
self._output_num = 0 # 输出数据个数
self._output_info = [] # 输出信息列表
self._is_released = True # 资源是否被释放
self.polygon = None #检测区域
self.system = myCongif.get_data("model_platform") #platform.system() #获取系统平台
self.do_map = { # 定义插件的入口函数 --
# POCType.POC: self.do_verify,
@ -32,17 +42,27 @@ class ModelBase(ABC):
# POCType.BRUTE: self.do_brute
}
self.model_path = path # 模型路径
self.init_ok = False
#self.init_ok = False
#---------------------------
#加载ACL模型文件---模型加载、模型执行、模型卸载的操作必须在同一个Context下
# if self.platform == 'acl':
# if self.init_acl_resource(): # 加载离线模型,创建输出缓冲区
# print("加载模型文件成功!")
# self.init_ok = True
# self._is_released = False # 资源是否被释放
# else: #其他平台暂时不需要额外初始化内容
# self.init_ok = True
def __del__(self):
print("资源释放")
# 卸载ACL模型文件
self.release()
def draw_polygon(self, img, polygon_points,color=(0, 255, 0)):
self.polygon = Polygon(ast.literal_eval(polygon_points))
points = np.array([self.polygon.exterior.coords], dtype=np.int32)
cv2.polylines(img, points, isClosed=True, color=color, thickness=2)
if polygon_points and polygon_points.strip():
self.polygon = Polygon(ast.literal_eval(polygon_points))
points = np.array([self.polygon.exterior.coords], dtype=np.int32)
cv2.polylines(img, points, isClosed=True, color=color, thickness=2)
def is_point_in_region(self, point):
'''判断点是否在区域内,需要先执行draw_polygon'''
@ -52,24 +72,23 @@ class ModelBase(ABC):
return False
#acl ----- 相关-----
def _init_acl(self):
device_id = 0
self.context, ret = acl.rt.create_context(device_id) # 显式创建一个Context
if ret:
raise RuntimeError(ret)
print('Init TH-Context Successfully')
# def _init_acl(self):
# device_id = 0
# self.context, ret = acl.rt.create_context(device_id) # 显式创建一个Context
# if ret:
# raise RuntimeError(ret)
# print('Init TH-Context Successfully')
def _del_acl(self):
device_id = 0
# 线程释放context
ret = acl.rt.destroy_context(self.context) # 释放 Context
if ret:
raise RuntimeError(ret)
print('Deinit TH-Context Successfully')
print('ACL finalize Successfully')
# def _del_acl(self):
# device_id = 0
# # 线程释放context
# ret = acl.rt.destroy_context(self.context) # 释放 Context
# if ret:
# raise RuntimeError(ret)
# print('Deinit TH-Context Successfully')
# print('ACL finalize Successfully')
def _init_resource(self):
#self._init_acl() #测试使用
def init_acl_resource(self):
''' 初始化模型、输出相关资源。相关数据类型: aclmdlDesc aclDataBuffer aclmdlDataset'''
print("Init model resource")
# 加载模型文件
@ -79,6 +98,10 @@ class ModelBase(ABC):
print(f"{self.model_path}---模型加载失败!")
return False
self.model_desc = acl.mdl.create_desc() # 初始化模型信息对象
if not self.model_desc:
return False
#(例如输入/输出的个数、名称、数据类型、Format、维度信息等)
ret = acl.mdl.get_desc(self.model_desc, self.model_id) # 根据模型ID获取该模型的aclmdlDesc类型数据(描述信息)
print("[Model] Model init resource stage success")
# 创建模型输出 dataset 结构
@ -86,6 +109,7 @@ class ModelBase(ABC):
if ret !=0:
print("[Model] create model output dataset fail")
return False
self._is_released = False # 资源是否被释放
return True
def _gen_output_dataset(self):
@ -112,14 +136,17 @@ class ModelBase(ABC):
self._input_num = acl.mdl.get_num_inputs(self.model_desc) # 获取模型输入个数
self.input_dataset = acl.mdl.create_dataset() # 创建输入dataset结构
for i in range(self._input_num):
item = input_list[i] # 获取第 i 个输入数据
item = input_list[i] # 获取第 i 个输入数据 --#?这里输入个数和input_list的个数是一一对应的? 还是默认只有一个输入
data_ptr = acl.util.bytes_to_ptr(item.tobytes()) # 获取输入数据字节流
size = item.size * item.itemsize # 获取输入数据字节数
#这里没有调用acl.rt.malloc 申请内存 后续需要跟进对比下。#?
dataset_buffer = acl.create_data_buffer(data_ptr, size) # 创建输入dataset buffer结构, 填入输入数据
_, ret = acl.mdl.add_dataset_buffer(self.input_dataset, dataset_buffer) # 将dataset buffer加入dataset
if ret == FAILED:
self._release_dataset(self.input_dataset) # 失败时释放dataset
self.input_dataset = None
return ret
#print("[Model] create model input dataset success")
def _unpack_bytes_array(self, byte_array, shape, datatype):
@ -171,14 +198,19 @@ class ModelBase(ABC):
def execute(self, input_list):
'''创建输入dataset对象, 推理完成后, 将输出数据转换为numpy格式'''
self._gen_input_dataset(input_list) # 创建模型输入dataset结构
ret = self._gen_input_dataset(input_list) # 创建模型输入dataset结构
if ret == FAILED:
self.mylogger.error(f"_gen_input_dataset fail!--{ret}")
return None
ret = acl.mdl.execute(self.model_id, self.input_dataset, self.output_dataset) # 调用离线模型的execute推理数据
if ret:
self.mylogger.error(f"acl.mdl.execute fail!--{ret}")
self._release_dataset(self.input_dataset) # 失败时释放dataset --创建输入空间失败时会释放。
self.input_dataset = None
return None
out_numpy = self._output_dataset_to_numpy() # 将推理输出的二进制数据流解码为numpy数组, 数组的shape和类型与模型输出规格一致
self._release_dataset(self.input_dataset) # 释放dataset -- 要不要执行需要验证
self.input_dataset = None
return out_numpy
def release(self):
@ -187,10 +219,12 @@ class ModelBase(ABC):
return
print("Model start release...")
self._release_dataset(self.input_dataset) # 释放输入数据结构
self.input_dataset = None # 将输入数据置空
self._release_dataset(self.output_dataset) # 释放输出数据结构
self.output_dataset = None # 将输出数据置空
if self.input_dataset:
self._release_dataset(self.input_dataset) # 释放输入数据结构
self.input_dataset = None # 将输入数据置空
if self.output_dataset:
self._release_dataset(self.output_dataset) # 释放输出数据结构
self.output_dataset = None # 将输出数据置空
if self.model_id:
ret = acl.mdl.unload(self.model_id) # 卸载模型
@ -225,4 +259,12 @@ class ModelBase(ABC):
:param isdraw: 是否需要绘制线框0-不绘制1-绘制
:return: detections,bwarn,warntext bwarn:0-没有识别到符合要求的目标1-没有识别到符合要求的目标
'''
pass
@abstractmethod
def prework(self,image):
pass
@abstractmethod
def postwork(self,image,outputs,scale_ratio,pad_size,check_area,polygon,conf_threshold,iou_thres):
pass

76
model/plugins/Peo_ACL/Peo_Model_ACL.py

@ -0,0 +1,76 @@
import os.path
from model.plugins.ModelBase import ModelBase
from myutils.ConfigManager import myCongif
from model.base_model.ascnedcl.det_utils import get_labels_from_txt, letterbox, scale_coords, nms, draw_bbox # 模型前后处理相关函数
import cv2
import numpy as np
import torch # 深度学习运算框架,此处主要用来处理数据
from core.ACLModelManager import ACLModeManger
class Model(ModelBase):
def __init__(self,path,threshold=0.5):
# 找pt模型路径 -- 一个约束py文件和模型文件的路径关系需要固定, -- 上传模型时,要解压好路径
dirpath, filename = os.path.split(path)
self.model_file = os.path.join(dirpath, "yolov5s_bs1.om") # 目前约束模型文件和py文件在同一目录
#self.coco_file = os.path.join(dirpath, "coco_names.txt")
super().__init__(self.model_file) # acl环境初始化基类负责类的实例化
self.name = "人员模型-yolov5"
self.version = "V1.0"
self.model_type = 2
self.neth = 640 # 缩放的目标高度, 也即模型的输入高度
self.netw = 640 # 缩放的目标宽度, 也即模型的输入宽度
self.conf_threshold = threshold # 置信度阈值
def verify(self,image,data,isdraw=1):
labels_dict = get_labels_from_txt('/mnt/zfbox/model/plugins/RYRQ_ACL/coco_names.txt') # 得到类别信息,返回序号与类别对应的字典
# 数据前处理
img, scale_ratio, pad_size = letterbox(image, new_shape=[640, 640]) # 对图像进行缩放与填充
img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, HWC to CHW #图片在输入时已经做了转换
img = np.ascontiguousarray(img, dtype=np.float32) / 255.0 # 转换为内存连续存储的数组
# 模型推理, 得到模型输出
outputs = None
outputs = self.execute([img,])#创建input,执行模型,返回结果 --失败返回None
filtered_pred_all = None
bwarn = False
warn_text = ""
# 是否有检测区域,有先绘制检测区域 由于在该函数生成了polygon对象,所有需要在检测区域前调用。
if data[1] == 1:
self.draw_polygon(image, data[2], (255, 0, 0))
if outputs:
output = outputs[0] #只放了一张图片
# 后处理 -- boxout 是 tensor-list: [tensor([[],[].[]])] --[x1,y1,x2,y2,置信度,coco_index]
boxout = nms(torch.tensor(output), conf_thres=0.3,
iou_thres=0.5) # 利用非极大值抑制处理模型输出,conf_thres 为置信度阈值,iou_thres 为iou阈值
pred_all = boxout[0].numpy() # 转换为numpy数组 -- [[],[],[]] --[x1,y1,x2,y2,置信度,coco_index]
# pred_all[:, :4] 取所有行的前4列,pred_all[:,1]--第一列
scale_coords([640, 640], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size)) # 将推理结果缩放到原始图片大小
#过滤掉不是目标标签的数据 -- 序号0-- person
filtered_pred_all = pred_all[pred_all[:, 5] == 0]
# 绘制检测结果 --- 也需要封装在类里,
for pred in filtered_pred_all:
x1, y1, x2, y2 = int(pred[0]), int(pred[1]), int(pred[2]), int(pred[3])
# # 绘制目标识别的锚框 --已经在draw_bbox里处理
# cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
if data[1] == 1: # 指定了检测区域
x_center = (x1 + x2) / 2
y_center = (y1 + y2) / 2
#绘制中心点?
cv2.circle(image, (int(x_center), int(y_center)), 5, (0, 0, 255), -1)
#判断是否区域点
if not self.is_point_in_region((x_center, y_center)):
continue #没产生报警-继续
#产生报警 -- 有一个符合即可
bwarn = True
warn_text = "People checked!"
img_dw = draw_bbox(filtered_pred_all, image, (0, 255, 0), 2, labels_dict) # 画出检测框、类别、概率
#cv2.imwrite('img_res_peo.png', image)
return filtered_pred_all, bwarn, warn_text
def testRun(self):
print("1111")

BIN
model/plugins/Peo_ACL/people.om

Binary file not shown.

BIN
model/plugins/Peo_ACL/yolov5s_bs1.om

Binary file not shown.

8
model/plugins/RYRQ/RYRQ_Model.py

@ -17,10 +17,10 @@ class Model(ModelBase):
self.version = "V1.0"
self.model_type = 2
#实例化模型--实例化模型没有对失败的情况进行处理
self.init_ok = True
self.model = torch.hub.load(yolov5_path, 'custom', path=model_file, source='local')
#if model 失败,inti_ok = Flase
# #实例化模型--实例化模型没有对失败的情况进行处理
# self.init_ok = True
# self.model = torch.hub.load(yolov5_path, 'custom', path=model_file, source='local')
# #if model 失败,inti_ok = Flase
def verify(self,image,data,isdraw=1):

110
model/plugins/RYRQ_ACL/RYRQ_Model_ACL.py

@ -1,46 +1,92 @@
import os.path
from model.plugins.ModelBase import ModelBase
from myutils.ConfigManager import myCongif
from model.base_model.ascnedcl.det_utils import get_labels_from_txt, letterbox, scale_coords, nms, draw_bbox # 模型前后处理相关函数
import cv2
import numpy as np
import torch # 深度学习运算框架,此处主要用来处理数据
from core.ACLModelManager import ACLModeManger
class Model(ModelBase):
def __init__(self,path,threshold=0.5):
def __init__(self,path,threshold=0.5,iou_thres=0.5):
# 找pt模型路径 -- 一个约束py文件和模型文件的路径关系需要固定, -- 上传模型时,要解压好路径
dirpath, filename = os.path.split(path)
self.model_file = os.path.join(dirpath, "yolov5s_bs1.om") # 目前约束模型文件和py文件在同一目录
self.coco_file = os.path.join(dirpath, "coco_names.txt")
super().__init__(self.model_file) #acl环境初始化基类负责类的实例化
self.model_id = None # 模型 id
self.input_dataset = None # 输入数据结构
self.output_dataset = None # 输出数据结构
self.model_desc = None # 模型描述信息
self._input_num = 0 # 输入数据个数
self._output_num = 0 # 输出数据个数
self._output_info = [] # 输出信息列表
self._is_released = False # 资源是否被释放
self.labels_dict = get_labels_from_txt(self.coco_file) # 得到类别信息,返回序号与类别对应的字典
super().__init__(self.model_file) # acl环境初始化基类负责类的实例化
self.name = "人员入侵-yolov5"
self.version = "V1.0"
self.model_type = 2
self.neth = 640 # 缩放的目标高度, 也即模型的输入高度
self.netw = 640 # 缩放的目标宽度, 也即模型的输入宽度
self.conf_threshold = threshold # 置信度阈值
#加载ACL模型文件---模型加载、模型执行、模型卸载的操作必须在同一个Context下
if self._init_resource(): #加载离线模型,创建输出缓冲区
print("加载模型文件成功!")
self.init_ok = True
# self.conf_threshold = threshold # 置信度阈值
# self.iou_thres = iou_thres #IOU阈值
def prework(self,image):
'''模型输入图片数据前处理 --- 针对每个模型特有的预处理内容 -'''
img, scale_ratio, pad_size = letterbox(image, new_shape=[640, 640]) # 对图像进行缩放与填充
img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, HWC to CHW #图片在输入时已经做了转换
img = np.ascontiguousarray(img, dtype=np.float32) / 255.0 # 转换为内存连续存储的数组
return img,scale_ratio, pad_size
def __del__(self):
#卸载ACL模型文件
if self.init_ok:
self.release()
def postwork(self,image,outputs,scale_ratio,pad_size,check_area,polygon,conf_threshold,iou_thres):
'''
针对每个模型特有的后处理内容
:param image:
:param outputs:
:param scale_ratio:
:param pad_size:
:param check_area:
:param polygon:
:param conf_threshold:
:param iou_thres:
:return:
'''
bwarn = False
warn_text = ""
# 是否有检测区域,有先绘制检测区域 由于在该函数生成了polygon对象,所有需要在检测区域前调用。
if check_area == 1:
self.draw_polygon(image, polygon, (255, 0, 0))
if outputs:
output = outputs[0] # 只放了一张图片 -- #是否能批量验证?
# 后处理 -- boxout 是 tensor-list: [tensor([[],[].[]])] --[x1,y1,x2,y2,置信度,coco_index]
# 利用非极大值抑制处理模型输出,conf_thres 为置信度阈值,iou_thres 为iou阈值
output_torch = torch.tensor(output)
boxout = nms(output_torch, conf_thres=conf_threshold, iou_thres=iou_thres)
del output_torch
pred_all = boxout[0].numpy() # 转换为numpy数组 -- [[],[],[]] --[x1,y1,x2,y2,置信度,coco_index]
# pred_all[:, :4] 取所有行的前4列,pred_all[:,1]--第一列
scale_coords([640, 640], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size)) # 将推理结果缩放到原始图片大小
# 过滤掉不是目标标签的数据 -- 序号0-- person self.labels_dict --这个考虑下是否可以放到nms前面#?
filtered_pred_all = pred_all[pred_all[:, 5] == 0]
# 绘制检测结果 --- 也需要封装在类里,
for pred in filtered_pred_all:
x1, y1, x2, y2 = int(pred[0]), int(pred[1]), int(pred[2]), int(pred[3])
# # 绘制目标识别的锚框 --已经在draw_bbox里处理
# cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
if check_area == 1: # 指定了检测区域
x_center = (x1 + x2) / 2
y_center = (y1 + y2) / 2
# 绘制中心点?
cv2.circle(image, (int(x_center), int(y_center)), 5, (0, 0, 255), -1)
# 判断是否区域点
if not self.is_point_in_region((x_center, y_center)):
continue # 没产生报警-继续
# 产生报警 -- 有一个符合即可
bwarn = True
warn_text = "People Intruder detected!"
draw_bbox(filtered_pred_all, image, (0, 255, 0), 2, self.labels_dict) # 画出检测框、类别、概率
# 清理内存
del outputs, output
del boxout
del pred_all, filtered_pred_all
#图片绘制是在原图生效 image
return bwarn, warn_text
def verify(self,image,data,isdraw=1):
labels_dict = get_labels_from_txt('/mnt/zfbox/model/plugins/RYRQ_ACL/coco_names.txt') # 得到类别信息,返回序号与类别对应的字典
@ -50,8 +96,7 @@ class Model(ModelBase):
img = np.ascontiguousarray(img, dtype=np.float32) / 255.0 # 转换为内存连续存储的数组
# 模型推理, 得到模型输出
outputs = None
#outputs = self.execute([img,])#创建input,执行模型,返回结果 --失败返回None
outputs = self.execute([img,])#创建input,执行模型,返回结果 --失败返回None
filtered_pred_all = None
bwarn = False
@ -63,8 +108,10 @@ class Model(ModelBase):
if outputs:
output = outputs[0] #只放了一张图片
# 后处理 -- boxout 是 tensor-list: [tensor([[],[].[]])] --[x1,y1,x2,y2,置信度,coco_index]
boxout = nms(torch.tensor(output), conf_thres=0.3,
iou_thres=0.5) # 利用非极大值抑制处理模型输出,conf_thres 为置信度阈值,iou_thres 为iou阈值
# 利用非极大值抑制处理模型输出,conf_thres 为置信度阈值,iou_thres 为iou阈值
output_torch = torch.tensor(output)
boxout = nms(output_torch, conf_thres=0.4,iou_thres=0.5)
del output_torch
pred_all = boxout[0].numpy() # 转换为numpy数组 -- [[],[],[]] --[x1,y1,x2,y2,置信度,coco_index]
# pred_all[:, :4] 取所有行的前4列,pred_all[:,1]--第一列
scale_coords([640, 640], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size)) # 将推理结果缩放到原始图片大小
@ -85,10 +132,15 @@ class Model(ModelBase):
continue #没产生报警-继续
#产生报警 -- 有一个符合即可
bwarn = True
warn_text = "Intruder detected!"
img_dw = draw_bbox(filtered_pred_all, image, (0, 255, 0), 2, labels_dict) # 画出检测框、类别、概率
warn_text = "People Intruder detected!"
draw_bbox(filtered_pred_all, image, (0, 255, 0), 2, labels_dict) # 画出检测框、类别、概率
# 清理内存
del outputs, output
del boxout
del pred_all,filtered_pred_all
#cv2.imwrite('img_res.png', img_dw)
return filtered_pred_all, bwarn, warn_text
return bwarn, warn_text
def testRun(self):
print("1111")
print("I am RYRQ-Model-ACL!!!")

130
model/plugins/RYRQ_Model_ACL/RYRQ_Model_ACL.py

@ -0,0 +1,130 @@
import os.path
from model.plugins.ModelBase import ModelBase
#from model.base_model.ascnedcl.det_utils import get_labels_from_txt, letterbox, scale_coords, nms, draw_bbox # 模型前后处理相关函数
from model.base_model.ascnedcl.det_utils_v10 import draw_box,draw_bbox_old, letterbox,non_max_suppression_v10
import cv2
import numpy as np
import torch # 深度学习运算框架,此处主要用来处理数据
class Model(ModelBase):
def __init__(self,path,threshold=0.5,iou_thres=0.5):
# 找pt模型路径 -- 一个约束py文件和模型文件的路径关系需要固定, -- 上传模型时,要解压好路径
dirpath, filename = os.path.split(path)
#self.model_file = os.path.join(dirpath, "yolov5s_bs1.om") # 目前约束模型文件和py文件在同一目录
self.model_file = os.path.join(dirpath, "yolov10m_310B4.om") # 目前约束模型文件和py文件在同一目录
self.coco_file = os.path.join(dirpath, "coco_names.txt")
#self.labels_dict = get_labels_from_txt(self.coco_file) # 得到类别信息,返回序号与类别对应的字典
super().__init__(self.model_file) # acl环境初始化基类负责类的实例化
self.name = "人员入侵-yolov10"
self.version = "V1.0"
self.model_type = 2
self.neth = 640 # 缩放的目标高度, 也即模型的输入高度
self.netw = 640 # 缩放的目标宽度, 也即模型的输入宽度
self.conf_threshold = threshold # 置信度阈值
self.iou_thres = iou_thres #IOU阈值
def prework(self,image):
'''模型输入图片数据前处理 --- 针对每个模型特有的预处理内容 -'''
img, scale_ratio, dw,dh = letterbox(image, new_shape=[self.netw, self.neth]) # 对图像进行缩放与填充
img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, HWC to CHW #图片在输入时已经做了转换
img = np.ascontiguousarray(img, dtype=np.float32) / 255.0 # 转换为内存连续存储的数组
return img,scale_ratio, (dw,dh)
def postwork(self,image,outputs,scale_ratio,pad_size,check_area,polygon,conf_threshold,iou_thres):
'''
针对每个模型特有的后处理内容
:param image:
:param outputs:
:param scale_ratio:
:param pad_size:
:param check_area:
:param polygon:
:param conf_threshold:
:param iou_thres:
:return:
'''
filtered_pred_all = None
bwarn = False
warn_text = ""
# 是否有检测区域,有先绘制检测区域 由于在该函数生成了polygon对象,所有需要在检测区域前调用。
if check_area == 1:
self.draw_polygon(image, polygon, (255, 0, 0))
if outputs:
output = np.squeeze(outputs[0]) # 移除张量为1的维度 --暂时不明白其具体意义
dw,dh = pad_size
pred_all = non_max_suppression_v10(output, self.conf_threshold, scale_ratio, dw, dh)
for xmin, ymin, xmax, ymax, confidence, label in pred_all:
# # 绘制目标识别的锚框 --已经在draw_bbox里处理
# cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
draw_box(image, [xmin, ymin, xmax, ymax], confidence, label) # 画出检测框、类别、概率
if label == 0: # person
# 判断是否产生告警
x1, y1, x2, y2 = int(xmin), int(ymin), int(xmax), int(ymax)
if check_area == 1: # 指定了检测区域
x_center = (x1 + x2) / 2
y_center = (y1 + y2) / 2
# 绘制中心点?
cv2.circle(image, (int(x_center), int(y_center)), 5, (0, 0, 255), -1)
# 判断是否区域点
if not self.is_point_in_region((x_center, y_center)):
continue # 没产生报警-继续
# 产生报警 -- 有一个符合即可
bwarn = True
warn_text = "People Intruder detected!"
# 清理内存
del outputs, output
del pred_all, filtered_pred_all
# cv2.imwrite('img_res.png', img_dw)
return bwarn, warn_text
def verify(self,image,data,isdraw=1):
# 数据前处理
img, scale_ratio, dw,dh = letterbox(image, new_shape=[self.netw, self.neth]) # 对图像进行缩放与填充
img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, HWC to CHW #图片在输入时已经做了转换
img = np.ascontiguousarray(img, dtype=np.float32) / 255.0 # 转换为内存连续存储的数组
# 模型推理, 得到模型输出
outputs = self.execute([img,])#创建input,执行模型,返回结果 --失败返回None
filtered_pred_all = None
bwarn = False
warn_text = ""
# 是否有检测区域,有先绘制检测区域 由于在该函数生成了polygon对象,所有需要在检测区域前调用。
if data[1] == 1:
self.draw_polygon(image, data[2], (255, 0, 0))
if outputs:
output = np.squeeze(outputs[0]) #移除张量为1的维度 --暂时不明白其具体意义
pred_all = non_max_suppression_v10(output,self.conf_threshold,scale_ratio,dw,dh)
for xmin, ymin, xmax, ymax, confidence, label in pred_all:
# # 绘制目标识别的锚框 --已经在draw_bbox里处理
# cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
draw_box(image, [xmin, ymin, xmax, ymax], confidence, label) # 画出检测框、类别、概率
if label == 0: # person
#判断是否产生告警
x1, y1, x2, y2 = int(xmin), int(ymin), int(xmax), int(ymax)
if data[1] == 1: # 指定了检测区域
x_center = (x1 + x2) / 2
y_center = (y1 + y2) / 2
# 绘制中心点?
cv2.circle(image, (int(x_center), int(y_center)), 5, (0, 0, 255), -1)
# 判断是否区域点
if not self.is_point_in_region((x_center, y_center)):
continue # 没产生报警-继续
# 产生报警 -- 有一个符合即可
bwarn = True
warn_text = "People Intruder detected!"
# 清理内存
del outputs, output
del pred_all,filtered_pred_all
#cv2.imwrite('img_res.png', img_dw)
return bwarn, warn_text
def testRun(self):
print("I am RYRQ-Model-ACL!!!")

80
model/plugins/RYRQ_Model_ACL/coco_names.txt

@ -0,0 +1,80 @@
person
bicycle
car
motorcycle
airplane
bus
train
truck
boat
traffic_light
fire_hydrant
stop_sign
parking_meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
backpack
umbrella
handbag
tie
suitcase
frisbee
skis
snowboard
sports_ball
kite
baseball_bat
baseball_glove
skateboard
surfboard
tennis_racket
bottle
wine_glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot_dog
pizza
donut
cake
chair
couch
potted_plant
bed
dining_table
toilet
tv
laptop
mouse
remote
keyboard
cell_phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy_bear
hair_drier
toothbrush

BIN
model/plugins/RYRQ_Model_ACL/yolov5s_bs1.om

Binary file not shown.

155
model/plugins/yolov5-1.py

@ -1,155 +0,0 @@
# 导入代码依赖
import cv2
import numpy as np
from myutils.ConfigManager import myCongif
import os
import torch
import ipywidgets as widgets
from IPython.display import display
from skvideo.io import vreader, FFmpegWriter
import IPython.display
from ais_bench.infer.interface import InferSession
from det_utils import letterbox, scale_coords, nms
def preprocess_image(image, cfg, bgr2rgb=True):
"""图片预处理"""
img, scale_ratio, pad_size = letterbox(image, new_shape=cfg['input_shape'])
if bgr2rgb:
img = img[:, :, ::-1]
img = img.transpose(2, 0, 1) # HWC2CHW
img = np.ascontiguousarray(img, dtype=np.float32)
return img, scale_ratio, pad_size
def draw_bbox(bbox, img0, color, wt, names):
"""在图片上画预测框"""
det_result_str = ''
for idx, class_id in enumerate(bbox[:, 5]):
if float(bbox[idx][4] < float(0.05)):
continue
img0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])),
color, wt)
img0 = cv2.putText(img0, str(idx) + ' ' + names[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] + 16)),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
img0 = cv2.putText(img0, '{:.4f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] + 32)),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
det_result_str += '{} {} {} {} {} {}\n'.format(
names[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3])
return img0
def get_labels_from_txt(path):
"""从txt文件获取图片标签"""
labels_dict = dict()
with open(path) as f:
for cat_id, label in enumerate(f.readlines()):
labels_dict[cat_id] = label.strip()
return labels_dict
def draw_prediction(pred, image, labels):
"""在图片上画出预测框并进行可视化展示"""
imgbox = widgets.Image(format='jpg', height=720, width=1280)
img_dw = draw_bbox(pred, image, (0, 255, 0), 2, labels)
imgbox.value = cv2.imencode('.jpg', img_dw)[1].tobytes()
display(imgbox)
def infer_image(img_path, model, class_names, cfg):
"""图片推理"""
# 图片载入
image = cv2.imread(img_path)
# 数据预处理
img, scale_ratio, pad_size = preprocess_image(image, cfg)
# 模型推理
output = model.infer([img])[0]
output = torch.tensor(output)
# 非极大值抑制后处理
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])
pred_all = boxout[0].numpy()
# 预测坐标转换
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size))
# 图片预测结果可视化
draw_prediction(pred_all, image, class_names)
def infer_frame_with_vis(image, model, labels_dict, cfg, bgr2rgb=True):
# 数据预处理
img, scale_ratio, pad_size = preprocess_image(image, cfg, bgr2rgb)
# 模型推理
output = model.infer([img])[0]
output = torch.tensor(output)
# 非极大值抑制后处理
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])
pred_all = boxout[0].numpy()
# 预测坐标转换
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size))
# 图片预测结果可视化
img_vis = draw_bbox(pred_all, image, (0, 255, 0), 2, labels_dict)
return img_vis
def img2bytes(image):
"""将图片转换为字节码"""
return bytes(cv2.imencode('.jpg', image)[1])
def infer_video(video_path, model, labels_dict, cfg):
"""视频推理"""
image_widget = widgets.Image(format='jpeg', width=800, height=600)
display(image_widget)
# 读入视频
cap = cv2.VideoCapture(video_path)
while True:
ret, img_frame = cap.read()
if not ret:
break
# 对视频帧进行推理
image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg, bgr2rgb=True)
image_widget.value = img2bytes(image_pred)
def infer_camera(model, labels_dict, cfg):
"""外设摄像头实时推理"""
def find_camera_index():
max_index_to_check = 10 # Maximum index to check for camera
for index in range(max_index_to_check):
cap = cv2.VideoCapture(index)
if cap.read()[0]:
cap.release()
return index
# If no camera is found
raise ValueError("No camera found.")
# 获取摄像头
camera_index = find_camera_index()
cap = cv2.VideoCapture(camera_index)
# 初始化可视化对象
image_widget = widgets.Image(format='jpeg', width=1280, height=720)
display(image_widget)
while True:
# 对摄像头每一帧进行推理和可视化
_, img_frame = cap.read()
image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg)
image_widget.value = img2bytes(image_pred)
if __name__ == "__main__":
cfg = {
'conf_thres': 0.4, # 模型置信度阈值,阈值越低,得到的预测框越多
'iou_thres': 0.5, # IOU阈值,高于这个阈值的重叠预测框会被过滤掉
'input_shape': [640, 640], # 模型输入尺寸
}
model_path = os.path.join(myCongif.get_data('weight_path'),'/yolov5-1/yolov5s.pt')
label_path = os.path.join(myCongif.get_data('weight_path'),'/yolov5-1/coco_names.txt')
# 初始化推理模型
model = InferSession(0, model_path)
labels_dict = get_labels_from_txt(label_path)
infer_mode = 'video'
if infer_mode == 'image':
img_path = 'world_cup.jpg'
infer_image(img_path, model, labels_dict, cfg)
elif infer_mode == 'camera':
infer_camera(model, labels_dict, cfg)
elif infer_mode == 'video':
video_path = 'racing.mp4'
infer_video(video_path, model, labels_dict, cfg)

64
model/weights/yolov5-1/yoloV5.py

@ -1,64 +0,0 @@
import torch
import cv2
import numpy as np
from shapely.geometry import Point, Polygon
import os
# # 自定义模型文件的路径
# model_path = 'yolov5s.pt' # 假设模型文件名为 yolov5s.pt 并与执行文件在同一个目录
# # 本地YOLOv5仓库路径
# repo_path = '../base_model/yolov5'
# 自定义模型文件的路径
print(f"Current working directory (yolov5.py): {os.getcwd()}")
model_path = 'D:/Project/FristProject/model/mode_test/yolov5s.pt' # 假设模型文件名为 yolov5s.pt 并与执行文件在同一个目录
# 本地YOLOv5仓库路径
repo_path = 'D:/Project/FristProject/model/base_model/yolov5'
# 加载自定义模型
model = torch.hub.load(repo_path, 'custom', path=model_path, source='local')
# 定义监控区域(多边形顶点)
region_points = [(100, 100), (500, 100), (500, 400), (100, 400)]
polygon = Polygon(region_points)
# 打开摄像头
cap = cv2.VideoCapture(0)
def is_point_in_polygon(point, polygon):
return polygon.contains(Point(point))
while True:
ret, frame = cap.read()
if not ret:
break
# 进行推理
results = model(frame)
detections = results.pandas().xyxy[0]
# 绘制监控区域
cv2.polylines(frame, [np.array(region_points, np.int32)], isClosed=True, color=(0, 255, 0), thickness=2)
for _, row in detections.iterrows():
if row['name'] == 'person':
# 获取人员检测框的中心点
x_center = (row['xmin'] + row['xmax']) / 2
y_center = (row['ymin'] + row['ymax']) / 2
if is_point_in_polygon((x_center, y_center), polygon):
# 触发报警
cv2.putText(frame, 'Alert: Intrusion Detected', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
print('Alert: Intrusion Detected')
# 绘制检测框
cv2.rectangle(frame, (int(row['xmin']), int(row['ymin'])), (int(row['xmax']), int(row['ymax'])), (255, 0, 0), 2)
cv2.circle(frame, (int(x_center), int(y_center)), 5, (0, 0, 255), -1)
# 显示结果
cv2.imshow('Frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()

300
myutils/IPManager.py

@ -0,0 +1,300 @@
import subprocess
import platform
import locale
import re
'''
针对windows和linux的网络信息获取和设置功能类
由于网络接口名字并不一定又有多网卡等情况实际应用时需要指定网络接口固化硬件环境
'''
class IPManager:
def __init__(self):
self.os_type = platform.system()
self.encoding = locale.getpreferredencoding()
def set_ip(self, interface_name, ip_address, subnet_mask, gateway):
if self.os_type == "Windows":
self._set_ip_windows(interface_name, ip_address, subnet_mask, gateway)
elif self.os_type == "Linux":
self._set_ip_linux(interface_name, ip_address, subnet_mask, gateway)
else:
raise NotImplementedError("Unsupported OS")
def connect_wifi(self, ssid, password):
if self.os_type == "Windows":
self._connect_wifi_windows(ssid, password)
elif self.os_type == "Linux":
self._connect_wifi_linux(ssid, password)
else:
raise NotImplementedError("Unsupported OS")
def get_wifi_list(self):
wifis = []
if self.os_type == "Windows":
wifis = self._get_wifi_list_windows()
elif self.os_type == "Linux":
wifis = self._get_wifi_list_linux()
else:
raise NotImplementedError("Unsupported OS")
return wifis
def get_connected_wifi(self):
ssid = None
if self.os_type == "Windows":
ssid = self._get_connected_wifi_windows()
elif self.os_type == "Linux":
ssid = self._get_connected_wifi_linux()
else:
raise NotImplementedError("Unsupported OS")
return ssid
def get_network_info(self):
info = None
if self.os_type == "Windows":
info = self._get_network_info_windows()
elif self.os_type == "Linux":
info = self._get_network_info_linux()
else:
raise NotImplementedError("Unsupported OS")
return info
def _set_ip_windows(self, interface_name, ip_address, subnet_mask, gateway):
command = f'netsh interface ip set address name="{interface_name}" static {ip_address} {subnet_mask} {gateway} 1'
#result = subprocess.run(command, shell=True,capture_output=True, text=True, encoding='utf-8')
# 打印输出结果
result = self._run_cmd(command)
print(result.stdout)
# 检查返回码
if result.returncode == 0:
print("IP address set successfully.")
else:
print("Failed to set IP address. Please check the output for errors.")
def _set_ip_linux(self, interface_name, ip_address, subnet_mask, gateway):
self._run_cmd(f"sudo ip addr flush dev {interface_name}")
self._run_cmd(f"sudo ip addr add {ip_address}/{subnet_mask} dev {interface_name}")
self._run_cmd(f"sudo ip route add default via {gateway}")
def _connect_wifi_windows(self, ssid, password):
command = f'netsh wlan connect name="{ssid}"'
self._run_cmd(command)
def _connect_wifi_linux(self, ssid, password):
command = f"nmcli dev wifi connect '{ssid}' password '{password}'"
self._run_cmd(command)
def _get_wifi_list_windows(self):
command = "netsh wlan show networks"
result = self._run_cmd(command)
wifi_list = []
lines = result.stdout.split('\n')
for line in lines:
if "SSID" in line and "BSSID" not in line:
ssid = line.split(":")[1].strip()
wifi_list.append(ssid)
return wifi_list
def _get_wifi_list_linux(self):
command = "nmcli dev wifi list"
result = self._run_cmd(command)
# 解析输出结果
wifi_list = []
lines = result.stdout.split('\n')
for line in lines[1:]: # 跳过表头
if line.strip():
ssid = line.split()[0]
wifi_list.append(ssid)
return wifi_list
def _get_connected_wifi_windows(self):
command = "netsh wlan show interfaces"
result = self._run_cmd(command)
# 使用正则表达式提取SSID
ssid_match = re.search(r"SSID\s+: (.+)", result.stdout)
if ssid_match:
ssid = ssid_match.group(1).strip()
return ssid
else:
return None
def _get_connected_wifi_linux(self):
command = "iwgetid -r"
result = self._run_cmd(command)
ssid = result.stdout.strip()
if ssid:
return ssid
else:
return None
def _get_network_info_windows(self):
command = "ipconfig /all"
result = self._run_cmd(command)
interfaces = {}
current_interface = None
for line in result.stdout.splitlines():
# 识别接口名称
interface_match = re.match(r"^\s*([^:\s]+.*):$", line)
if interface_match:
current_interface = interface_match.group(1).strip()
interfaces[current_interface] = {"IP": None, "Subnet": None, "Gateway": None, "DNS": []}
if current_interface:
# 解析IP地址
ip_match = re.search(r"^\s*IPv4 地址[^\:]*:\s*(\d+\.\d+\.\d+\.\d+)", line)
if ip_match:
interfaces[current_interface]["IP"] = ip_match.group(1).strip()
# 解析子网掩码
subnet_match = re.search(r"^\s*子网掩码[^\:]*:\s*(\d+\.\d+\.\d+\.\d+)", line)
if subnet_match:
interfaces[current_interface]["Subnet"] = subnet_match.group(1).strip()
# 解析网关
gateway_match = re.search(r"^\s*默认网关[^\:]*:\s*(\d+\.\d+\.\d+\.\d+)", line)
if gateway_match:
interfaces[current_interface]["Gateway"] = gateway_match.group(1).strip()
# 解析DNS服务器
dns_match = re.search(r"^\s*DNS 服务器[^\:]*:\s*(\d+\.\d+\.\d+\.\d+)", line)
if dns_match:
interfaces[current_interface]["DNS"].append(dns_match.group(1).strip())
else:
# 匹配后续行的DNS服务器
dns_continued_match = re.search(r"^\s*(\d+\.\d+\.\d+\.\d+)", line)
if dns_continued_match:
interfaces[current_interface]["DNS"].append(dns_continued_match.group(1).strip())
return interfaces
def _get_network_info_linux(self):
# 获取IP地址、子网掩码和网关
ip_info = self._run_cmd("ip addr show").stdout
route_info = self._run_cmd("ip route show").stdout
# 获取DNS服务器
dns_info = self._run_cmd("nmcli dev show | grep DNS").stdout
interfaces = {}
current_interface = None
for line in ip_info.splitlines():
# 识别接口名称
interface_match = re.match(r"^\d+: ([^:\s]+):", line)
if interface_match:
current_interface = interface_match.group(1).strip()
interfaces[current_interface] = {"IP": None, "Subnet": None, "Gateway": None, "DNS": []}
if current_interface:
# 解析IP地址和子网掩码
ip_match = re.search(r"^\s*inet (\d+\.\d+\.\d+\.\d+)/(\d+)", line)
if ip_match:
interfaces[current_interface]["IP"] = ip_match.group(1).strip()
interfaces[current_interface]["Subnet"] = ip_match.group(2).strip()
# 解析网关
for line in route_info.splitlines():
if "default via" in line:
gateway_match = re.search(r"default via (\d+\.\d+\.\d+\.\d+)", line)
interface_match = re.search(r"dev (\S+)", line)
if gateway_match and interface_match:
interface = interface_match.group(1).strip()
if interface in interfaces:
interfaces[interface]["Gateway"] = gateway_match.group(1).strip()
# 解析DNS服务器
for line in dns_info.splitlines():
dns_match = re.search(r"DNS\[\d+\]:\s*(\d+\.\d+\.\d+\.\d+)", line)
if dns_match:
# 假设第一个接口是主要接口
primary_interface = list(interfaces.keys())[0]
interfaces[primary_interface]["DNS"].append(dns_match.group(1).strip())
return interfaces
def _get_interface_info_windows(self,interface_name):
command = f'netsh interface ip show config name="{interface_name}"'
result = self._run_cmd(command)
info = {"IP": None, "Subnet": None, "Gateway": None, "DNS": []}
# 解析IP地址
ip_match = re.search(r"IP Address:\s*(\d+\.\d+\.\d+\.\d+)", result.stdout)
if ip_match:
info["IP"] = ip_match.group(1).strip()
# 解析子网掩码
subnet_match = re.search(r"Subnet Prefix:\s*(\d+\.\d+\.\d+\.\d+)", result.stdout)
if subnet_match:
info["Subnet"] = subnet_match.group(1).strip()
# 解析网关
gateway_match = re.search(r"Default Gateway:\s*(\d+\.\d+\.\d+\.\d+)", result.stdout)
if gateway_match:
info["Gateway"] = gateway_match.group(1).strip()
# 解析DNS服务器
dns_matches = re.findall(r"Statically Configured DNS Servers:\s*(\d+\.\d+\.\d+\.\d+)", result.stdout)
for dns in dns_matches:
info["DNS"].append(dns.strip())
return info
def _get_interface_info_linux(self,interface_name):
info = {"IP": None, "Subnet": None, "Gateway": None, "DNS": []}
# 获取IP地址和子网掩码
ip_command = f"ip addr show dev {interface_name}"
ip_result = self._run_cmd(ip_command)
ip_match = re.search(r"inet (\d+\.\d+\.\d+\.\d+)/(\d+)", ip_result.stdout)
if ip_match:
info["IP"] = ip_match.group(1).strip()
info["Subnet"] = ip_match.group(2).strip()
# 获取网关信息
gateway_command = f"ip route show dev {interface_name}"
gateway_result = subprocess.run(gateway_command, shell=True, capture_output=True, text=True, encoding='utf-8')
gateway_match = re.search(r"default via (\d+\.\d+\.\d+\.\d+)", gateway_result.stdout)
if gateway_match:
info["Gateway"] = gateway_match.group(1).strip()
# 获取DNS服务器信息
dns_command = f"nmcli dev show {interface_name} | grep DNS"
dns_result = subprocess.run(dns_command, shell=True, capture_output=True, text=True, encoding='utf-8')
dns_matches = re.findall(r"DNS\[\d+\]:\s*(\d+\.\d+\.\d+\.\d+)", dns_result.stdout)
for dns in dns_matches:
info["DNS"].append(dns.strip())
return info
def _run_cmd(self,command):
'''
为了统一命令执行的返回参数格式统一定义了一个执行函数
:param command:
:return:
'''
result = subprocess.run(command, shell=True, capture_output=True, text=True, encoding=self.encoding)
return result
IPM = IPManager()
if __name__ == "__main__":#WLAN
# 示例用法
nm = IPManager()
try:
#nm.set_ip("以太网 2", "192.168.1.100", "255.255.255.0", "192.168.1.1")
#nm.set_ip("WLAN", "192.168.3.100", "255.255.255.0", "192.168.3.1") #zhang wifi
network_info = nm.get_wifi_list()
print(network_info)
except Exception as e:
print(e)
#nm.connect_wifi("YourSSID", "YourPassword")

33
myutils/MyDeque.py

@ -0,0 +1,33 @@
from collections import deque
from threading import Thread, Lock
class MyDeque:
def __init__(self,maxlen=1):
self.len = maxlen
self.dq = deque(maxlen=maxlen)
self.lock = Lock()
def __del__(self):
del self.dq
def isfull(self):
if len(self.dq) == self.len:
return True
return False
def myappend(self,object):
with self.lock:
self.dq.append(object)
def mypopleft(self):
object = None
with self.lock:
if self.dq:
object = self.dq.popleft()
else:
pass
return object
def myclear(self):
with self.lock:
self.dq.clear()

52
myutils/MyRtspManager.py

@ -0,0 +1,52 @@
import socket
class MyRtspManager:
def __init__(self):
self.rtsp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
pass
def __del__(self):
pass
def _send_rtsp_request(self,request):
'''
发送 RTSP 请求按照 RTSP 协议的格式发送请求例如 OPTIONSDESCRIBESETUP PLAY 请求
:param socket:
:param request:
:return:
'''
self.rtsp_socket.sendall(request.encode())
response = self.rtsp_socket.recv(4096).decode()
print("Response:\n", response)
return response
def _connectRest(self,IP,Port):
#self.rtsp_socket.connect(('192.168.3.103', 554))
self.rtsp_socket.connect((IP, Port))
#需要补充重连机制
def startGetRtsp(self):
# 发送 OPTIONS 请求
request = "OPTIONS rtsp://192.168.3.103/live1 RTSP/1.0\r\nCSeq: 1\r\n\r\n"
self._send_rtsp_request(request)
# 发送 DESCRIBE 请求获取 SDP 信息
request = "DESCRIBE rtsp://192.168.3.103/live1 RTSP/1.0\r\nCSeq: 2\r\nAccept: application/sdp\r\n\r\n"
response = self._send_rtsp_request(request)
# 解析 SDP 信息,提取媒体信息(如视频轨道的端口、编码)
# 此处需解析返回的 response 来提取端口、编码等信息
# 发送 SETUP 请求来配置 RTP/RTCP 传输
request = "SETUP rtsp://192.168.3.103/live1/trackID=0 RTSP/1.0\r\nCSeq: 3\r\nTransport: RTP/AVP;unicast;client_port=5000-5001\r\n\r\n"
self._send_rtsp_request(request)
# 创建 UDP 套接字来接收 RTP 数据
rtp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
rtp_socket.bind(('0.0.0.0', 5000)) # 绑定到前面 SETUP 请求中指定的 client_port
while True:
rtp_packet, _ = rtp_socket.recvfrom(2048)
# 解析 RTP 包的头部,提取负载数据(视频帧)
# 可以根据负载类型解析 H264 或其他格式的帧数据
print(f"Received RTP packet of size {len(rtp_packet)}")

28
myutils/MyTraceMalloc.py

@ -0,0 +1,28 @@
import tracemalloc
import time
class MyTraceMalloc:
def __init__(self):
tracemalloc.start(25) # 保留25个堆栈级别
self.before_snapshot = tracemalloc.take_snapshot()
self.current_snapshot = None
self.top_stats = []
# 内存跟踪情况输出
def display_top_stats(self):
self.current_snapshot = tracemalloc.take_snapshot()
self.top_stats = self.current_snapshot .compare_to(self.before_snapshot, 'lineno')
print("[ Top 10 differences ]")
for stat in self.top_stats[:10]:
print(stat)
current, peak = tracemalloc.get_traced_memory()
print(f"当前内存分配: {current / 1024 / 1024:.2f} MiB")
print(f"峰值内存分配: {peak / 1024 / 1024:.2f} MiB")
self.before_snapshot = self.current_snapshot
def trace_memory(self):
while True:
time.sleep(60) # 每隔60秒输出一次
self.display_top_stats()

16
myutils/mydvpp.py

@ -0,0 +1,16 @@
import cv2
def bgr_to_yuv420(bgr_img):
# Step 1: Convert BGR to YUV 4:4:4
yuv_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2YUV)
# Step 2: Extract Y, U, V channels
Y, U, V = cv2.split(yuv_img)
# Step 3: Downsample U and V channels (Subsample by a factor of 2)
U_downsampled = cv2.resize(U, (U.shape[1] // 2, U.shape[0] // 2), interpolation=cv2.INTER_LINEAR)
V_downsampled = cv2.resize(V, (V.shape[1] // 2, V.shape[0] // 2), interpolation=cv2.INTER_LINEAR)
# Step 4: Combine Y, U_downsampled, V_downsampled to get YUV 4:2:0 format
return Y, U_downsampled, V_downsampled

70
run.py

@ -1,15 +1,69 @@
from core.ViewManager import mVManager
from web import create_app
from core.ModelManager import mMM
import os
import platform
import shutil
import asyncio
import uvicorn
from hypercorn.asyncio import serve
from hypercorn.config import Config
from myutils.MyTraceMalloc import MyTraceMalloc
import subprocess
print(f"Current working directory (run.py): {os.getcwd()}")
web = create_app()
app = create_app()
async def run_quart_app():
config = Config()
config.bind = ["0.0.0.0:5001"]
await serve(app, config)
def test():
mMM.test1()
def run_subprocess():
# 启动子进程,用于接收 stdin 输入并通过 stdout 返回结果
process = subprocess.Popen(
['python3', '-c', '''
import sys
# 从stdin读取输入
for line in sys.stdin:
# 处理输入并写回stdout
sys.stdout.write(f"Processed: {line}")
sys.stdout.flush() # 刷新stdout输出缓冲区
'''],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
# 发送输入数据到子进程的 stdin
input_data = "Hello, subprocess!\n"
print(f"Sending to subprocess: {input_data}")
process.stdin.write(input_data)
process.stdin.flush() # 确保输入被传递给子进程
# 从子进程的 stdout 读取返回数据
output = process.stdout.readline() # 读取一行输出
print(f"Received from subprocess: {output}")
# 检查是否有错误输出
error = process.stderr.read()
if error:
print(f"Error from subprocess: {error}")
else:
print("no error!!")
# 关闭 stdin,并等待子进程完成
process.stdin.close()
process.wait()
if __name__ == '__main__':
#test()
#run_subprocess()
system = platform.system()
if system == "Windows":
total, used, free = shutil.disk_usage("/")
@ -20,7 +74,17 @@ if __name__ == '__main__':
else:
raise NotImplementedError(f"Unsupported operating system: {system}")
print(free/(1024*1024))
# #内存监控线程
# myTM = MyTraceMalloc()
# threading.Thread(target=myTM.trace_memory, daemon=True).start()
#启动工作线程
mMM.start_work() # 启动所有通道的处理
#mVManager.start_check_rtsp() #线程更新视频在线情况
web.run(debug=True,port=5001,host="0.0.0.0")
#启动web服务
asyncio.run(run_quart_app())
#uvicorn.run("run:app", host="0.0.0.0", port=5001, workers=4,reload=True)

BIN
uploads/8.zip

Binary file not shown.

2
web/API/__init__.py

@ -1,4 +1,4 @@
from quart import Blueprint
#定义模块
api = Blueprint('api',__name__)
from . import user,system,viedo,channel,model
from . import user,system,viedo,channel,model,warn

352
web/API/channel.py

@ -4,6 +4,10 @@ from . import api
from web.common.utils import login_required
from core.DBManager import mDBM
from myutils.ReManager import mReM
from core.ModelManager import mMM
from myutils.ConfigManager import myCongif
import asyncio
import time
@api.route('/channel/tree',methods=['GET'])
@login_required
@ -15,11 +19,15 @@ async def channel_tree(): #获取通道树
@api.route('/channel/list',methods=['GET'])
async def channel_list(): #获取通道列表 --分页查询,支持区域和通道名称关键字查询
strsql = ("select t2.area_name ,t1.ID ,t1.channel_name ,t1.ulr ,t1.'type' ,t1.status ,t1.element_id"
" from channel t1 left join area t2 on t1.area_id = t2.id where t1.is_work=1;")
strsql = ("select t2.area_name,t1.ID,t1.channel_name,t1.ulr,t1.'type',t1.status,t1.element_id,t4.model_name "
"from channel t1 left join area t2 on t1.area_id = t2.id "
"left JOIN channel2model t3 on t1.ID = t3.channel_id "
"left JOIN model t4 on t3.model_id = t4.ID "
"where t1.is_work=1 order by area_name desc;")
data = mDBM.do_select(strsql)
channel_list = [{"area_name": channel[0], "ID": channel[1], "channel_name": channel[2], "ulr": channel[3],
"type": channel[4], "status": channel[5], "element_id": channel[6]} for channel in data]
"type": channel[4], "status": channel[5],
"element_id": channel[6],"model_name":channel[7]} for channel in data]
return jsonify(channel_list)
@api.route('/channel/info',methods=['GET'])
@ -29,75 +37,119 @@ async def channel_info(): #获取通道信息 ---- list已获取详情
@api.route('/channel/add',methods=['POST'])
@login_required
async def channel_add(): #新增通道
area_id = (await request.form)['area_id']
channel_name = (await request.form)['channel_name']
url = (await request.form)['url']
if mReM.is_valid_rtsp_url(url) is not True:
async def channel_add(): #新增通道 -- 2024-8-1修改为与修改通道用一个接口
json_data = await request.get_json()
area = json_data.get('area')
cName = json_data.get('cName')
Rtsp = json_data.get('Rtsp')
cid = int(json_data.get('cid'))
if mReM.is_valid_rtsp_url(Rtsp) is not True:
reStatus = 0
reMsg = 'rtsp地址不合法'
return jsonify({'status': reStatus, 'msg': reMsg})
strsql = f"select area_name from area where id = {area_id};"
ret = mDBM.do_select(strsql,1)
if ret:
strsql = (f"INSERT INTO channel (area_id,channel_name,ulr,'type',status) values "
f"({area_id},'{channel_name}','{url}',1,0);")
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '添加通道成功'
else:
strsql = f"select id from area where area_name = '{area}';"
area = mDBM.do_select(strsql,1)
if area:
area_id = area[0]
#strsql = f"select ID from channel where area_id={area_id} and channel_name='{cName}';"
strsql = f"select ID from channel where channel_name='{cName}';"
data = mDBM.do_select(strsql, 1)
if data and data[0] != cid: #有值--代表重复 或者是它自己(只修改了RTSP地址)
reStatus = 0
reMsg = '添加通道失败,请联系技术支持!'
reMsg = "通道名称不能相同!"
else:
if cid == -1:
max_count = myCongif.get_data("max_channel_num")
strsql = "select count(*) from channel;"
data = mDBM.do_select(strsql,1)
if data[0] >= max_count:
reStatus = 0
reMsg = f"已达到最多通道数量-{max_count}通道,不能再添加"
return jsonify({'status': reStatus, 'msg': reMsg})
strsql = (f"INSERT INTO channel (area_id,channel_name,ulr,'type',status) values "
f"({area_id},'{cName}','{Rtsp}',1,0);")
else:
strsql = (f"UPDATE channel SET area_id={area_id},channel_name='{cName}'"
f",ulr='{Rtsp}' where ID={cid};")
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
if cid == -1:
reMsg = '添加通道成功'
#await asyncio.sleep(0.5) # 休眠0.5,待数据更新完成
# 对新增的视频通道进行视频采集和
strsql = f"select ID from channel where area_id={area_id} and channel_name='{cName}';"
data = mDBM.do_select(strsql, 1)
if data:
cid = data[0]
mMM.start_work(cid)
else:
print(f"这里不应该没有值!!!!area_id-{area_id},cName--{cName}")
await asyncio.sleep(1) #休眠一秒
strsql = f"select ID from channel where area_id={area_id} and channel_name='{cName}';"
data = mDBM.do_select(strsql, 1)
if data:
cid = data[0]
mMM.start_work(cid)
else:
print(f"这里真的不应该没有值了!!!!area_id-{area_id},cName--{cName}")
elif cid >0: #cid 不会是0,以防万一
reMsg = '修改通道成功'
#需要先停再启动---不区分有没有修改URL了,就当有修改使用
mMM.stop_work(cid)
start_time = time.time()
mMM.start_work(cid)
end_time = time.time()
execution_time = end_time - start_time
print(f"开始一个通道线程,花费了: {execution_time} seconds")
else:
reStatus = 0
if cid == -1:
reMsg = '添加通道失败,请联系技术支持!'
else:
reMsg = '修改通道信息失败,请联系技术支持!'
else:
reStatus = 0
reMsg = '错误的通道ID,请修改'
reMsg = '错误的区域ID,请修改'
return jsonify({'status':reStatus,'msg':reMsg})
@api.route('/channel/change',methods=['POST'])
@api.route('/channel/img',methods=['POST'])
@login_required
async def channel_change(): #修改通道信息
area_id = (await request.form)['area_id']
channel_id = (await request.form)['channel_id']
channel_name = (await request.form)['channel_name']
url = (await request.form)['url']
if mReM.is_valid_rtsp_url(url) is not True:
reStatus = 0
reMsg = 'rtsp地址不合法'
return jsonify({'status': reStatus, 'msg': reMsg})
strsql = f"select area_name from area where id = {area_id};"
ret = mDBM.do_select(strsql, 1)
if ret:
strsql = f"UPDATE channel SET area_id={area_id},channel_name='{channel_name}',ulr='{url}' where ID={channel_id};"
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '修改通道信息成'
else:
reStatus = 0
reMsg = '修改通道信息失败,请联系技术支持!'
async def get_channel_img():
'''获取一帧图片'''
json_data = await request.get_json()
cid = int(json_data.get('cid'))
img_base64 = mMM.verify_list.cm_get_cap_frame(cid)
if img_base64:
# 返回JSON响应
return jsonify({"image": img_base64})
else:
reStatus = 0
reMsg = '错误的通道ID,请修改'
return jsonify({'status': reStatus, 'msg': reMsg})
return jsonify({"error": "Failed to capture frame"}), 404
@api.route('/channel/del',methods=['POST'])
@login_required
async def channel_del(): #删除通道
channel_id = (await request.form)['channel_id']
#删除该通道和算法的关联信息:布防时间,算法模型数据----使用外键级联删除会方便很多,只要一个删除就可以
ret = mDBM.delchannel(channel_id)
if ret == True:
reStatus = 1
reMsg = '删除通道信息成'
json_data = await request.get_json()
cid = int(json_data.get('cid'))
reStatus = 0
if cid > 0:
mMM.stop_work(cid)
#删除该通道和算法的关联信息:布防时间,算法模型数据----使用外键级联删除会方便很多,只要一个删除就可以
ret = mDBM.delchannel(cid)
if ret == True:
reStatus = 1
reMsg = '删除通道信息成功'
else:
reMsg = '删除通道信息失败,请联系技术支持!'
else:
reStatus = 0
reMsg = '删除通道信息失败,请联系技术支持!'
reMsg = '通道ID参数错误,请联系技术支持!'
return jsonify({'status': reStatus, 'msg': reMsg})
@api.route('/channel/check',methods=['GET'])
@login_required
async def channel_check(): #检查通道视频的在线情况--可以获取全部 ID-0,全部,1*具体通道ID--10分钟会更新一次在线状态
async def channel_check(): #检查通道视频的在线情况--可以获取全部 ID-0,全部,1*具体通道ID--10分钟会更新一次在线状态-- 要验证
ID = request.args.get('ID')
if ID:
ID = int(ID)
@ -118,9 +170,133 @@ async def channel_check(): #检查通道视频的在线情况--可以获取全
reMsg = "参数错误"
return jsonify({'status': reStatus, 'msg': reMsg})
@api.route('/channel/C2M',methods=['POST'])
@login_required
async def get_ctm_data():
'''获取通道关联模型的相关数据'''
json_data = await request.get_json()
cid = int(json_data.get('cid'))
#获取算法数据
strsql = "select ID,model_name from model;"
model_datas = mDBM.do_select(strsql)
m_datas = []
if model_datas:
m_datas = [{'ID':row[0],'model_name':row[1]} for row in model_datas]
#获取c2m数据
strsql = f"select ID,model_id,check_area,polygon,conf_thres,iou_thres from channel2model where channel_id = {cid};"
c2m_data = mDBM.do_select(strsql,1)
#schedule数据
schedule = []
if c2m_data:
c2m_data_json = [{'model_id':c2m_data[1],'check_area':c2m_data[2],'polygon':c2m_data[3],
'conf_thres':c2m_data[4],'iou_thres':c2m_data[5]}]
c2m_id = c2m_data[0]
strsql = f"select day,hour,status from schedule where channel2model_id ={c2m_id} order by hour asc,day asc;"
schedule_datas = mDBM.do_select(strsql)
if schedule_datas:
schedule = [{'day': row[0], 'hour': row[1], 'status': row[2]} for row in schedule_datas]
else:
schedule = []
else:
schedule = []
c2m_data_json = []
#返回数据
redata = {"m_datas":m_datas,"c2m_data":c2m_data_json,"schedule":schedule}
return jsonify(redata)
@api.route('/channel/chanegeC2M',methods=['POST'])
@login_required
async def change_c_t_m():
'''
修改和新增与通道关联的算法模块
:return:
'''
json_data = await request.get_json()
model_name = json_data.get('model_name')
check_area = json_data.get('check_area')
polygon_str = json_data.get('polygon_str')
iou_thres = json_data.get('iou_thres')
conf_thres = json_data.get('conf_thres')
schedule = json_data.get('schedule')
cid = int(json_data.get('cid'))
#返回数据
reStatus = 0
reMsg = "更新失败,请联系技术支持!"
#开始更新--- 统一先停止原通道工作线程
if model_name=="请选择":
strsql = f"select ID from channel2model where channel_id={cid};"
data = mDBM.do_select(strsql,1)
if data:
#需要删除数据
ret = mDBM.delC2M(cid,1) #只是删除了数据库数据
if ret:
#停止该通道的model线程
mMM.restartC2M(cid) #没有模型关联数据,模型工作线程不会启动
reStatus = 1
reMsg = "更新成功"
else: #原本就没数据
reStatus = 1
reMsg = "更新成功"
else: #新增关联或修改关联
# 验证数据
if conf_thres <= 0 or conf_thres >= 1 or iou_thres <= 0 or iou_thres >= 1:
reMsg = "阈值的有效范围是大于0,小于1;请输入正确的阈值"
return jsonify({'status': reStatus, 'msg': reMsg})
c2m_id = updateModel(cid,model_name,check_area,polygon_str,conf_thres,iou_thres) #c2m表
if c2m_id != 0:
ret = updataSchedule(c2m_id,schedule.replace("'", "\"")) #schedule表
if ret:
# 重启下通道的工作线程
print(f"restartC2M--{cid}")
mMM.restartC2M(cid) #没有模型关联数据,模型工作线程不会启动
reStatus = 1
reMsg = "更新成功"
return jsonify({'status': reStatus, 'msg': reMsg})
def updataSchedule(c2m_id,schedule):
# schedule_data_str = ("{'6': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "
# "'0': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "
# "'1': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "
# "'2': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "
# "'3': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],"
# "'4': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],"
# "'5': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}")
#先删
strsql = f"delete from schedule where channel2model_id={c2m_id};"
mDBM.do_sql(strsql)
#再加
json_object = json.loads(schedule)
for day, hours in json_object.items():
for hour, status in enumerate(hours):
strsql = (
f"insert into schedule (channel2model_id,day,hour,status) values ({c2m_id},'{day}',{hour},{status})"
f" on conflict(channel2model_id,day,hour) do update set status=excluded.status;")
ret = mDBM.do_sql(strsql)
if not ret: #插入失败后,需要删除所有数据
strsql = f"delete from schedule where channel2model_id={c2m_id};"
mDBM.do_sql(strsql)
return ret
return 1
def updateModel(channel_id,model_name,check_area,polygon_str,conf_thres,iou_thres):
'''新增和修改通道关联的模型 ----约束:一个通道只能关联一个算法模型
return 0 失败 其他为c2m_id
'''
reStatus = 0
strsql = f"select ID from channel where ID={channel_id};"
if mDBM.do_select(strsql, 1): # 通道号在数据库中
strsql = f"select ID from model where model_name = '{model_name}';"
data = mDBM.do_select(strsql, 1)
if data: #通道和模型都有对应数据
reStatus = mDBM.updateC2M(channel_id, data[0],check_area,polygon_str,conf_thres,iou_thres)
return reStatus
@api.route('/channel/area/list',methods=['GET'])
@login_required
async def channel_area_list(): #获取区域列表
async def channel_area_list():
'''获取所属区域list'''
strsql = "select * from area;"
datas = mDBM.do_select(strsql)
reMsg = [{'id': data[0], 'area_name': data[1]} for data in datas]
@ -131,14 +307,20 @@ async def channel_area_list(): #获取区域列表
async def channel_area_change(): #修改区域名称
area_id = (await request.form)['id']
area_name = (await request.form)['name']
strsql = f"update area set area_name='{area_name}' where id = {area_id};"
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '修改通道名称成功'
else:
strsql = f"select id from area where area_name='{area_name}';"
datas = mDBM.do_select(strsql)
if datas:
reStatus = 0
reMsg = '修改通道名称失败,请联系技术支持!'
reMsg = '区域名称重复,请修改!'
else:
strsql = f"update area set area_name='{area_name}' where id = {area_id};"
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '修改通道名称成功'
else:
reStatus = 0
reMsg = '修改通道名称失败,请联系技术支持!'
return jsonify({'status': reStatus, 'msg': reMsg})
@api.route('/channel/area/del',methods=['POST'])
@ -164,29 +346,24 @@ async def channel_area_del(): #删除区域
@api.route('/channel/area/add',methods=['POST'])
@login_required
async def channel_area_add(): #添加区域
area_name = (await request.form)['name']
strsql = f"insert into area (area_name) values ('{area_name}');"
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '新增区域成功'
else:
json_data = await request.get_json()
area_name = json_data.get('name')
strsql = f"select id from area where area_name='{area_name}';"
data = mDBM.do_select(strsql,1)
if data:
reStatus = 0
reMsg = '新增区域失败,请联系技术支持!'
reMsg = '区域名称重复,请修改!'
else:
strsql = f"insert into area (area_name) values ('{area_name}');"
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '新增区域成功'
else:
reStatus = 0
reMsg = '新增区域失败,请联系技术支持!'
return jsonify({'status': reStatus, 'msg': reMsg})
@api.route('/channel/model/linklist',methods=['GET'])
@login_required
async def channel_model_linklist(): #获取算法列表 --关联算法时展示
ID = request.args.get('ID') #通道ID
strsql = (f"select t1.ID,t2.model_name from channel2model t1 left join model t2 "
f"on t1.model_id=t2.ID where channel_id={ID};")
datas = mDBM.do_select(strsql)
reMsg = {}
if datas:
reMsg = [{'ID': data[0], 'model_name': data[1]} for data in datas]
return jsonify(reMsg)
@api.route('/channel/model/list',methods=['GET'])
@login_required
async def channel_model_list(): #获取算法列表
@ -197,7 +374,8 @@ async def channel_model_list(): #获取算法列表
reMsg = [{'ID': data[0], 'model_name': data[1],'version':data[2]} for data in datas]
return jsonify(reMsg)
@api.route('/channel/model/linkmodel',methods=['POST'])
@api.route('/channel/model/linkmodel',methods=['POST']) #--没调用。。
@login_required
async def channel_model_linkmodel(): #获取算法列表 --关联算法时展示 #?关联算法时需要初始化布防计划,同样删除的需要删除
channel_id = (await request.form)['channel_id']
@ -234,7 +412,7 @@ async def channel_model_getarea(): #获取算法区域的备注信息 --- 同时
@api.route('/channel/model/changearea',methods=['POST'])
@login_required
async def channel_model_changearea(): #修改算法区域信息
async def channel_model_changearea(): #修改算法检测区域信息
ID = (await request.form)['ID']
check_area = (await request.form)['check_area']
check_x = (await request.form)['polygon']
@ -243,6 +421,8 @@ async def channel_model_changearea(): #修改算法区域信息
if ret == True:
reStatus = 1
reMsg = '修改算法检测区域成功'
#需要重启视频通道的执行程序 --需要cid
#?
else:
reStatus = 0
reMsg = '新修改算法检测区域失败,请联系技术支持!'
@ -250,7 +430,7 @@ async def channel_model_changearea(): #修改算法区域信息
@api.route('/channel/model/changethreshold',methods=['POST'])
@login_required
async def channel_model_changthreshold(): #修改算法区域信息
async def channel_model_changthreshold(): #修改算法阈值
ID = (await request.form)['ID']
conf_threshold = (await request.form)['conf_threshold']
@ -258,10 +438,10 @@ async def channel_model_changthreshold(): #修改算法区域信息
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '修改算法检测区域成功'
reMsg = '修改算法的阈值成功'
else:
reStatus = 0
reMsg = '新修改算法检测区域失败,请联系技术支持!'
reMsg = '新修改算法的阈值失败,请联系技术支持!'
return jsonify({'status': reStatus, 'msg': reMsg})
@api.route('/channel/model/getschedule',methods=['GET'])

198
web/API/model.py

@ -1,9 +1,11 @@
import os
import shutil
from quart import jsonify, request,session,flash,redirect
from . import api
from web.common.utils import login_required
from core.DBManager import mDBM
from core.Upload_file import allowed_file,check_file,updata_model
from core.ModelManager import mMM
from core.Upload_file import allowed_file,check_file
from myutils.ConfigManager import myCongif
from werkzeug.utils import secure_filename
@ -16,99 +18,155 @@ async def model_list(): #获取算法列表
"proportion":data[4]} for data in datas]
return jsonify(reMsg)
@api.route('/model/upload',methods=['POST'])
def restart_work(mid):
strsql = f"select channel_id from channel2model where model_id = {mid};"
datas = mDBM.do_select(strsql)
if datas: # 有关联
print("有关联")
# 重启通道业务
for data in datas:
mMM.restartC2M(data[0]) # 根该模型关联的所有通道都需要重启工作线程
@api.route('/model/add',methods=['POST'])
@login_required
async def model_add(): #新增算法
reStatus = 0
reMsg = "有错误!"
form = await request.form
model_name = form['mName']
files = await request.files
if 'file' not in files:
reMsg = '参数错误'
return jsonify({'status': reStatus, 'msg': reMsg})
file = files['file']
if file.filename == '':
reMsg = '没有选择文件'
return jsonify({'status': reStatus, 'msg': reMsg})
#判断算法名称是否重复
strsql = f"select ID from model where model_name='{model_name}';"
data = mDBM.do_select(strsql, 1)
if data:
reMsg = "算法名称重复,请修改!"
else:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename) #安全过滤
file_path = os.path.join(myCongif.get_data('UPLOAD_FOLDER'), filename)
await file.save(file_path)
#检查上传文件的合法性,若符合要求移动到正式路径
filename_pre = filename.rsplit('.',1)[0] #除去到.zip
model_version, model_name_file, model_path = check_file(file_path,filename_pre,2) #itype--2 是算法模型升级 1-系统升级
#删除压缩包
os.remove(file_path)
if model_version and model_path:
#model表插入数据
strsql = (f"insert into model (model_name,version,model_path) values "
f"('{model_name}','{model_version}','{model_path}');")
ret = mDBM.do_sql(strsql)
if ret:
reStatus = 1
reMsg = '算法添加成功'
else:
reMsg = '插入数据库出错,请联系技术支持!!'
else:
reMsg = '升级包不合法,请重新上传!'
else:
reMsg = '只允许上传zip文件'
#新增算法,不需要处理通道关联的相关业务
return jsonify({'status': reStatus, 'msg': reMsg})
@api.route('/model/upgrade',methods=['POST'])
@login_required
async def model_upload(): #上传算法文件--需要进行文件校验
async def model_upgrade(): #升级算法
reStatus = 0
reMsg = "有错误!"
form = await request.form
model_name = form['model_name']
mid = form['mid']
files = await request.files
if 'file' not in files:
flash('参数错误')
return redirect(request.url)
reMsg = '参数错误'
return jsonify({'status': reStatus, 'msg': reMsg})
file = files['file']
if file.filename == '':
flash('没有选择文件')
return redirect(request.url)
reMsg = '没有选择文件'
return jsonify({'status': reStatus, 'msg': reMsg})
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
filename = secure_filename(file.filename) # 安全过滤
file_path = os.path.join(myCongif.get_data('UPLOAD_FOLDER'), filename)
await file.save(file_path)
if check_file(file_path,2): #itype--2 是算法模型升级
strsql = (f"insert into upgrade (itype,filepath,model_name) values (2,'{file_path}','{model_name}')"
f" on conflict(itype,model_name) do update set filepath=excluded.filepath;")
# 检查上传文件的合法性,若符合要求移动到正式路径
filename_pre = filename.rsplit('.', 1)[0] # 除去到.zip
model_version, model_name_file, model_path = check_file(file_path, filename_pre, 2) # itype--2 是算法模型升级 1-系统升级
# 删除压缩包
os.remove(file_path)
if model_version and model_path:
strsql = (f"update model set version='{model_version}',model_path='{model_path}' "
f"where ID={mid};")
ret = mDBM.do_sql(strsql)
# session['model'] = file_path
if ret:
strsql = f"select id from upgrade where itype=2 and model_name='{model_name}';"
data=mDBM.do_select(strsql,1)
reStatus = data[0]
reMsg = "升级包上传成功"
reStatus = 1
reMsg = '升級算法成功'
#重启业务数据
restart_work(mid)
else:
reStatus = 0
reMsg = "升级包上传失败"
return jsonify({'status': reStatus, 'msg': reMsg})
reMsg = '修改数据库出错,请联系技术支持!!'
else:
flash('升级包不合法,请重新上传')
# return redirect(url_for('main.get_html', html='系统管理.html'))
return redirect(request.url)
reMsg = '升级包不合法,请重新上传!'
else:
flash('只允许上传zip文件')
return redirect(request.url)
reMsg = '只允许上传zip文件'
@api.route('/model/add',methods=['POST'])
@login_required
async def model_add(): #新增算法,需要先上传算法文件
model_name = (await request.form)['model_name']
upgrade_id = (await request.form)['upgrade_id'] #升级文件ID
###---需要根据升级包获取模型文件路径,算法版本号等信息,若根据upgrade_id获取不了对应的信息,则返回报错
###
strsql = f"select ID from model where model_name='{model_name}';"
data = mDBM.do_select(strsql,1)
if data:
reStatus = 0
reMsg = "算法名称重复,请修改!"
else:
strsql = f"insert into model (model_name) values ('{model_name}');" #还有参数未写全
ret = mDBM.do_sql(strsql)
if ret:
reStatus = 1
reMsg = "新增算法成功!"
else:
reStatus = 0
reMsg = "新增算法失败,请联系技术支持!"
return jsonify({'status': reStatus, 'msg': reMsg})
@api.route('/model/upgrade',methods=['POST'])
@api.route('/model/del',methods=['POST'])
@login_required
async def model_upgrade(): #升级算法,需要先上传算法文件
return jsonify(1)
async def model_del():
json_data = await request.get_json()
mid = json_data.get('mid')
#删除与该算法关联的通道相关数据
strsql = f"select channel_id from channel2model where model_id = {mid};"
datas = mDBM.do_select(strsql)
if datas: #有关联
#删与通道的关联信息 --c2m,schedule
mDBM.delC2M(mid,2)
#重启通道业务
for data in datas:
mMM.restartC2M(data[0]) #根该模型关联的所有通道都需要重启工作线程
@api.route('/model/config',methods=['GET'])
@login_required
async def model_config(): #获取算法的配置信息 --- list已经获取
ID = request.args.get('ID')
strsql = f"select model_name,version,duration_time,proportion from model where ID={ID};"
#删除算法文件
strsql = f"select model_path from model where ID = {mid};"
data = mDBM.do_select(strsql,1)
reMsg = {"model_name":data[0],"version":data[1],"duration_time":data[2],"proportion":data[3]}
return jsonify(reMsg)
if data:
py_path = data[0]
dir_path = py_path.rsplit('/',1)[0] #正常最后一层应该都是/--手动加的
print(dir_path)
shutil.rmtree(dir_path)
# 删该算法记录
strsql = f"delete from model where ID = {mid};"
mDBM.do_sql(strsql)
#正常来说删除一般不会失败
return jsonify({'status': 1, 'msg': "删除成功"})
@api.route('/model/changecnf',methods=['POST'])
@login_required
async def model_config_change(): #修改算法的配置信息
ID = (await request.form)['ID']
duration_time = (await request.form)['duration_time']
proportion = float((await request.form)['proportion'])
if proportion>0 and proportion < 1:
strsql = f"update model set duration_time='{duration_time}',proportion='{proportion}' where ID={ID};"
ret = mDBM.do_sql(strsql)
if ret:
reStatus = 1
reMsg = "修复算法配置成功"
json_data = await request.get_json()
mid = json_data.get('mid')
reStatus = 0
try:
duration_time = int(json_data.get('duration_time'))
proportion = float(json_data.get('proportion'))
if proportion > 0 and proportion < 1:
strsql = f"update model set duration_time='{duration_time}',proportion='{proportion}' where ID={mid};"
ret = mDBM.do_sql(strsql)
if ret:
reStatus = 1
reMsg = "修改算法配置成功"
#重启-工作线程
restart_work(mid)
else:
reMsg = "修改算法配置失败"
else:
reStatus = 0
reMsg = "修复算法配置失败"
else:
reStatus = 0
reMsg = "占比需要为大于0,小于1的值"
reMsg = "占比阈值需要为大于0,小于1的值"
except ValueError:
reMsg = "数据类型不对!"
return jsonify({'status': reStatus, 'msg': reMsg})

22
web/API/system.py

@ -6,6 +6,7 @@ from core.DBManager import mDBM
from core.Upload_file import allowed_file,check_file,update_system
from myutils.ConfigManager import myCongif
from myutils.ReManager import mReM
from myutils.IPManager import IPM
from werkzeug.utils import secure_filename
@api.route('/system/info',methods=['GET'])
@ -15,11 +16,28 @@ async def system_info(): #获取系统信息
data = mDBM.do_select(strsql,1)
strRet = ""
if data:
strRet = {"ID":data[0],"version":data[1],"dev_ip":data[2],"dev_mask":data[3],"dev_gateway":data[4],
"server_ip":data[5],"server_port":data[6]}
#获取wifilist
wifilist = IPM.get_wifi_list()
connected_wifi = IPM.get_connected_wifi()
print(connected_wifi)
strRet = {"ID":data[0],"version":data[1],"wired_type":data[2],"wired_ip":data[3],"wired_mask":data[4],
"wired_gateway":data[5],"wired_dns":data[6],"wireless_type":data[7],"wireless_ip":data[8],"wireless_mask":data[9],
"wireless_gateway":data[10],"wireless_dns":data[11],"service_ip":data[12],"service_port":data[13],
"ssid":connected_wifi,"wifi_passwd":data[15],"wifi_list":wifilist}
return jsonify(strRet) #它将Python对象转换为JSON格式的字符串,并将其作为HTTP响应的主体返回给客户端,
# 同时设置正确的Content-Type响应头,表明响应主体是JSON格式的数据。
@api.route('/system/area',methods=['GET'])
@login_required
async def area_info(): #获取系统信息
strsql = "select * from area;"
datas = mDBM.do_select(strsql)
strRet = ""
if datas:
strRet = [{'ID':data[0],'area_name':data[1]} for data in datas]
return jsonify(strRet)
@api.route('/system/upload',methods=['POST'])
@login_required
async def system_upload(): #上传系统升级文件

70
web/API/user.py

@ -1,5 +1,6 @@
import os
from quart import Quart, render_template, request, session, redirect, url_for,jsonify,send_file
import hashlib
from quart import Quart, render_template, request, session, redirect, url_for,jsonify,send_file,flash
from quart_sqlalchemy import SQLAlchemy
from quart_session import Session
from web.common.utils import generate_captcha,login_required
@ -19,22 +20,34 @@ async def user_get_code(): #获取验证码
@api.route('/user/login',methods=['POST'])
async def user_login(): #用户登录
username = (await request.form)['username']
password = (await request.form)['password']
captcha = (await request.form)['captcha']
try:
form = await request.form
username = form['username']
password = form['password']
captcha = form['captcha']
except Exception as e:
await flash('请求数据格式错误', 'error')
return redirect(url_for('main.login'))
#return jsonify({'error': '请求数据格式错误'}), 400
if captcha != session.get('captcha'):
#验证码验证过后,需要失效
print(session.get('captcha'))
return '验证码错误', 400
# 验证码验证过后,需要失效
session.pop('captcha', None)
await flash('验证码错误', 'error')
return redirect(url_for('main.login'))
#return jsonify({'error': '验证码错误'}), 400
#return 'captcha error!', 400
#比对用户名和密码
strsql = f"select password from user where username = '{username}'"
db_password = mDBM.do_select(strsql,1)
passwd_md5 = get_md5(password)
if db_password:
if db_password[0] == password: #后续需要对密码进行MD5加默
if db_password[0] == passwd_md5: #后续需要对密码进行MD5加默
print("登录成功")
session['user'] = username
return redirect(url_for('main.get_html', html='实时预览.html'))
return '用户名或密码错误', 400
return redirect(url_for('main.get_html', html='view_main.html'))
await flash('用户名或密码错误', 'error')
return redirect(url_for('main.login'))
@api.route('/user/userinfo',methods=['GET'])
@login_required
@ -75,19 +88,29 @@ async def user_adduser(): #新增用户
@api.route('/user/passwd',methods=['POST'])
@login_required
async def user_change_passwd(): #重置密码
username = (await request.form)['username']
password = myCongif.get_data('pw')
strsql = f"update user set password='{password}' where username='{username}';"
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '重置密码成功'
async def user_change_passwd(): #修改密码
json_data = await request.get_json()
oldpasswd = json_data.get('oldpasswd')
newpasswd = json_data.get('newpasswd')
old_md5= get_md5(oldpasswd)
print(old_md5)
strsql = f"select id from user where password='{old_md5}';"
data = mDBM.do_select(strsql,1)
reStatus = 0
if data:
new_md5 = get_md5(newpasswd)
strsql = f"update user set password = '{new_md5}' where password = '{old_md5}';"
ret = mDBM.do_sql(strsql)
if ret:
reStatus = 1
reMsg = '修改密码成功'
else:
reMsg = '修改密码失败,请联系技术支持!'
else:
reStatus = 0
reMsg = '重置密码失败,请联系管理员处理!'
reMsg = '原密码错误,请确认!'
return jsonify({'status':reStatus,'msg':reMsg})
@api.route('/user/changeuser',methods=['POST'])
@login_required
async def user_change_user_info(): #修改用户信息
@ -113,4 +136,9 @@ async def get_user(user_id):
else:
return jsonify({'error': 'User not found'}), 404
except Exception as e:
return handle_error(e)
return handle_error(e)
def get_md5(value):
md5 = hashlib.md5() # 创建一个md5对象
md5.update(value.encode('utf-8')) # 使用utf-8编码更新待计算的字符串
return md5.hexdigest() # 返回十六进制的MD5值

253
web/API/viedo.py

@ -5,6 +5,11 @@ from core.ModelManager import mMM
from core.DBManager import mDBM
from myutils.ConfigManager import myCongif
import logging
import time
import subprocess
from concurrent.futures import ThreadPoolExecutor
import threading
from collections import deque
# 配置日志
logging.basicConfig(level=logging.INFO)
@ -12,39 +17,10 @@ logger = logging.getLogger(__name__)
#-------------------基于WEBRTC实现拉流
#pcs = set() #创建一个空的集合,去重复且无序
pcs = {}
active_tasks = {} # 用来存储每个channel的任务
executor = ThreadPoolExecutor(max_workers=4)
'''
--------------基础信息--后续封装在函数里---------------
'''
# 打开摄像头
# def get_camera():
# cap = cv2.VideoCapture(0)
# if not cap.isOpened():
# raise IOError("Cannot open webcam")
# return cap
#
# cap = get_camera()
# last_image = None
# read_lock = threading.Lock()
# def camera_thread():
# global cap, last_image
# while True:
# try:
# ret, frame = cap.read()
# if not ret:
# logger.warning("Camera disconnected. Reconnecting...")
# cap.release()
# cap = get_camera()
# continue
# frame = cv2.resize(frame, (640, 480)) # 降低视频分辨率
# with read_lock:
# last_image = frame
# time.sleep(1.0/20)
# except Exception as e:
# logger.error(f"Error in camera thread: {e}")
# continue
#threading.Thread(target=camera_thread, daemon=True).start()
'''
---------------------传输--------------------------
'''
@ -141,20 +117,141 @@ async def get_stats(peer_connection):
# "msg":reMsg
# })
def stream_rtsp_to_flv(rtsp_url):
command = [
'ffmpeg',
'-i', rtsp_url, # 输入 RTSP 流
'-vcodec', 'libx264', # 视频编码器
'-f', 'flv', # 输出格式为 FLV
'pipe:1' # 输出到管道
]
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return process
async def handle_channel_rtf(channel_id,websocket):
rtsp_url = "rtsp://192.168.3.103/live1"
process = stream_rtsp_to_flv(rtsp_url)
try:
while True:
data = process.stdout.read(1024) # 从管道读取 FLV 数据
if not data:
break
await websocket.send(data) # 通过 WebSocket 发送 FLV 数据
except asyncio.CancelledError:
process.terminate() # 如果 WebSocket 连接关闭,则终止 ffmpeg 进程
finally:
process.terminate()
def send_frame_thread(channel_id,websocket):
pass
async def handle_channel(channel_id,websocket):
verify_rate = int(myCongif.get_data("verify_rate"))
error_max_count = verify_rate * int(myCongif.get_data("video_error_count")) # 视频帧捕获失败触发提示的上限
sleep_time = int(myCongif.get_data("cap_sleep_time"))
frame_interval = 1.0 / verify_rate # 用于帧率控制
last_frame_time = time.time() # 初始化个读帧时间
icount = 0
#视频传输缓冲区
#frame_buffer = deque(maxlen=10)
try:
cnode = mMM.verify_list.get_channel_data(channel_id) #ChannelManager.get_channel_data
if cnode is None:
print("---channel_id--错误--")
return
frame_count = 0
start_time = time.time()
all_time = 0
get_all_time = 0
send_all_time = 0
while True: # 这里的多线程并发,还需要验证检查
# 帧率控制帧率 ---输出暂时不控制帧率,有就传输
current_time = time.time()
elapsed_time = current_time - last_frame_time
if elapsed_time < frame_interval:
await asyncio.sleep(frame_interval - elapsed_time) # 若小于间隔时间则休眠
last_frame_time = time.time()
# 执行视频传输
#frame = mMM.verify_list.cm_get_last_frame(channel_id) # get_last_frame 用了try
get_stime = time.time()
frame = cnode.get_last_frame()
get_etime = time.time()
get_all_time = get_all_time + (get_etime - get_stime)
if frame is not None:
# frame_buffer.append(frame) #先放入缓冲区
#7print("KB---",len(frame)/1024)
icount = 0
send_stime = time.time()
await websocket.send(b'frame:'+frame)
send_etime = time.time()
send_all_time = send_all_time + (send_etime - send_stime)
else:
# print("frame is None")
icount += 1
if icount > error_max_count:
print(f"通道-{channel_id},长时间未获取图像,休眠一段时间后再获取。")
icount = 0
error_message = b'error:video_error'
await websocket.send(error_message)
await asyncio.sleep(sleep_time) # 等待视频重连时间
#----------输出时间-----------
# frame_count += 1
# end_time = time.time()
# # 计算时间差
# el_time = end_time - start_time
# all_time = all_time + (end_time - current_time)
# # 每隔一定时间(比如5秒)计算一次帧率
# if el_time >= 10:
# fps = frame_count / el_time
# print(f"{channel_id}当前帧率: {fps} FPS,循环次数:{frame_count},花费总耗时:{all_time}S,get耗时:{get_all_time},send耗时:{send_all_time}")
# # 重置计数器和时间
# frame_count = 0
# all_time = 0
# get_all_time = 0
# send_all_time = 0
# start_time = time.time()
except asyncio.CancelledError:
print(f"WebSocket connection for channel {channel_id} closed by client")
raise
except Exception as e:
print(f"Unexpected error: {e}")
finally:
print(f"Cleaning up resources for channel {channel_id}")
@api.websocket('/ws/video_feed/<int:channel_id>')
async def ws_video_feed(channel_id):
channel_data = mMM.verify_list.get_channel(channel_id)
frame_rate = myCongif.get_data("frame_rate")
while channel_data.bool_run: #这里的多线程并发,还需要验证检查
frame = channel_data.get_last_frame()
if frame is not None:
#img = frame.to_ndarray(format="bgr24")
# ret, buffer = cv2.imencode('.jpg', frame)
# if not ret:
# continue
# frame = buffer.tobytes()
await websocket.send(frame)
await asyncio.sleep(1.0 / frame_rate) # Adjust based on frame rate
print(f"New connection for channel: {channel_id}")
if channel_id in active_tasks:
active_tasks[channel_id].cancel()
try:
await active_tasks[channel_id] # 确保旧任务被完全取消
del active_tasks[channel_id]
except asyncio.CancelledError:
print(f"旧任务 {channel_id} 已取消")
try:
# 为每个通道创建独立的协程
shendtask = asyncio.create_task(handle_channel(channel_id, websocket))
#shendtask = asyncio.create_task(handle_channel_rtf(channel_id, websocket))
# 将任务存储到 active_tasks
active_tasks[channel_id] = shendtask
# 等待协程完成
await shendtask
except Exception as e:
print(f"Channel {channel_id} 出现异常: {e}")
finally:
# 移除已完成的任务
if channel_id in active_tasks:
del active_tasks[channel_id]
print(f"Cleaning up resources for channel {channel_id}")
@api.route('/shutdown', methods=['POST'])
async def shutdown():#这是全关 --需要修改
@ -163,24 +260,60 @@ async def shutdown():#这是全关 --需要修改
pcs.clear()
return 'Server shutting down...'
@api.route('/viewlist', methods=['GET'])
async def viewlist():#视频列表
count = request.args.get('count')
channel_list = []
element_list = []
name_list = []
if count:
strsql = (f"select t1.ID,t1.element_id,t1.channel_name,t2.area_name from channel t1 left join "
f"area t2 on t1.area_id =t2.id where element_id between 0 and {count};")
datas = mDBM.do_select(strsql)
for data in datas:
channel_list.append(data[0])
element_list.append(data[1])
name_list.append(f"{data[3]}--{data[2]}")
return jsonify({'clist': channel_list, 'elist': element_list,'nlist':name_list})
@api.route('/start_stream', methods=['POST'])
async def start_stream(): #开启视频通道,把视频通道编号和元素编号进行关联
json_data = await request.get_json()
channel_id = json_data.get('channel_id')
element_id = json_data.get('element_id')
reStatus = 0
reMsg = ""
strsql = f"select element_id from channel where ID = {channel_id};"
data = mDBM.do_select(strsql,1)
if data:
if not data[0] or data[0] == '':
strsql = f"update channel set element_id = '{element_id}' where ID={channel_id};"
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '播放视频配置成功!'
else:
reMsg = '播放视频配置失败,请联系技术支持!'
else:
index = int(data[0]) +1
reMsg = f"该视频通道已在:Video Stream {index}播放,请先关闭"
return jsonify({'status': reStatus, 'msg': reMsg})
@api.route('/close_stream', methods=['POST'])
async def close_stream(): # 需要修改
channel_id = (await request.form)['channel_id']
async def close_stream(): #关闭视频通道
json_data = await request.get_json()
element_id = json_data.get('element_id')
reStatus = 0
reMsg =""
if channel_id in pcs:
await pcs[channel_id].close()
pcs.pop(channel_id, None)
print(f'Stream {channel_id} closed.')
#数据库中该通道的关联关系要清除
strsql = f"update channel set element_id = NULL where ID={channel_id};"
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '关闭画面成功!'
else:
reStatus = 0
reMsg = '删除通道与组件关联关系失败,请联系技术支持!'
#数据库中该通道的关联关系要清除
strsql = f"update channel set element_id = '' where element_id={element_id};"
ret = mDBM.do_sql(strsql)
if ret == True:
reStatus = 1
reMsg = '关闭画面成功!'
else:
reMsg = "通道编号不在系统内,请检查!"
reMsg = '删除通道与组件关联关系失败,请联系技术支持!'
# ?关闭视频播放--业务逻辑-待确认后端是否需要执行
return jsonify({'status': reStatus, 'msg': reMsg})

89
web/API/warn.py

@ -0,0 +1,89 @@
import os
from . import api
from web.common.utils import login_required
from quart import jsonify, request,send_file
from core.DBManager import mDBM
@api.route('/warn/search_warn',methods=['POST'])
@login_required
async def warn_search(): #查询报警
#获取查询参数
json_data = await request.get_json()
s_count = json_data.get('s_count','')
e_count = json_data.get('e_count','')
model_name = json_data.get('model_name','')
channel_name = json_data.get('channel_name','')
start_time = json_data.get('start_time','')
end_time = json_data.get('end_time','')
# 动态拼接 SQL 语句
sql = "SELECT t1.*,t2.channel_name FROM warn t1 LEFT JOIN channel t2 ON t1.channel_id = t2.element_id WHERE 1=1"
if model_name:
sql += f" AND t1.model_name = {model_name}"
if channel_name:
sql += f" AND t2.channel_name = {channel_name}"
if start_time and end_time:
sql += f" AND t1.creat_time BETWEEN {start_time} AND {end_time}"
# 增加倒序排列和分页
sql += f" ORDER BY t1.creat_time DESC LIMIT {e_count} OFFSET {s_count}"
# 使用SQLAlchemy执行查询
try:
print(sql)
data = mDBM.do_select(sql)
# 将数据转换为JSON格式返回给前端
warn_list = [{"ID": warn[0], "model_name": warn[1], "video_path": warn[2], "img_path": warn[3],
"creat_time": warn[4], "channel_name": warn[6]} for warn in data]
return jsonify(warn_list)
except Exception as e:
return jsonify({"error": str(e)}), 500
@api.route('/warn/warn_img')
@login_required
async def warn_img():
# 获取图片路径参数
image_path = request.args.get('path')
if image_path and os.path.exists(image_path):
# 返回图片文件
return await send_file(image_path)
else:
# 图片不存在时,返回 404
return 'Image not found', 404
@api.route('/warn/warn_video')
@login_required
async def warn_video():
# 获取视频路径参数
video_path = request.args.get('path')
if video_path and os.path.exists(video_path):
# 返回视频文件流
return await send_file(video_path, as_attachment=True)
else:
# 视频文件不存在时,返回 404
return 'Video not found', 404
@api.route('/warn/warn_del',methods=['POST'])
@login_required
async def warn_del():
# 获取请求体中的报警ID数组
data = await request.get_json()
alarm_ids = data.get('alarmIds')
if not alarm_ids:
return jsonify({'success': False, 'message': '没有提供报警ID'}), 400
try:
# 根据报警ID进行删除数据的操作,这里是假设数据库删除操作
# 例如:delete_from_database(alarm_ids)
# 模拟删除成功
success = True
if success:
return jsonify({'success': True, 'message': '删除成功'})
else:
return jsonify({'success': False, 'message': '删除失败'})
except Exception as e:
return jsonify({'success': False, 'message': f'发生异常: {str(e)}'}), 500

6
web/__init__.py

@ -1,5 +1,6 @@
from quart import Quart,session,redirect, url_for
from quart_session import Session
from quart_cors import cors
from pymemcache.client import base
from .main import main
from .API import api
@ -31,14 +32,13 @@ class MemcachedSessionInterface: #只是能用,不明所以
def create_app():
app = Quart(__name__)
#相关配置--设置各种配置选项,这些选项会在整个应用程序中被访问和使用。
# app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
# app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'zfxxkj_2024_!@#'
if myCongif.get_data("model_platform") == "acl":
app.config['SESSION_TYPE'] = 'memcached' # session类型
elif myCongif.get_data("model_platform") =="cpu":
app.config['SESSION_TYPE'] = 'redis' # session类型
#app.config['SESSION_FILE_DIR'] = './sessions' # session保存路径
#app.config['SESSION_MEMCACHED'] = base.Client(('localhost', 11211))
app.config['SESSION_PERMANENT'] = True # 如果设置为True,则关闭浏览器session就失效。

2
web/main/__init__.py

@ -1,5 +1,5 @@
from quart import Blueprint
main = Blueprint('main', __name__,template_folder='templates')
main = Blueprint('main', __name__,static_folder='static/resources',template_folder='templates')
from . import routes

24
web/main/routes.py

@ -14,7 +14,6 @@ from werkzeug.utils import secure_filename
def login_required(f):
@wraps(f)
async def decorated_function(*args, **kwargs):
print("decorated_function3")
if 'user' not in session:
return redirect(url_for('main.index',error='未登录,请重新登录'))
return await f(*args, **kwargs)
@ -22,12 +21,27 @@ def login_required(f):
@main.route('/')
async def index():
print("index")
#error = request.args.get('error')
return await render_template('实时预览.html')
#return await render_template('登录.html',error=error)
#return await render_template('实时预览.html')
return await render_template('login.html')
#return await render_template('index_webrtc.html')
@main.route('/login', methods=['GET', 'POST'])
async def login():
if request.method == 'POST':
form = await request.form
username = form.get('username')
password = form.get('password')
# Add your login logic here
if username == 'admin' and password == 'password':
return redirect(url_for('main.dashboard')) # Assuming you have a dashboard route
else:
return "Invalid credentials", 401
return await render_template('login.html')
@main.route('/dashboard')
async def dashboard():
return "Welcome to the dashboard!"
# @main.route('/', methods=['GET', 'POST'])
# async def upload_file():
# if request.method == 'POST':

BIN
web/main/static/favicon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 70 KiB

BIN
web/main/static/favicon_bak.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

7
web/main/static/files/实时预览/data.js

File diff suppressed because one or more lines are too long

1397
web/main/static/files/实时预览/styles.css

File diff suppressed because it is too large

7
web/main/static/files/用户管理/data.js

File diff suppressed because one or more lines are too long

4032
web/main/static/files/用户管理/styles.css

File diff suppressed because it is too large

7
web/main/static/files/登录/data.js

@ -1,7 +0,0 @@
$axure.loadCurrentPage(
(function() {
var _ = function() { var r={},a=arguments; for(var i=0; i<a.length; i+=2) r[a[i]]=a[i+1]; return r; }
var _creator = function() { return _(b,c,d,e,f,_(g,h,i,_(j,k,l,k)),m,[],n,_(h,o),p,[q],r,_(s,t,u,v,g,w,x,_(),y,[],z,_(A,B,C,D,E,_(F,G,H,I),J,null,K,L,L,M,N,O,null,P,Q,R,S,T,U,V,Q,W,X,Y,_(F,G,H,Z),ba,Q,bb,X,bc,_(bd,be,bf,bg,bh,bg,bi,bg,bj,k,H,_(bk,bl,bm,bl,bn,bl,bo,bp)),i,_(j,k,l,k)),bq,_(),br,_(),bs,_(bt,[_(bu,bv,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(i,_(j,bD,l,bE),A,bF),bq,_(),bG,_(),bH,be),_(bu,bI,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(i,_(j,bD,l,bJ),A,bF,E,_(F,G,H,bK),Y,_(F,G,H,bL)),bq,_(),bG,_(),bH,be),_(bu,bM,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(bN,bO,i,_(j,bP,l,bQ),A,bR,bS,_(bT,bU,bV,bW),bX,bY),bq,_(),bG,_(),bH,be),_(bu,bZ,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(bN,bO,i,_(j,ca,l,cb),A,cc,bS,_(bT,cd,bV,ce)),bq,_(),bG,_(),bH,be),_(bu,cf,bw,h,bx,cg,u,bz,bA,bz,bB,bC,z,_(A,ch,V,Q,i,_(j,ci,l,cj),E,_(F,G,H,ck),Y,_(F,G,H,cl),bc,_(bd,be,bf,k,bh,k,bi,cm,bj,k,H,_(bk,bl,bm,bl,bn,bl,bo,cn)),co,_(bd,be,bf,k,bh,k,bi,cm,bj,k,H,_(bk,bl,bm,bl,bn,bl,bo,cn)),bS,_(bT,cp,bV,cq)),bq,_(),bG,_(),cr,_(cs,ct),bH,be),_(bu,cu,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(bN,bO,i,_(j,cv,l,cq),A,cw,bS,_(bT,cx,bV,cy)),bq,_(),bG,_(),bH,be),_(bu,cz,bw,h,bx,cA,u,cB,bA,cB,bB,bC,z,_(i,_(j,cC,l,cD),cE,_(cF,_(A,cG),cH,_(A,cI)),A,cJ,bS,_(bT,cK,bV,cL)),cM,be,bq,_(),bG,_(),cN,h),_(bu,cO,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(bN,bO,i,_(j,cP,l,cq),A,cw,bS,_(bT,cQ,bV,cR)),bq,_(),bG,_(),bH,be),_(bu,cS,bw,h,bx,cA,u,cB,bA,cB,bB,bC,z,_(i,_(j,cC,l,cD),cE,_(cF,_(A,cG),cH,_(A,cI)),A,cJ,bS,_(bT,cK,bV,cT)),cM,be,bq,_(),bG,_(),cN,h),_(bu,cU,bw,h,bx,cA,u,cB,bA,cB,bB,bC,z,_(i,_(j,cV,l,cD),cE,_(cF,_(A,cG),cH,_(A,cI)),A,cJ,bS,_(bT,cK,bV,cW)),cM,be,bq,_(),bG,_(),cN,h),_(bu,cX,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(bN,bO,i,_(j,cv,l,cq),A,cw,bS,_(bT,cx,bV,cY)),bq,_(),bG,_(),bH,be),_(bu,cZ,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(i,_(j,da,l,cj),A,db,bS,_(bT,cx,bV,dc),bX,dd),bq,_(),bG,_(),br,_(de,_(df,dg,dh,di,dj,[_(dh,h,dk,h,dl,be,dm,dn,dp,[_(dq,dr,dh,ds,dt,du,dv,_(dw,_(h,ds)),dx,_(dy,r,b,dz,dA,bC),dB,dC)])])),dD,bC,bH,be),_(bu,dE,bw,h,bx,dF,u,dG,bA,dG,bB,bC,z,_(i,_(j,da,l,dH),A,dI,J,null,bS,_(bT,dJ,bV,dK)),bq,_(),bG,_(),cr,_(cs,dL)),_(bu,dM,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(i,_(j,da,l,cj),A,dN,bS,_(bT,dJ,bV,dc),bX,dd),bq,_(),bG,_(),bH,be),_(bu,dO,bw,h,bx,by,u,bz,bA,bz,bB,bC,z,_(dP,_(F,G,H,dQ,dR,dS),i,_(j,dT,l,dU),A,dV,bS,_(bT,dW,bV,dX)),bq,_(),bG,_(),bH,be)])),dY,_(),dZ,_(ea,_(eb,ec),ed,_(eb,ee),ef,_(eb,eg),eh,_(eb,ei),ej,_(eb,ek),el,_(eb,em),en,_(eb,eo),ep,_(eb,eq),er,_(eb,es),et,_(eb,eu),ev,_(eb,ew),ex,_(eb,ey),ez,_(eb,eA),eB,_(eb,eC),eD,_(eb,eE)));};
var b="url",c="登录.html",d="generationDate",e=new Date(1716520879185.01),f="defaultAdaptiveView",g="name",h="",i="size",j="width",k=0,l="height",m="adaptiveViews",n="sketchKeys",o="s0",p="variables",q="OnLoadVariable",r="page",s="packageId",t="7ecba5060add4e8c88625127aa952ee2",u="type",v="Axure:Page",w="登录",x="notes",y="annotations",z="style",A="baseStyle",B="627587b6038d43cca051c114ac41ad32",C="pageAlignment",D="center",E="fill",F="fillType",G="solid",H="color",I=0xFFFFFFFF,J="image",K="imageAlignment",L="near",M="imageRepeat",N="auto",O="favicon",P="sketchFactor",Q="0",R="colorStyle",S="appliedColor",T="fontName",U="Applied Font",V="borderWidth",W="borderVisibility",X="all",Y="borderFill",Z=0xFF797979,ba="cornerRadius",bb="cornerVisibility",bc="outerShadow",bd="on",be=false,bf="offsetX",bg=5,bh="offsetY",bi="blurRadius",bj="spread",bk="r",bl=0,bm="g",bn="b",bo="a",bp=0.349019607843137,bq="adaptiveStyles",br="interactionMap",bs="diagram",bt="objects",bu="id",bv="c5bc1d2efee44f68879fd659e38e9747",bw="label",bx="friendlyType",by="Rectangle",bz="vectorShape",bA="styleType",bB="visible",bC=true,bD=1280,bE=800,bF="caddf88798f04a469d3bb16589ed2a5d",bG="imageOverrides",bH="generateCompound",bI="2c24030b551d41378f944055f4a44c64",bJ=90,bK=0xFF02A7F0,bL=0xFF81D3F8,bM="fad482ab9b5c46c1952d5aad4ea0a508",bN="fontWeight",bO="700",bP=254,bQ=45,bR="1111111151944dfba49f67fd55eb1f88",bS="location",bT="x",bU=61,bV="y",bW=23,bX="fontSize",bY="40px",bZ="bb91b2fe6e994c93abaa1907c4f474e4",ca=289,cb=21,cc="8c7a4c5ad69a4369a5f7788171ac0b32",cd=496,ce=750,cf="fd8428de1c954a7fb54cb8b737fa8cb8",cg="Shape",ch="26c731cb771b44a88eb8b6e97e78c80e",ci=35,cj=40,ck=0xFF000000,cl=0xFFFFFF,cm=10,cn=0.313725490196078,co="innerShadow",cp=1165,cq=28,cr="images",cs="normal~",ct="images/登录/u4.svg",cu="81dff38c4abb4c299d032505ce1bd3b8",cv=96,cw="b3a15c9ddde04520be40f94c8168891e",cx=427,cy=265,cz="214f4eb955814b23864a6056e1b34ac4",cA="Text Field",cB="textBox",cC=300,cD=25,cE="stateStyles",cF="hint",cG="4889d666e8ad4c5e81e59863039a5cc0",cH="disabled",cI="9bd0236217a94d89b0314c8c7fc75f16",cJ="44157808f2934100b68f2394a66b2bba",cK=553,cL=266,cM="HideHintOnFocused",cN="placeholderText",cO="c1e2c2c547d34189a097fc5a573d1e84",cP=72,cQ=451,cR=343,cS="79ffc447be8549799643c1ef0b212546",cT=345,cU="ddb9300483dd4254bdfbb4ca5ff5723c",cV=136,cW=423,cX="c309227fa1ce48a0b2b15877b05adacb",cY=421,cZ="c17788f3902d49daa20fbbe38be1daa4",da=140,db="cd64754845384de3872fb4a066432c1f",dc=521,dd="18px",de="onClick",df="eventType",dg="OnClick",dh="description",di="Click or Tap",dj="cases",dk="conditionString",dl="isNewIfGroup",dm="caseColorHex",dn="AB68FF",dp="actions",dq="action",dr="linkWindow",ds="Open 实时预览 in Current Window",dt="displayName",du="Open Link",dv="actionInfoDescriptions",dw="实时预览",dx="target",dy="targetType",dz="实时预览.html",dA="includeVariables",dB="linkType",dC="current",dD="tabbable",dE="476ed508a0e641c3821a489ba050926d",dF="Image",dG="imageBox",dH=47,dI="75a91ee5b9d042cfa01b8d565fe289c0",dJ=713,dK=412,dL="images/登录/u12.png",dM="24c27214a4004ee3becff6c24ff7cfe3",dN="c9f35713a1cf4e91a0f2dbac65e6fb5c",dO="70009ea6695547be8b66debf61616908",dP="foreGroundFill",dQ=0xFFD9001B,dR="opacity",dS=1,dT=196,dU=16,dV="2285372321d148ec80932747449c36c9",dW=657,dX=581,dY="masters",dZ="objectPaths",ea="c5bc1d2efee44f68879fd659e38e9747",eb="scriptId",ec="u0",ed="2c24030b551d41378f944055f4a44c64",ee="u1",ef="fad482ab9b5c46c1952d5aad4ea0a508",eg="u2",eh="bb91b2fe6e994c93abaa1907c4f474e4",ei="u3",ej="fd8428de1c954a7fb54cb8b737fa8cb8",ek="u4",el="81dff38c4abb4c299d032505ce1bd3b8",em="u5",en="214f4eb955814b23864a6056e1b34ac4",eo="u6",ep="c1e2c2c547d34189a097fc5a573d1e84",eq="u7",er="79ffc447be8549799643c1ef0b212546",es="u8",et="ddb9300483dd4254bdfbb4ca5ff5723c",eu="u9",ev="c309227fa1ce48a0b2b15877b05adacb",ew="u10",ex="c17788f3902d49daa20fbbe38be1daa4",ey="u11",ez="476ed508a0e641c3821a489ba050926d",eA="u12",eB="24c27214a4004ee3becff6c24ff7cfe3",eC="u13",eD="70009ea6695547be8b66debf61616908",eE="u14";
return _creator();
})());

763
web/main/static/files/登录/styles.css

@ -1,763 +0,0 @@
body {
margin:0px;
background-image:none;
position:relative;
left:0px;
width:1280px;
margin-left:auto;
margin-right:auto;
text-align:left;
}
.form_sketch {
border-color:transparent;
background-color:transparent;
}
#base {
position:absolute;
z-index:0;
}
#u0_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:1280px;
height:800px;
background:inherit;
background-color:rgba(255, 255, 255, 1);
box-sizing:border-box;
border-width:1px;
border-style:solid;
border-color:rgba(121, 121, 121, 1);
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
}
#u0 {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:1280px;
height:800px;
display:flex;
}
#u0 .text {
position:absolute;
align-self:center;
padding:2px 2px 2px 2px;
box-sizing:border-box;
width:100%;
}
#u0_text {
border-width:0px;
word-wrap:break-word;
text-transform:none;
visibility:hidden;
}
#u1_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:1280px;
height:90px;
background:inherit;
background-color:rgba(2, 167, 240, 1);
box-sizing:border-box;
border-width:1px;
border-style:solid;
border-color:rgba(129, 211, 248, 1);
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
}
#u1 {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:1280px;
height:90px;
display:flex;
}
#u1 .text {
position:absolute;
align-self:center;
padding:2px 2px 2px 2px;
box-sizing:border-box;
width:100%;
}
#u1_text {
border-width:0px;
word-wrap:break-word;
text-transform:none;
visibility:hidden;
}
#u2_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:254px;
height:45px;
background:inherit;
background-color:rgba(255, 255, 255, 0);
border:none;
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
font-size:40px;
}
#u2 {
border-width:0px;
position:absolute;
left:61px;
top:23px;
width:254px;
height:45px;
display:flex;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
font-size:40px;
}
#u2 .text {
position:absolute;
align-self:flex-start;
padding:0px 0px 0px 0px;
box-sizing:border-box;
width:100%;
}
#u2_text {
border-width:0px;
white-space:nowrap;
text-transform:none;
}
#u3_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:289px;
height:21px;
background:inherit;
background-color:rgba(255, 255, 255, 0);
border:none;
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
}
#u3 {
border-width:0px;
position:absolute;
left:496px;
top:750px;
width:289px;
height:21px;
display:flex;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
}
#u3 .text {
position:absolute;
align-self:flex-start;
padding:0px 0px 0px 0px;
box-sizing:border-box;
width:100%;
}
#u3_text {
border-width:0px;
word-wrap:break-word;
text-transform:none;
}
#u4_img {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:35px;
height:40px;
}
#u4 {
border-width:0px;
position:absolute;
left:1165px;
top:28px;
width:35px;
height:40px;
display:flex;
}
#u4 .text {
position:absolute;
align-self:center;
padding:2px 2px 2px 2px;
box-sizing:border-box;
width:100%;
}
#u4_text {
border-width:0px;
word-wrap:break-word;
text-transform:none;
visibility:hidden;
}
#u5_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:96px;
height:28px;
background:inherit;
background-color:rgba(255, 255, 255, 0);
border:none;
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
}
#u5 {
border-width:0px;
position:absolute;
left:427px;
top:265px;
width:96px;
height:28px;
display:flex;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
}
#u5 .text {
position:absolute;
align-self:flex-start;
padding:0px 0px 0px 0px;
box-sizing:border-box;
width:100%;
}
#u5_text {
border-width:0px;
white-space:nowrap;
text-transform:none;
}
#u6_input {
position:absolute;
left:0px;
top:0px;
width:300px;
height:25px;
padding:2px 2px 2px 2px;
font-family:'Arial Normal', 'Arial', sans-serif;
font-weight:400;
font-style:normal;
font-size:13px;
letter-spacing:normal;
color:#000000;
vertical-align:none;
text-align:left;
text-transform:none;
background-color:transparent;
border-color:transparent;
}
#u6_input.disabled {
position:absolute;
left:0px;
top:0px;
width:300px;
height:25px;
padding:2px 2px 2px 2px;
font-family:'Arial Normal', 'Arial', sans-serif;
font-weight:400;
font-style:normal;
font-size:13px;
letter-spacing:normal;
color:#000000;
vertical-align:none;
text-align:left;
text-transform:none;
background-color:transparent;
border-color:transparent;
}
#u6_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:300px;
height:25px;
background:inherit;
background-color:rgba(255, 255, 255, 1);
box-sizing:border-box;
border-width:1px;
border-style:solid;
border-color:rgba(121, 121, 121, 1);
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
}
#u6 {
border-width:0px;
position:absolute;
left:553px;
top:266px;
width:300px;
height:25px;
display:flex;
}
#u6 .text {
position:absolute;
align-self:center;
padding:2px 2px 2px 2px;
box-sizing:border-box;
width:100%;
}
#u6_div.disabled {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:300px;
height:25px;
background:inherit;
background-color:rgba(240, 240, 240, 1);
box-sizing:border-box;
border-width:1px;
border-style:solid;
border-color:rgba(121, 121, 121, 1);
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
}
#u6.disabled {
}
#u7_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:72px;
height:28px;
background:inherit;
background-color:rgba(255, 255, 255, 0);
border:none;
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
}
#u7 {
border-width:0px;
position:absolute;
left:451px;
top:343px;
width:72px;
height:28px;
display:flex;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
}
#u7 .text {
position:absolute;
align-self:flex-start;
padding:0px 0px 0px 0px;
box-sizing:border-box;
width:100%;
}
#u7_text {
border-width:0px;
white-space:nowrap;
text-transform:none;
}
#u8_input {
position:absolute;
left:0px;
top:0px;
width:300px;
height:25px;
padding:2px 2px 2px 2px;
font-family:'Arial Normal', 'Arial', sans-serif;
font-weight:400;
font-style:normal;
font-size:13px;
letter-spacing:normal;
color:#000000;
vertical-align:none;
text-align:left;
text-transform:none;
background-color:transparent;
border-color:transparent;
}
#u8_input.disabled {
position:absolute;
left:0px;
top:0px;
width:300px;
height:25px;
padding:2px 2px 2px 2px;
font-family:'Arial Normal', 'Arial', sans-serif;
font-weight:400;
font-style:normal;
font-size:13px;
letter-spacing:normal;
color:#000000;
vertical-align:none;
text-align:left;
text-transform:none;
background-color:transparent;
border-color:transparent;
}
#u8_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:300px;
height:25px;
background:inherit;
background-color:rgba(255, 255, 255, 1);
box-sizing:border-box;
border-width:1px;
border-style:solid;
border-color:rgba(121, 121, 121, 1);
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
}
#u8 {
border-width:0px;
position:absolute;
left:553px;
top:345px;
width:300px;
height:25px;
display:flex;
}
#u8 .text {
position:absolute;
align-self:center;
padding:2px 2px 2px 2px;
box-sizing:border-box;
width:100%;
}
#u8_div.disabled {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:300px;
height:25px;
background:inherit;
background-color:rgba(240, 240, 240, 1);
box-sizing:border-box;
border-width:1px;
border-style:solid;
border-color:rgba(121, 121, 121, 1);
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
}
#u8.disabled {
}
#u9_input {
position:absolute;
left:0px;
top:0px;
width:136px;
height:25px;
padding:2px 2px 2px 2px;
font-family:'Arial Normal', 'Arial', sans-serif;
font-weight:400;
font-style:normal;
font-size:13px;
letter-spacing:normal;
color:#000000;
vertical-align:none;
text-align:left;
text-transform:none;
background-color:transparent;
border-color:transparent;
}
#u9_input.disabled {
position:absolute;
left:0px;
top:0px;
width:136px;
height:25px;
padding:2px 2px 2px 2px;
font-family:'Arial Normal', 'Arial', sans-serif;
font-weight:400;
font-style:normal;
font-size:13px;
letter-spacing:normal;
color:#000000;
vertical-align:none;
text-align:left;
text-transform:none;
background-color:transparent;
border-color:transparent;
}
#u9_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:136px;
height:25px;
background:inherit;
background-color:rgba(255, 255, 255, 1);
box-sizing:border-box;
border-width:1px;
border-style:solid;
border-color:rgba(121, 121, 121, 1);
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
}
#u9 {
border-width:0px;
position:absolute;
left:553px;
top:423px;
width:136px;
height:25px;
display:flex;
}
#u9 .text {
position:absolute;
align-self:center;
padding:2px 2px 2px 2px;
box-sizing:border-box;
width:100%;
}
#u9_div.disabled {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:136px;
height:25px;
background:inherit;
background-color:rgba(240, 240, 240, 1);
box-sizing:border-box;
border-width:1px;
border-style:solid;
border-color:rgba(121, 121, 121, 1);
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
}
#u9.disabled {
}
#u10_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:96px;
height:28px;
background:inherit;
background-color:rgba(255, 255, 255, 0);
border:none;
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
}
#u10 {
border-width:0px;
position:absolute;
left:427px;
top:421px;
width:96px;
height:28px;
display:flex;
font-family:'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
font-weight:700;
font-style:normal;
}
#u10 .text {
position:absolute;
align-self:flex-start;
padding:0px 0px 0px 0px;
box-sizing:border-box;
width:100%;
}
#u10_text {
border-width:0px;
white-space:nowrap;
text-transform:none;
}
#u11_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:140px;
height:40px;
background:inherit;
background-color:rgba(22, 155, 213, 1);
border:none;
border-radius:5px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
font-size:18px;
}
#u11 {
border-width:0px;
position:absolute;
left:427px;
top:521px;
width:140px;
height:40px;
display:flex;
font-size:18px;
}
#u11 .text {
position:absolute;
align-self:center;
padding:2px 2px 2px 2px;
box-sizing:border-box;
width:100%;
}
#u11_text {
border-width:0px;
word-wrap:break-word;
text-transform:none;
}
#u12_img {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:140px;
height:47px;
}
#u12 {
border-width:0px;
position:absolute;
left:713px;
top:412px;
width:140px;
height:47px;
display:flex;
}
#u12 .text {
position:absolute;
align-self:center;
padding:2px 2px 2px 2px;
box-sizing:border-box;
width:100%;
}
#u12_text {
border-width:0px;
word-wrap:break-word;
text-transform:none;
visibility:hidden;
}
#u13_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:140px;
height:40px;
background:inherit;
background-color:rgba(255, 255, 255, 1);
box-sizing:border-box;
border-width:1px;
border-style:solid;
border-color:rgba(121, 121, 121, 1);
border-radius:5px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
font-size:18px;
}
#u13 {
border-width:0px;
position:absolute;
left:713px;
top:521px;
width:140px;
height:40px;
display:flex;
font-size:18px;
}
#u13 .text {
position:absolute;
align-self:center;
padding:2px 2px 2px 2px;
box-sizing:border-box;
width:100%;
}
#u13_text {
border-width:0px;
word-wrap:break-word;
text-transform:none;
}
#u14_div {
border-width:0px;
position:absolute;
left:0px;
top:0px;
width:196px;
height:16px;
background:inherit;
background-color:rgba(255, 255, 255, 0);
border:none;
border-radius:0px;
-moz-box-shadow:none;
-webkit-box-shadow:none;
box-shadow:none;
color:#D9001B;
}
#u14 {
border-width:0px;
position:absolute;
left:657px;
top:581px;
width:196px;
height:16px;
display:flex;
color:#D9001B;
}
#u14 .text {
position:absolute;
align-self:flex-start;
padding:0px 0px 0px 0px;
box-sizing:border-box;
width:100%;
}
#u14_text {
border-width:0px;
white-space:nowrap;
text-transform:none;
}

7
web/main/static/files/算法管理/data.js

File diff suppressed because one or more lines are too long

3945
web/main/static/files/算法管理/styles.css

File diff suppressed because it is too large

7
web/main/static/files/系统管理/data.js

File diff suppressed because one or more lines are too long

1604
web/main/static/files/系统管理/styles.css

File diff suppressed because it is too large

7
web/main/static/files/通道管理/data.js

File diff suppressed because one or more lines are too long

6164
web/main/static/files/通道管理/styles.css

File diff suppressed because it is too large

BIN
web/main/static/images/实时预览/u20_menu.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

BIN
web/main/static/images/实时预览/u22.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 B

BIN
web/main/static/images/实时预览/u26.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

BIN
web/main/static/images/实时预览/u32.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

BIN
web/main/static/images/实时预览/u48.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 B

BIN
web/main/static/images/实时预览/u48_selected.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 B

BIN
web/main/static/images/用户管理/u410.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

BIN
web/main/static/images/用户管理/u411.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

BIN
web/main/static/images/用户管理/u412.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

BIN
web/main/static/images/用户管理/u413.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 B

BIN
web/main/static/images/用户管理/u441.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

BIN
web/main/static/images/用户管理/u442.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

BIN
web/main/static/images/用户管理/u443.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save