Compare commits
No commits in common. "2c4b880d93215d79ef0384bdd89b84a993251098" and "5cc22405a42d1ce61317f2fa296430ae5267ddcb" have entirely different histories.
2c4b880d93
...
5cc22405a4
|
|
@ -1,8 +0,0 @@
|
|||
1.2025.01.21把之前的tuoheng alg仓库代码重新开个仓库 (1)在config/service/dsp_test_service.yml里面添加参数,控制存储用的oss还是minio storage_source: 1 2.2025.02.06 (1)修改代码,把mqtt读取加入到系统中。config/service/dsp_test_service.yml,中添加mqtt_flag,决定是否启用。 (2)修改了minio情况下的,文件名命名方式。 3.2025.02.12 (1)增加了对alg算法开发的代码。可以通过配置文件config/service/dsp_test_service.yml中algSwitch: true,决定是否启用。
|
||||
|
||||
4、2025.07.10 周树亮 - 增加人群计数,自研车牌模型,裸土覆盖3个场景
|
||||
|
||||
5、江朝庆 -- 0715
|
||||
1)代码整理,删除冗余代码。
|
||||
2)增加requirements.txt,方便部署
|
||||
3) logs
|
||||
|
|
@ -19,21 +19,22 @@ from util.QueUtil import put_queue, get_no_block_queue, clear_queue
|
|||
import io
|
||||
from util.LocationUtils import locate_byMqtt
|
||||
|
||||
|
||||
class FileUpload(Thread):
|
||||
__slots__ = ('_fb_queue', '_context', '_image_queue', '_analyse_type', '_msg', '_mqtt_list')
|
||||
__slots__ = ('_fb_queue', '_context', '_image_queue', '_analyse_type', '_msg','_mqtt_list')
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__()
|
||||
self._fb_queue, self._context, self._msg, self._image_queue, self._analyse_type, self._mqtt_list = args
|
||||
self._fb_queue, self._context, self._msg, self._image_queue, self._analyse_type,self._mqtt_list = args
|
||||
self._storage_source = self._context['service']['storage_source']
|
||||
self._algStatus = False # 默认关闭
|
||||
|
||||
self._algStatus = False # 默认关闭
|
||||
|
||||
# self._algStatus = True # 默认关闭
|
||||
self._algSwitch = self._context['service']['algSwitch']
|
||||
|
||||
# 0521:
|
||||
default_enabled = str(self._msg.get("defaultEnabled", "True")).lower() == "true"
|
||||
self._algSwitch = self._context['service']['algSwitch']
|
||||
|
||||
|
||||
|
||||
#0521:
|
||||
default_enabled = str(self._msg.get("defaultEnabled", "True")).lower() == "true"
|
||||
if default_enabled:
|
||||
print("执行默认程序(defaultEnabled=True)")
|
||||
self._algSwitch = True
|
||||
|
|
@ -43,15 +44,15 @@ class FileUpload(Thread):
|
|||
# 这里放非默认逻辑的代码
|
||||
self._algSwitch = False
|
||||
|
||||
print("---line46 :FileUploadThread.py---", self._algSwitch)
|
||||
print("---line46 :FileUploadThread.py---",self._algSwitch)
|
||||
|
||||
|
||||
# 如果任务是在线、离线处理,则用此类
|
||||
#如果任务是在线、离线处理,则用此类
|
||||
class ImageFileUpload(FileUpload):
|
||||
__slots__ = ()
|
||||
|
||||
# @staticmethod
|
||||
def handle_image(self, frame_msg, frame_step):
|
||||
#@staticmethod
|
||||
def handle_image(self,frame_msg, frame_step):
|
||||
# (high_score_image["code"], all_frames, draw_config["font_config"])
|
||||
# high_score_image["code"][code][cls] = (frame, frame_index_list[i], cls_list)
|
||||
det_xywh, frame, current_frame, all_frames, font_config = frame_msg
|
||||
|
|
@ -64,7 +65,8 @@ class ImageFileUpload(FileUpload):
|
|||
模型编号:modeCode
|
||||
检测目标:detectTargetCode
|
||||
'''
|
||||
print('*' * 100, ' mqtt_list:', len(self._mqtt_list))
|
||||
print('*'*100,' mqtt_list:',len(self._mqtt_list))
|
||||
|
||||
|
||||
model_info = []
|
||||
# 更加模型编码解析数据
|
||||
|
|
@ -76,10 +78,12 @@ class ImageFileUpload(FileUpload):
|
|||
for target in target_list:
|
||||
# 自研车牌模型判断
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code):
|
||||
draw_name_ocr(target[1], aFrame, target[4])
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code):
|
||||
draw_name_crowd(target[1], aFrame, target[4])
|
||||
box = [target[1][0][0], target[1][0][1], target[1][3][0], target[1][3][1]]
|
||||
draw_name_ocr(box, aFrame, target[4], target[0])
|
||||
cls = 0
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code):
|
||||
draw_name_crowd(target[3], aFrame, target[4], cls)
|
||||
cls = 0
|
||||
else:
|
||||
draw_painting_joint(target[1], aFrame, target[3], target[2], target[4], font_config,
|
||||
target[5])
|
||||
|
|
@ -111,15 +115,13 @@ class ImageFileUpload(FileUpload):
|
|||
image_queue, fb_queue, analyse_type = self._image_queue, self._fb_queue, self._analyse_type
|
||||
service_timeout = int(service["timeout"])
|
||||
frame_step = int(service["filter"]["frame_step"]) + 120
|
||||
if msg['taskType'] == 0:
|
||||
self._algStatus = False
|
||||
else:
|
||||
self._algStatus = True
|
||||
if msg['taskType']==0: self._algStatus = False
|
||||
else: self._algStatus = True
|
||||
try:
|
||||
with ThreadPoolExecutor(max_workers=2) as t:
|
||||
# 初始化oss客户端
|
||||
if self._storage_source == 1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id)
|
||||
if self._storage_source==1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id )
|
||||
else:
|
||||
aliyunOssSdk = AliyunOssSdk(base_dir, env, request_id)
|
||||
start_time = time()
|
||||
|
|
@ -135,14 +137,12 @@ class ImageFileUpload(FileUpload):
|
|||
if image_msg is not None:
|
||||
|
||||
if image_msg[0] == 2:
|
||||
logger.info("图片上传线程收到命令:{}, requestId: {}", image_msg[1], request_id)
|
||||
logger.info("图片上传线程收到命令:{}, requestId: {}",image_msg[1] ,request_id)
|
||||
if 'stop' == image_msg[1]:
|
||||
logger.info("开始停止图片上传线程, requestId:{}", request_id)
|
||||
break
|
||||
if 'algStart' == image_msg[1]: self._algStatus = True; logger.info(
|
||||
"图片上传线程,执行算法开启命令, requestId:{}", request_id)
|
||||
if 'algStop' == image_msg[1]: self._algStatus = False; logger.info(
|
||||
"图片上传线程,执行算法关闭命令, requestId:{}", request_id)
|
||||
if 'algStart' == image_msg[1]: self._algStatus = True; logger.info("图片上传线程,执行算法开启命令, requestId:{}", request_id)
|
||||
if 'algStop' == image_msg[1]: self._algStatus = False; logger.info("图片上传线程,执行算法关闭命令, requestId:{}", request_id)
|
||||
|
||||
if image_msg[0] == 1:
|
||||
image_result = self.handle_image(image_msg[1], frame_step)
|
||||
|
|
@ -153,8 +153,8 @@ class ImageFileUpload(FileUpload):
|
|||
image_result["last_frame"],
|
||||
analyse_type,
|
||||
"OR", "0", "0", request_id)
|
||||
if self._storage_source == 1:
|
||||
or_future = t.submit(minioSdk.put_object, or_image, or_image_name)
|
||||
if self._storage_source==1:
|
||||
or_future = t.submit(minioSdk.put_object, or_image,or_image_name)
|
||||
else:
|
||||
or_future = t.submit(aliyunOssSdk.put_object, or_image_name, or_image.tobytes())
|
||||
task.append(or_future)
|
||||
|
|
@ -169,38 +169,38 @@ class ImageFileUpload(FileUpload):
|
|||
model_info["modelCode"],
|
||||
model_info["detectTargetCode"],
|
||||
request_id)
|
||||
if self._storage_source == 1:
|
||||
if self._storage_source==1:
|
||||
ai_future = t.submit(minioSdk.put_object, ai_image,
|
||||
ai_image_name)
|
||||
ai_image_name)
|
||||
else:
|
||||
ai_future = t.submit(aliyunOssSdk.put_object, ai_image_name,
|
||||
ai_image.tobytes())
|
||||
ai_image.tobytes())
|
||||
|
||||
task.append(ai_future)
|
||||
# msg_list.append(message_feedback(request_id,
|
||||
#msg_list.append(message_feedback(request_id,
|
||||
# AnalysisStatus.RUNNING.value,
|
||||
# analyse_type, "", "", "",
|
||||
# or_image_name,
|
||||
# ai_image_name,
|
||||
# model_info['modelCode'],
|
||||
# model_info['detectTargetCode']))
|
||||
remote_image_list = []
|
||||
remote_image_list=[]
|
||||
for tk in task:
|
||||
remote_image_list.append(tk.result())
|
||||
remote_image_list.append( tk.result())
|
||||
|
||||
for ii, model_info in enumerate(model_info_list):
|
||||
msg_list.append(message_feedback(request_id,
|
||||
for ii,model_info in enumerate(model_info_list):
|
||||
msg_list.append( message_feedback(request_id,
|
||||
AnalysisStatus.RUNNING.value,
|
||||
analyse_type, "", "", "",
|
||||
remote_image_list[0],
|
||||
remote_image_list[ii + 1],
|
||||
remote_image_list[ii+1],
|
||||
model_info['modelCode'],
|
||||
model_info['detectTargetCode'],
|
||||
longitude=model_info['gps'][0],
|
||||
latitude=model_info['gps'][1],
|
||||
))
|
||||
) )
|
||||
|
||||
if (not self._algSwitch) or (self._algStatus and self._algSwitch):
|
||||
if (not self._algSwitch) or ( self._algStatus and self._algSwitch):
|
||||
for msg in msg_list:
|
||||
put_queue(fb_queue, msg, timeout=2, is_ex=False)
|
||||
del task, msg_list
|
||||
|
|
@ -227,7 +227,7 @@ def build_image_name(*args):
|
|||
random_num, mode_type, modeCode, target, image_type)
|
||||
|
||||
|
||||
# 如果任务是图像处理,则用此类
|
||||
#如果任务是图像处理,则用此类
|
||||
class ImageTypeImageFileUpload(Thread):
|
||||
__slots__ = ('_fb_queue', '_context', '_image_queue', '_analyse_type', '_msg')
|
||||
|
||||
|
|
@ -235,7 +235,6 @@ class ImageTypeImageFileUpload(Thread):
|
|||
super().__init__()
|
||||
self._fb_queue, self._context, self._msg, self._image_queue, self._analyse_type = args
|
||||
self._storage_source = self._context['service']['storage_source']
|
||||
|
||||
@staticmethod
|
||||
def handle_image(det_xywh, copy_frame, font_config):
|
||||
"""
|
||||
|
|
@ -257,10 +256,9 @@ class ImageTypeImageFileUpload(Thread):
|
|||
for target in target_list:
|
||||
# 自研车牌模型判断
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code):
|
||||
draw_name_ocr(target, aiFrame, font_config[cls])
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or \
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code):
|
||||
draw_name_crowd(target, aiFrame, font_config[cls])
|
||||
draw_name_ocr(target[1], aiFrame, font_config[cls], target[0])
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code):
|
||||
draw_name_crowd(target[1],aiFrame,font_config[cls],target[0])
|
||||
else:
|
||||
draw_painting_joint(target[1], aiFrame, target[3], target[2], target[4], font_config)
|
||||
|
||||
|
|
@ -289,8 +287,8 @@ class ImageTypeImageFileUpload(Thread):
|
|||
with ThreadPoolExecutor(max_workers=2) as t:
|
||||
try:
|
||||
# 初始化oss客户端
|
||||
if self._storage_source == 1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id)
|
||||
if self._storage_source==1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id )
|
||||
else:
|
||||
aliyunOssSdk = AliyunOssSdk(base_dir, env, request_id)
|
||||
|
||||
|
|
@ -315,14 +313,14 @@ class ImageTypeImageFileUpload(Thread):
|
|||
ai_image_name = build_image_name(0, 0, analyse_type, "AI", result.get("modelCode"),
|
||||
result.get("type"), request_id)
|
||||
|
||||
if self._storage_source == 1:
|
||||
ai_future = t.submit(minioSdk.put_object, copy_frame, ai_image_name)
|
||||
if self._storage_source==1:
|
||||
ai_future = t.submit(minioSdk.put_object, copy_frame,ai_image_name)
|
||||
else:
|
||||
ai_future = t.submit(aliyunOssSdk.put_object, ai_image_name, copy_frame)
|
||||
|
||||
task.append(ai_future)
|
||||
remote_names.append(ai_image_name)
|
||||
# msg_list.append(message_feedback(request_id,
|
||||
#msg_list.append(message_feedback(request_id,
|
||||
# AnalysisStatus.RUNNING.value,
|
||||
# analyse_type, "", "", "",
|
||||
# image_url,
|
||||
|
|
@ -338,12 +336,12 @@ class ImageTypeImageFileUpload(Thread):
|
|||
if image_url is None:
|
||||
or_result, or_image = cv2.imencode(".jpg", image_result.get("or_frame"))
|
||||
image_url_0 = build_image_name(image_result.get("current_frame"),
|
||||
image_result.get("last_frame"),
|
||||
analyse_type,
|
||||
"OR", "0", "O", request_id)
|
||||
image_result.get("last_frame"),
|
||||
analyse_type,
|
||||
"OR", "0", "O", request_id)
|
||||
|
||||
if self._storage_source == 1:
|
||||
or_future = t.submit(minioSdk.put_object, or_image, image_url_0)
|
||||
if self._storage_source==1:
|
||||
or_future = t.submit(minioSdk.put_object, or_image,image_url_0)
|
||||
else:
|
||||
or_future = t.submit(aliyunOssSdk.put_object, image_url_0,
|
||||
or_image.tobytes())
|
||||
|
|
@ -359,14 +357,14 @@ class ImageTypeImageFileUpload(Thread):
|
|||
model_info.get("modelCode"),
|
||||
model_info.get("detectTargetCode"),
|
||||
request_id)
|
||||
if self._storage_source == 1:
|
||||
ai_future = t.submit(minioSdk.put_object, ai_image, ai_image_name)
|
||||
if self._storage_source==1:
|
||||
ai_future = t.submit(minioSdk.put_object, ai_image, ai_image_name)
|
||||
else:
|
||||
ai_future = t.submit(aliyunOssSdk.put_object, ai_image_name,
|
||||
ai_image.tobytes())
|
||||
task.append(ai_future)
|
||||
remote_names.append(ai_image_name)
|
||||
# msg_list.append(message_feedback(request_id,
|
||||
#msg_list.append(message_feedback(request_id,
|
||||
# AnalysisStatus.RUNNING.value,
|
||||
# analyse_type, "", "", "",
|
||||
# image_url,
|
||||
|
|
@ -391,12 +389,12 @@ class ImageTypeImageFileUpload(Thread):
|
|||
else:
|
||||
if image_result:
|
||||
if image_url is None:
|
||||
for ii in range(len(remote_names) - 1):
|
||||
for ii in range(len(remote_names)-1):
|
||||
msg_list.append(message_feedback(request_id,
|
||||
AnalysisStatus.RUNNING.value,
|
||||
analyse_type, "", "", "",
|
||||
remote_url_list[0],
|
||||
remote_url_list[1 + ii],
|
||||
remote_url_list[1+ii],
|
||||
model_info.get('modelCode'),
|
||||
model_info.get('detectTargetCode'),
|
||||
analyse_results=result))
|
||||
|
|
@ -408,8 +406,7 @@ class ImageTypeImageFileUpload(Thread):
|
|||
image_url,
|
||||
remote_url_list[ii],
|
||||
model_info_list[ii].get('modelCode'),
|
||||
model_info_list[ii].get(
|
||||
'detectTargetCode'),
|
||||
model_info_list[ii].get('detectTargetCode'),
|
||||
analyse_results=result))
|
||||
|
||||
for msg in msg_list:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,305 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from threading import Thread
|
||||
from time import sleep, time
|
||||
from traceback import format_exc
|
||||
|
||||
from loguru import logger
|
||||
import cv2
|
||||
|
||||
from entity.FeedBack import message_feedback
|
||||
from enums.ExceptionEnum import ExceptionType
|
||||
from exception.CustomerException import ServiceException
|
||||
from util.AliyunSdk import AliyunOssSdk
|
||||
from util.MinioSdk import MinioSdk
|
||||
from util import TimeUtils
|
||||
from enums.AnalysisStatusEnum import AnalysisStatus
|
||||
from util.PlotsUtils import draw_painting_joint
|
||||
from util.QueUtil import put_queue, get_no_block_queue, clear_queue
|
||||
import io
|
||||
|
||||
class FileUpload(Thread):
|
||||
__slots__ = ('_fb_queue', '_context', '_image_queue', '_analyse_type', '_msg')
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__()
|
||||
self._fb_queue, self._context, self._msg, self._image_queue, self._analyse_type = args
|
||||
self._storage_source = self._context['service']['storage_source']
|
||||
|
||||
class ImageFileUpload(FileUpload):
|
||||
__slots__ = ()
|
||||
|
||||
@staticmethod
|
||||
def handle_image(frame_msg, frame_step):
|
||||
# (high_score_image["code"], all_frames, draw_config["font_config"])
|
||||
# high_score_image["code"][code][cls] = (frame, frame_index_list[i], cls_list)
|
||||
det_xywh, frame, current_frame, all_frames, font_config = frame_msg
|
||||
'''
|
||||
det_xywh:{
|
||||
'code':{
|
||||
1: [[detect_targets_code, box, score, label_array, color]]
|
||||
}
|
||||
}
|
||||
模型编号:modeCode
|
||||
检测目标:detectTargetCode
|
||||
'''
|
||||
model_info = []
|
||||
# 更加模型编码解析数据
|
||||
for code, det_list in det_xywh.items():
|
||||
if len(det_list) > 0:
|
||||
for cls, target_list in det_list.items():
|
||||
if len(target_list) > 0:
|
||||
aFrame = frame.copy()
|
||||
for target in target_list:
|
||||
draw_painting_joint(target[1], aFrame, target[3], target[2], target[4], font_config, target[5])
|
||||
model_info.append({"modelCode": str(code), "detectTargetCode": str(cls), "aFrame": aFrame})
|
||||
if len(model_info) > 0:
|
||||
image_result = {
|
||||
"or_frame": frame,
|
||||
"model_info": model_info,
|
||||
"current_frame": current_frame,
|
||||
"last_frame": current_frame + frame_step
|
||||
}
|
||||
return image_result
|
||||
return None
|
||||
|
||||
def run(self):
|
||||
msg, context = self._msg, self._context
|
||||
service = context["service"]
|
||||
base_dir, env, request_id = context["base_dir"], context["env"], msg["request_id"]
|
||||
logger.info("启动图片上传线程, requestId: {}", request_id)
|
||||
image_queue, fb_queue, analyse_type = self._image_queue, self._fb_queue, self._analyse_type
|
||||
service_timeout = int(service["timeout"])
|
||||
frame_step = int(service["filter"]["frame_step"]) + 120
|
||||
try:
|
||||
with ThreadPoolExecutor(max_workers=2) as t:
|
||||
# 初始化oss客户端
|
||||
if self._storage_source==1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id )
|
||||
else:
|
||||
aliyunOssSdk = AliyunOssSdk(base_dir, env, request_id)
|
||||
start_time = time()
|
||||
while True:
|
||||
try:
|
||||
if time() - start_time > service_timeout:
|
||||
logger.error("图片上传线程运行超时, requestId: {}", request_id)
|
||||
break
|
||||
raise ServiceException(ExceptionType.TASK_EXCUTE_TIMEOUT.value[0],
|
||||
ExceptionType.TASK_EXCUTE_TIMEOUT.value[1])
|
||||
# 获取队列中的消息
|
||||
image_msg = get_no_block_queue(image_queue)
|
||||
if image_msg is not None:
|
||||
if image_msg[0] == 2:
|
||||
if 'stop' == image_msg[1]:
|
||||
logger.info("开始停止图片上传线程, requestId:{}", request_id)
|
||||
break
|
||||
if image_msg[0] == 1:
|
||||
image_result = self.handle_image(image_msg[1], frame_step)
|
||||
if image_result is not None:
|
||||
task = []
|
||||
or_image = cv2.imencode(".jpg", image_result["or_frame"])[1]
|
||||
or_image_name = build_image_name(image_result["current_frame"],
|
||||
image_result["last_frame"],
|
||||
analyse_type,
|
||||
"OR", "0", "0", request_id)
|
||||
if self._storage_source==1:
|
||||
or_future = t.submit(minioSdk.put_object, or_image,or_image_name)
|
||||
else:
|
||||
or_future = t.submit(aliyunOssSdk.put_object, or_image_name, or_image.tobytes())
|
||||
task.append(or_future)
|
||||
model_info_list = image_result["model_info"]
|
||||
msg_list = []
|
||||
for model_info in model_info_list:
|
||||
ai_image = cv2.imencode(".jpg", model_info["aFrame"])[1]
|
||||
ai_image_name = build_image_name(image_result["current_frame"],
|
||||
image_result["last_frame"],
|
||||
analyse_type,
|
||||
"AI",
|
||||
model_info["modelCode"],
|
||||
model_info["detectTargetCode"],
|
||||
request_id)
|
||||
if self._storage_source==1:
|
||||
ai_future = t.submit(minioSdk.put_object, ai_image,
|
||||
ai_image_name)
|
||||
else:
|
||||
ai_future = t.submit(aliyunOssSdk.put_object, ai_image_name,
|
||||
ai_image.tobytes())
|
||||
|
||||
task.append(ai_future)
|
||||
msg_list.append(message_feedback(request_id,
|
||||
AnalysisStatus.RUNNING.value,
|
||||
analyse_type, "", "", "",
|
||||
or_image_name,
|
||||
ai_image_name,
|
||||
model_info['modelCode'],
|
||||
model_info['detectTargetCode']))
|
||||
for tk in task:
|
||||
tk.result()
|
||||
for msg in msg_list:
|
||||
put_queue(fb_queue, msg, timeout=2, is_ex=False)
|
||||
del task, msg_list
|
||||
else:
|
||||
sleep(1)
|
||||
del image_msg
|
||||
except Exception:
|
||||
logger.error("图片上传异常:{}, requestId:{}", format_exc(), request_id)
|
||||
finally:
|
||||
logger.info("停止图片上传线程0, requestId:{}", request_id)
|
||||
clear_queue(image_queue)
|
||||
logger.info("停止图片上传线程1, requestId:{}", request_id)
|
||||
|
||||
|
||||
def build_image_name(*args):
|
||||
"""
|
||||
{requestId}/{time_now}_frame-{current_frame}-{last_frame}_type_{random_num}-{mode_type}" \
|
||||
"-{modeCode}-{target}_{image_type}.jpg
|
||||
"""
|
||||
current_frame, last_frame, mode_type, image_type, modeCode, target, request_id = args
|
||||
random_num = TimeUtils.now_date_to_str(TimeUtils.YMDHMSF)
|
||||
time_now = TimeUtils.now_date_to_str("%Y-%m-%d-%H-%M-%S")
|
||||
return "%s/%s_frame-%s-%s_type_%s-%s-%s-%s_%s.jpg" % (request_id, time_now, current_frame, last_frame,
|
||||
random_num, mode_type, modeCode, target, image_type)
|
||||
|
||||
|
||||
class ImageTypeImageFileUpload(Thread):
|
||||
__slots__ = ('_fb_queue', '_context', '_image_queue', '_analyse_type', '_msg')
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__()
|
||||
self._fb_queue, self._context, self._msg, self._image_queue, self._analyse_type = args
|
||||
self._storage_source = self._context['service']['storage_source']
|
||||
@staticmethod
|
||||
def handle_image(det_xywh, copy_frame, font_config):
|
||||
"""
|
||||
det_xywh:{
|
||||
'code':{
|
||||
1: [[detect_targets_code, box, score, label_array, color]]
|
||||
}
|
||||
}
|
||||
模型编号:modeCode
|
||||
检测目标:detectTargetCode
|
||||
"""
|
||||
model_info = []
|
||||
# 更加模型编码解析数据
|
||||
for code, det_info in det_xywh.items():
|
||||
if det_info is not None and len(det_info) > 0:
|
||||
for cls, target_list in det_info.items():
|
||||
if target_list is not None and len(target_list) > 0:
|
||||
aiFrame = copy_frame.copy()
|
||||
for target in target_list:
|
||||
draw_painting_joint(target[1], aiFrame, target[3], target[2], target[4], font_config)
|
||||
model_info.append({
|
||||
"modelCode": str(code),
|
||||
"detectTargetCode": str(cls),
|
||||
"frame": aiFrame
|
||||
})
|
||||
if len(model_info) > 0:
|
||||
image_result = {
|
||||
"or_frame": copy_frame,
|
||||
"model_info": model_info,
|
||||
"current_frame": 0,
|
||||
"last_frame": 0
|
||||
}
|
||||
return image_result
|
||||
return None
|
||||
|
||||
def run(self):
|
||||
context, msg = self._context, self._msg
|
||||
base_dir, env, request_id = context["base_dir"], context["env"], msg["request_id"]
|
||||
logger.info("启动图片识别图片上传线程, requestId: {}", request_id)
|
||||
image_queue, fb_queue, analyse_type = self._image_queue, self._fb_queue, self._analyse_type
|
||||
service_timeout = int(context["service"]["timeout"])
|
||||
with ThreadPoolExecutor(max_workers=2) as t:
|
||||
try:
|
||||
# 初始化oss客户端
|
||||
if self._storage_source==1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id )
|
||||
else:
|
||||
aliyunOssSdk = AliyunOssSdk(base_dir, env, request_id)
|
||||
|
||||
start_time = time()
|
||||
while True:
|
||||
try:
|
||||
if time() - start_time > service_timeout:
|
||||
logger.error("图片上传进程运行超时, requestId: {}", request_id)
|
||||
break
|
||||
# 获取队列中的消息
|
||||
image_msg = image_queue.get()
|
||||
if image_msg is not None:
|
||||
if image_msg[0] == 2:
|
||||
if 'stop' == image_msg[1]:
|
||||
logger.info("开始停止图片上传线程, requestId:{}", request_id)
|
||||
break
|
||||
if image_msg[0] == 1:
|
||||
task, msg_list = [], []
|
||||
det_xywh, image_url, copy_frame, font_config, result = image_msg[1]
|
||||
if det_xywh is None:
|
||||
ai_image_name = build_image_name(0, 0, analyse_type, "AI", result.get("modelCode"),
|
||||
result.get("type"), request_id)
|
||||
|
||||
if self._storage_source==1:
|
||||
ai_future = t.submit(minioSdk.put_object, copy_frame,ai_image_name)
|
||||
else:
|
||||
ai_future = t.submit(aliyunOssSdk.put_object, ai_image_name, copy_frame)
|
||||
|
||||
task.append(ai_future)
|
||||
msg_list.append(message_feedback(request_id,
|
||||
AnalysisStatus.RUNNING.value,
|
||||
analyse_type, "", "", "",
|
||||
image_url,
|
||||
ai_image_name,
|
||||
result.get("modelCode"),
|
||||
result.get("type"),
|
||||
analyse_results=result))
|
||||
else:
|
||||
image_result = self.handle_image(det_xywh, copy_frame, font_config)
|
||||
if image_result:
|
||||
# 图片帧数编码
|
||||
if image_url is None:
|
||||
or_result, or_image = cv2.imencode(".jpg", image_result.get("or_frame"))
|
||||
image_url = build_image_name(image_result.get("current_frame"),
|
||||
image_result.get("last_frame"),
|
||||
analyse_type,
|
||||
"OR", "0", "O", request_id)
|
||||
|
||||
if self._storage_source==1:
|
||||
or_future = t.submit(minioSdk.put_object, or_image,image_url)
|
||||
else:
|
||||
or_future = t.submit(aliyunOssSdk.put_object, image_url,
|
||||
or_image.tobytes())
|
||||
task.append(or_future)
|
||||
model_info_list = image_result.get("model_info")
|
||||
for model_info in model_info_list:
|
||||
ai_result, ai_image = cv2.imencode(".jpg", model_info.get("frame"))
|
||||
ai_image_name = build_image_name(image_result.get("current_frame"),
|
||||
image_result.get("last_frame"),
|
||||
analyse_type,
|
||||
"AI",
|
||||
model_info.get("modelCode"),
|
||||
model_info.get("detectTargetCode"),
|
||||
request_id)
|
||||
if self._storage_source==1:
|
||||
ai_future = t.submit(minioSdk.put_object, ai_image, ai_image_name)
|
||||
else:
|
||||
ai_future = t.submit(aliyunOssSdk.put_object, ai_image_name,
|
||||
ai_image.tobytes())
|
||||
task.append(ai_future)
|
||||
msg_list.append(message_feedback(request_id,
|
||||
AnalysisStatus.RUNNING.value,
|
||||
analyse_type, "", "", "",
|
||||
image_url,
|
||||
ai_image_name,
|
||||
model_info.get('modelCode'),
|
||||
model_info.get('detectTargetCode'),
|
||||
analyse_results=result))
|
||||
for thread_result in task:
|
||||
thread_result.result()
|
||||
for msg in msg_list:
|
||||
put_queue(fb_queue, msg, timeout=2, is_ex=False)
|
||||
else:
|
||||
sleep(1)
|
||||
except Exception as e:
|
||||
logger.error("图片上传异常:{}, requestId:{}", format_exc(), request_id)
|
||||
finally:
|
||||
clear_queue(image_queue)
|
||||
logger.info("停止图片识别图片上传线程, requestId:{}", request_id)
|
||||
|
|
@ -62,7 +62,7 @@ class IntelligentRecognitionProcess(Process):
|
|||
# 发送waitting消息
|
||||
put_queue(self._fb_queue, message_feedback(self._msg["request_id"], AnalysisStatus.WAITING.value,
|
||||
self._analyse_type, progress=init_progess), timeout=2, is_ex=True)
|
||||
self._storage_source = self._context['service']['storage_source']
|
||||
self._storage_source = self._context['service']['storage_source']
|
||||
self._algStatus = False
|
||||
def sendEvent(self, eBody):
|
||||
put_queue(self.event_queue, eBody, timeout=2, is_ex=True)
|
||||
|
|
@ -92,6 +92,8 @@ class IntelligentRecognitionProcess(Process):
|
|||
return hb_thread
|
||||
|
||||
|
||||
|
||||
|
||||
class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
||||
__slots__ = ()
|
||||
|
||||
|
|
@ -110,16 +112,19 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
|||
pullProcess.start()
|
||||
return pullProcess
|
||||
|
||||
|
||||
def upload_video(self,base_dir, env, request_id, orFilePath, aiFilePath):
|
||||
if self._storage_source==1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id)
|
||||
minioSdk = MinioSdk(base_dir, env, request_id )
|
||||
upload_video_thread_or = Common(minioSdk.put_object, orFilePath, "or_online_%s.mp4" % request_id)
|
||||
upload_video_thread_ai = Common(minioSdk.put_object, aiFilePath, "ai_online_%s.mp4" % request_id)
|
||||
else:
|
||||
else:
|
||||
aliyunVodSdk = ThAliyunVodSdk(base_dir, env, request_id)
|
||||
upload_video_thread_or = Common(aliyunVodSdk.get_play_url, orFilePath, "or_online_%s" % request_id)
|
||||
upload_video_thread_ai = Common(aliyunVodSdk.get_play_url, aiFilePath, "ai_online_%s" % request_id)
|
||||
|
||||
|
||||
|
||||
|
||||
upload_video_thread_or.setDaemon(True)
|
||||
upload_video_thread_ai.setDaemon(True)
|
||||
upload_video_thread_or.start()
|
||||
|
|
@ -140,7 +145,7 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
|||
or_url = upload_video_thread_or.get_result()
|
||||
ai_url = upload_video_thread_ai.get_result()
|
||||
return or_url, ai_url
|
||||
'''
|
||||
'''
|
||||
|
||||
@staticmethod
|
||||
def ai_normal_dtection(model, frame, request_id):
|
||||
|
|
@ -220,7 +225,7 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
|||
ex = None
|
||||
# 拉流进程、推流进程、心跳线程
|
||||
pull_process, push_process, hb_thread = None, None, None
|
||||
|
||||
|
||||
# 事件队列、拉流队列、心跳队列、反馈队列
|
||||
event_queue, pull_queue, hb_queue, fb_queue = self.event_queue, self._pull_queue, self._hb_queue, self._fb_queue
|
||||
|
||||
|
|
@ -235,14 +240,14 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
|||
# 启动拉流进程(包含拉流线程, 图片上传线程,mqtt读取线程)
|
||||
# 拉流进程初始化时间长, 先启动
|
||||
pull_process = self.start_pull_stream(msg, context, fb_queue, pull_queue, image_queue, analyse_type, 25)
|
||||
#print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno) #7.0,
|
||||
#print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno) #7.0,
|
||||
# 启动心跳线程
|
||||
hb_thread = self.start_heartbeat(fb_queue, hb_queue, request_id, analyse_type, context)
|
||||
|
||||
# print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno) #7.0,
|
||||
# 加载算法模型
|
||||
model_array = get_model(msg, context, analyse_type)
|
||||
# print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno) #9.5
|
||||
#print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno) #9.5
|
||||
# 启动推流进程
|
||||
push_process = self.start_push_stream(msg, push_queue, image_queue, push_ex_queue, hb_queue, context)
|
||||
#print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno)
|
||||
|
|
@ -295,8 +300,7 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
|||
for i, model in enumerate(model_array):
|
||||
model_conf, code = model
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code) or \
|
||||
ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code):
|
||||
ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code):
|
||||
if draw_config.get(code) is None:
|
||||
draw_config[code] = {}
|
||||
draw_config["font_config"] = model_conf[4]
|
||||
|
|
@ -327,11 +331,11 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
|||
frame_index_list[i], tt, request_id)
|
||||
det_array.append(det_result)
|
||||
push_objs = [det.result() for det in det_array]
|
||||
# print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno)
|
||||
#print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno)
|
||||
put_queue(push_queue,
|
||||
(1, (frame_list, frame_index_list, all_frames, draw_config, push_objs)),
|
||||
timeout=2, is_ex=True)
|
||||
# print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno)
|
||||
#print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno)
|
||||
del det_array, push_objs
|
||||
del frame_list, frame_index_list, all_frames
|
||||
elif pull_result[0] == 1:
|
||||
|
|
@ -443,12 +447,12 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
|||
class OfflineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
||||
__slots__ = ()
|
||||
|
||||
def upload_video(self, base_dir, env, request_id, aiFilePath):
|
||||
def upload_video(self,base_dir, env, request_id, aiFilePath):
|
||||
aliyunVodSdk = ThAliyunVodSdk(base_dir, env, request_id)
|
||||
upload_video_thread_ai = Common(aliyunVodSdk.get_play_url, aiFilePath, "ai_online_%s" % request_id)
|
||||
|
||||
if self._storage_source == 1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id)
|
||||
if self._storage_source==1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id )
|
||||
upload_video_thread_ai = Common(minioSdk.put_object, aiFilePath, "ai_online_%s.mp4" % request_id)
|
||||
else:
|
||||
aliyunVodSdk = ThAliyunVodSdk(base_dir, env, request_id)
|
||||
|
|
@ -622,8 +626,7 @@ class OfflineIntelligentRecognitionProcess(IntelligentRecognitionProcess):
|
|||
for i, model in enumerate(model_array):
|
||||
model_conf, code = model
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code) or \
|
||||
ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code):
|
||||
ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code):
|
||||
if draw_config.get(code) is None:
|
||||
draw_config[code] = {}
|
||||
draw_config["font_config"] = model_conf[4]
|
||||
|
|
@ -763,7 +766,7 @@ class PhotosIntelligentRecognitionProcess(Process):
|
|||
put_queue(self._fb_queue, message_feedback(self._msg["request_id"], AnalysisStatus.WAITING.value,
|
||||
self._analyse_type, progress=init_progess), timeout=2, is_ex=True)
|
||||
self.build_logo(self._msg, self._context)
|
||||
self._storage_source = self._context['service']['storage_source']
|
||||
self._storage_source = self._context['service']['storage_source']
|
||||
|
||||
@staticmethod
|
||||
def build_logo(msg, context):
|
||||
|
|
@ -940,7 +943,7 @@ class PhotosIntelligentRecognitionProcess(Process):
|
|||
logger.error("模型分析异常: {}, requestId: {}", format_exc(), request_id)
|
||||
raise e
|
||||
|
||||
# 自研究车牌模型
|
||||
#自研究车牌模型
|
||||
def carplate_rec(self, imageUrl, mod, image_queue, request_id):
|
||||
try:
|
||||
# model_conf: modeType, allowedList, detpar, ocrmodel, rainbows
|
||||
|
|
@ -979,6 +982,7 @@ class PhotosIntelligentRecognitionProcess(Process):
|
|||
# param = [image, new_device, model, par, img_type, request_id]
|
||||
# model_conf, frame, device, requestId
|
||||
dataBack = MODEL_CONFIG[code][3]([[modeType, device, model, postPar], image, request_id])[0][2]
|
||||
logger.info("当前人数:{}", dataBack[0][0])
|
||||
dets[code][0] = dataBack
|
||||
if not dataBack:
|
||||
logger.info("当前页面无人")
|
||||
|
|
@ -1267,8 +1271,7 @@ class PhotosIntelligentRecognitionProcess(Process):
|
|||
result = t.submit(self.carpalteRec, imageUrls, model, image_queue, request_id)
|
||||
task_list.append(result)
|
||||
# 人群计数模型
|
||||
elif model[1] == ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] or \
|
||||
model[1] == ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1]:
|
||||
elif model[1] == ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1]:
|
||||
result = t.submit(self.denscrowdcountRec, imageUrls, model, image_queue, request_id)
|
||||
task_list.append(result)
|
||||
else:
|
||||
|
|
@ -1483,9 +1486,9 @@ class ScreenRecordingProcess(Process):
|
|||
clear_queue(self._hb_queue)
|
||||
clear_queue(self._pull_queue)
|
||||
|
||||
def upload_video(self, base_dir, env, request_id, orFilePath):
|
||||
if self._storage_source == 1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id)
|
||||
def upload_video(self,base_dir, env, request_id, orFilePath):
|
||||
if self._storage_source==1:
|
||||
minioSdk = MinioSdk(base_dir, env, request_id )
|
||||
upload_video_thread_ai = Common(minioSdk.put_object, aiFilePath, "%s/ai_online.mp4" % request_id)
|
||||
else:
|
||||
aliyunVodSdk = ThAliyunVodSdk(base_dir, env, request_id)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -151,35 +151,35 @@ class OnPushStreamProcess(PushStreamProcess):
|
|||
# 自研车牌模型处理
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code):
|
||||
cls = 0
|
||||
box = xy2xyxy(qs[1])
|
||||
ocrlabel, xybox = qs
|
||||
box = xy2xyxy(xybox)
|
||||
score = None
|
||||
color = rainbows[cls]
|
||||
label_array = None
|
||||
rr = t.submit(draw_name_ocr, qs, copy_frame, color)
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code):
|
||||
rr = t.submit(draw_name_ocr, xybox, copy_frame, color, ocrlabel)
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code):
|
||||
cls = 0
|
||||
# crowdlabel, points = qs
|
||||
crowdlabel, points = qs
|
||||
box = [(0, 0), (0, 0), (0, 0), (0, 0)]
|
||||
score = None
|
||||
color = rainbows[cls]
|
||||
label_array = None
|
||||
rr = t.submit(draw_name_crowd, qs, copy_frame, color)
|
||||
rr = t.submit(draw_name_crowd, points, copy_frame, color, crowdlabel)
|
||||
else:
|
||||
try: # 应对NaN情况
|
||||
box, score, cls = xywh2xyxy2(qs)
|
||||
except:
|
||||
continue
|
||||
if cls not in allowedList or score < frame_score:
|
||||
continue
|
||||
label_array, color = label_arrays[cls], rainbows[cls]
|
||||
if ModelType.CHANNEL2_MODEL.value[1] == str(code) and cls == 2:
|
||||
rr = t.submit(draw_name_joint, box, copy_frame,
|
||||
draw_config[code]["label_dict"], score, color,
|
||||
font_config, qs[6])
|
||||
else:
|
||||
rr = t.submit(draw_painting_joint, box, copy_frame, label_array,
|
||||
score, color, font_config)
|
||||
try: # 应对NaN情况
|
||||
box, score, cls = xywh2xyxy2(qs)
|
||||
except:
|
||||
continue
|
||||
if cls not in allowedList or score < frame_score:
|
||||
continue
|
||||
label_array, color = label_arrays[cls], rainbows[cls]
|
||||
if ModelType.CHANNEL2_MODEL.value[1] == str(code) and cls == 2:
|
||||
rr = t.submit(draw_name_joint, box, copy_frame,
|
||||
draw_config[code]["label_dict"], score, color,
|
||||
font_config, qs[6])
|
||||
else:
|
||||
rr = t.submit(draw_painting_joint, box, copy_frame, label_array,
|
||||
score, color, font_config)
|
||||
|
||||
thread_p.append(rr)
|
||||
if det_xywh.get(code) is None:
|
||||
|
|
@ -261,18 +261,17 @@ class OnPushStreamProcess(PushStreamProcess):
|
|||
is_new = False
|
||||
if q[11] == 1:
|
||||
is_new = True
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code) or \
|
||||
ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code):
|
||||
box = qs
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code):
|
||||
cls = ocrlabel
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code):
|
||||
cls = crowdlabel
|
||||
label_array = points
|
||||
if cd is None:
|
||||
det_xywh2[code][cls] = [[cls, box, score, label_array, color, is_new]]
|
||||
det_xywh2[code][cls] = [[cls, box, score, label_array, color, is_new]]
|
||||
else:
|
||||
det_xywh2[code][cls].append(
|
||||
[cls, box, score, label_array, color, is_new])
|
||||
det_xywh2[code][cls].append([cls, box, score, label_array, color, is_new])
|
||||
if len(det_xywh2) > 0:
|
||||
put_queue(image_queue, (1, [det_xywh2, frame, frame_index_list[i], all_frames,
|
||||
draw_config["font_config"]]))
|
||||
put_queue(image_queue, (1, [det_xywh2, frame, frame_index_list[i], all_frames, draw_config["font_config"]]))
|
||||
|
||||
push_p = push_stream_result.result(timeout=60)
|
||||
ai_video_file = write_ai_video_result.result(timeout=60)
|
||||
|
|
@ -394,21 +393,22 @@ class OffPushStreamProcess(PushStreamProcess):
|
|||
# 自研车牌模型处理
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code):
|
||||
cls = 0
|
||||
box = xy2xyxy(qs[1])
|
||||
ocrlabel, xybox = qs
|
||||
box = xy2xyxy(xybox)
|
||||
score = None
|
||||
color = rainbows[cls]
|
||||
label_array = None
|
||||
label_arrays = [None]
|
||||
rr = t.submit(draw_name_ocr, qs, copy_frame, color)
|
||||
rr = t.submit(draw_name_ocr,xybox,copy_frame,color,ocrlabel)
|
||||
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code):
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code):
|
||||
cls = 0
|
||||
crowdlabel, points = qs
|
||||
box = [(0,0),(0,0),(0,0),(0,0)]
|
||||
score = None
|
||||
color = rainbows[cls]
|
||||
label_array = None
|
||||
rr = t.submit(draw_name_crowd, qs, copy_frame, color)
|
||||
rr = t.submit(draw_name_crowd, points, copy_frame, color, crowdlabel)
|
||||
|
||||
else:
|
||||
box, score, cls = xywh2xyxy2(qs)
|
||||
|
|
@ -500,15 +500,16 @@ class OffPushStreamProcess(PushStreamProcess):
|
|||
if q[11] == 1:
|
||||
is_new = True
|
||||
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code) or \
|
||||
ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code):
|
||||
box = qs
|
||||
if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code):
|
||||
cls = ocrlabel
|
||||
elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code):
|
||||
cls = crowdlabel
|
||||
label_array = points
|
||||
|
||||
if cd is None:
|
||||
det_xywh2[code][cls] = [[cls, box, score, label_array, color, is_new]]
|
||||
det_xywh2[code][cls] = [[cls, box, score, label_array, color, is_new]]
|
||||
else:
|
||||
det_xywh2[code][cls].append(
|
||||
[cls, box, score, label_array, color, is_new])
|
||||
det_xywh2[code][cls].append([cls, box, score, label_array, color, is_new])
|
||||
if len(det_xywh2) > 0:
|
||||
put_queue(image_queue, (1, [det_xywh2, frame, frame_index_list[i], all_frames, draw_config["font_config"]]))
|
||||
push_p = push_stream_result.result(timeout=60)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@ log_name: "dsp.log"
|
|||
log_fmt: "{time:YYYY-MM-DD HH:mm:ss.SSS} [{level}][{process.name}-{process.id}-{thread.name}-{thread.id}][{line}] {module}-{function} - {message}"
|
||||
level: "INFO"
|
||||
rotation: "00:00"
|
||||
retention: "15 days"
|
||||
retention: "7 days"
|
||||
encoding: "utf8"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@ log_name: "dsp.log"
|
|||
log_fmt: "{time:YYYY-MM-DD HH:mm:ss.SSS} [{level}][{process.name}-{process.id}-{thread.name}-{thread.id}][{line}] {module}-{function} - {message}"
|
||||
level: "INFO"
|
||||
rotation: "00:00"
|
||||
retention: "7 days"
|
||||
retention: "3 days"
|
||||
encoding: "utf8"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,768 +0,0 @@
|
|||
import sys
|
||||
from enum import Enum, unique
|
||||
|
||||
from common.Constant import COLOR
|
||||
|
||||
sys.path.extend(['..', '../AIlib2'])
|
||||
from DMPR import DMPRModel
|
||||
from DMPRUtils.jointUtil import dmpr_yolo
|
||||
from segutils.segmodel import SegModel
|
||||
from utilsK.queRiver import riverDetSegMixProcess
|
||||
from utilsK.crowdGather import gather_post_process
|
||||
from segutils.trafficUtils import tracfficAccidentMixFunction
|
||||
from utilsK.drownUtils import mixDrowing_water_postprocess
|
||||
from utilsK.noParkingUtils import mixNoParking_road_postprocess
|
||||
from utilsK.illParkingUtils import illParking_postprocess
|
||||
from stdc import stdcModel
|
||||
from yolov5 import yolov5Model
|
||||
from DMPRUtils.jointUtil import dmpr_yolo_stdc
|
||||
from AI import default_mix
|
||||
from ocr import ocrModel
|
||||
from utilsK.channel2postUtils import channel2_post_process
|
||||
|
||||
'''
|
||||
参数说明
|
||||
1. 编号
|
||||
2. 模型编号
|
||||
3. 模型名称
|
||||
4. 选用的模型名称
|
||||
5. 模型配置
|
||||
6. 模型引用配置[Detweights文件, Segweights文件, 引用计数]
|
||||
'''
|
||||
|
||||
|
||||
@unique
|
||||
class ModelType(Enum):
|
||||
WATER_SURFACE_MODEL = ("1", "001", "河道模型", 'river', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["排口", "水生植被", "其它", "漂浮物", "污染排口", "菜地", "违建", "岸坡垃圾"],
|
||||
'seg_nclass': 2,
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'segRegionCnt': 1,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': riverDetSegMixProcess,
|
||||
'pars': {
|
||||
'slopeIndex': [5, 6, 7],
|
||||
'riverIou': 0.1
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/river/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': '../AIlib2/weights/river/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
# FOREST_FARM_MODEL = ("2", "002", "森林模型", 'forest2', lambda device, gpuName: {
|
||||
# 'device': device,
|
||||
# 'gpu_name': gpuName,
|
||||
# 'labelnames': ["林斑", "病死树", "行人", "火焰", "烟雾","云朵"],
|
||||
# 'trtFlag_det': True,
|
||||
# 'trtFlag_seg': False,
|
||||
# 'Detweights': "../AIlib2/weights/forest2/yolov5_%s_fp16.engine" % gpuName,
|
||||
# 'seg_nclass': 2,
|
||||
# 'segRegionCnt': 0,
|
||||
# 'slopeIndex': [],
|
||||
# 'segPar': None,
|
||||
# 'postFile': {
|
||||
# "name": "post_process",
|
||||
# "conf_thres": 0.25,
|
||||
# "iou_thres": 0.45,
|
||||
# "classes": 6,
|
||||
# "rainbows": COLOR
|
||||
# },
|
||||
# 'Segweights': None
|
||||
# })
|
||||
|
||||
|
||||
FOREST_FARM_MODEL = ("2", "002", "森林模型", 'forest2', lambda device, gpuName: {
|
||||
'labelnames': ["林斑", "病死树", "行人", "火焰", "烟雾","云朵"],
|
||||
'postProcess':{'function':default_mix,'pars':{}},
|
||||
'models':
|
||||
[
|
||||
{
|
||||
'weight':"../AIlib2/weights/forest2/yolov5_%s_fp16.engine"%(gpuName),###检测模型路径
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.45,'allowedList':[0,1,2,3],'segRegionCnt':1, 'trtFlag_det':False,'trtFlag_seg':False, "score_byClass":{"0":0.25,"1":0.3,"2":0.3,"3":0.3 } },
|
||||
}
|
||||
|
||||
|
||||
],
|
||||
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'detModelpara':[{"id":str(x),"config":{"k1":"v1","k2":"v2"}} for x in [0,1,2,3,4,5,6,7,8,9] ],###控制哪些检测类别显示、输出
|
||||
'segRegionCnt':2,###分割模型结果需要保留的等值线数目
|
||||
"pixScale": 1.2,
|
||||
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
TRAFFIC_FARM_MODEL = ("3", "003", "交通模型", 'highWay2', lambda device, gpuName: {
|
||||
'device': str(device),
|
||||
'labelnames': ["行人", "车辆", "纵向裂缝", "横向裂缝", "修补", "网状裂纹", "坑槽", "块状裂纹", "积水", "影子", "事故"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 3,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'predResize': True,
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': tracfficAccidentMixFunction,
|
||||
'pars': {
|
||||
'modelSize': (640, 360),
|
||||
#'modelSize': (1920,1080),
|
||||
'RoadArea': 16000,
|
||||
'roadVehicleAngle': 15,
|
||||
'speedRoadVehicleAngleMax': 75,
|
||||
'roundness': 1.0,
|
||||
'cls': 9,
|
||||
'vehicleFactor': 0.1,
|
||||
'confThres': 0.25,
|
||||
'roadIou': 0.6,
|
||||
'radius': 50,
|
||||
'vehicleFlag': False,
|
||||
'distanceFlag': False
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 10,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/highWay2/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': '../AIlib2/weights/highWay2/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
EPIDEMIC_PREVENTION_MODEL = ("4", "004", "防疫模型", None, None)
|
||||
|
||||
PLATE_MODEL = ("5", "005", "车牌模型", None, None)
|
||||
|
||||
VEHICLE_MODEL = ("6", "006", "车辆模型", 'vehicle', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["车辆"],
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/vehicle/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
PEDESTRIAN_MODEL = ("7", "007", "行人模型", 'pedestrian', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["行人"],
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 0,
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/pedestrian/yolov5_%s_fp16.engine" % gpuName,
|
||||
'slopeIndex': [],
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
SMOGFIRE_MODEL = ("8", "008", "烟火模型", 'smogfire', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["火焰", "烟雾"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/smogfire/yolov5_%s_fp16.engine" % gpuName,
|
||||
'slopeIndex': [],
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
ANGLERSWIMMER_MODEL = ("9", "009", "钓鱼游泳模型", 'AnglerSwimmer', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["钓鱼", "游泳"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/AnglerSwimmer/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
COUNTRYROAD_MODEL = ("10", "010", "乡村模型", 'countryRoad', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["违法种植"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/countryRoad/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
SHIP_MODEL = ("11", "011", "船只模型", 'ship2', lambda device, gpuName: {
|
||||
'model_size': (608, 608),
|
||||
'K': 100,
|
||||
'conf_thresh': 0.18,
|
||||
'device': 'cuda:%s' % device,
|
||||
'down_ratio': 4,
|
||||
'num_classes': 15,
|
||||
'weights': '../AIlib2/weights/ship2/obb_608X608_%s_fp16.engine' % gpuName,
|
||||
'dataset': 'dota',
|
||||
'half': False,
|
||||
'mean': (0.5, 0.5, 0.5),
|
||||
'std': (1, 1, 1),
|
||||
'heads': {'hm': None, 'wh': 10, 'reg': 2, 'cls_theta': 1},
|
||||
'decoder': None,
|
||||
'test_flag': True,
|
||||
"rainbows": COLOR,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'drawBox': False,
|
||||
'label_array': None,
|
||||
'labelnames': ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "船只"),
|
||||
})
|
||||
|
||||
BAIDU_MODEL = ("12", "012", "百度AI图片识别模型", None, None)
|
||||
|
||||
CHANNEL_EMERGENCY_MODEL = ("13", "013", "航道模型", 'channelEmergency', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["人"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/channelEmergency/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
RIVER2_MODEL = ("15", "015", "河道检测模型", 'river2', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["漂浮物", "岸坡垃圾", "排口", "违建", "菜地", "水生植物", "河湖人员", "钓鱼人员", "船只",
|
||||
"蓝藻"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 1,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': riverDetSegMixProcess,
|
||||
'pars': {
|
||||
'slopeIndex': [1, 3, 4, 7],
|
||||
'riverIou': 0.1
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.3,
|
||||
"ovlap_thres_crossCategory": 0.65,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
# "../AIlib2/weights/conf/%s/yolov5.pt" % modeType.value[3]
|
||||
'Detweights': "../AIlib2/weights/river2/yolov5_%s_fp16.engine" % gpuName,
|
||||
# '../AIlib2/weights/conf/%s/stdc_360X640.pth' % modeType.value[3]
|
||||
'Segweights': '../AIlib2/weights/river2/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
CITY_MANGEMENT_MODEL = ("16", "016", "城管模型", 'cityMangement2', lambda device, gpuName: {
|
||||
'labelnames': ["车辆", "垃圾", "商贩", "违停"],
|
||||
'postProcess':{
|
||||
'function':dmpr_yolo_stdc,
|
||||
'pars':{'carCls':0 ,'illCls':3,'scaleRatio':0.5,'border':80,'rubCls': 1, 'Rubfilter': 150}
|
||||
},
|
||||
'models':[
|
||||
{
|
||||
#'weight':'../AIlib2/weights/conf/cityMangement3/yolov5.pt',
|
||||
'weight':'../AIlib2/weights/cityMangement3/yolov5_%s_fp16.engine'%(gpuName),
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.5,'allowedList':[0,1,2,3],'segRegionCnt':1, 'trtFlag_det':False,'trtFlag_seg':False, "score_byClass":{"0":0.8,"1":0.4,"2":0.5,"3":0.5 } }
|
||||
},
|
||||
{
|
||||
'weight':'../AIlib2/weights/conf/cityMangement3/dmpr.pth',
|
||||
'par':{
|
||||
'depth_factor':32,'NUM_FEATURE_MAP_CHANNEL':6,'dmpr_thresh':0.1, 'dmprimg_size':640,
|
||||
'name':'dmpr'
|
||||
},
|
||||
'model':DMPRModel,
|
||||
'name':'dmpr'
|
||||
},
|
||||
{
|
||||
'weight':'../AIlib2/weights/conf/cityMangement3/stdc_360X640.pth',
|
||||
|
||||
'par':{
|
||||
'modelSize':(640,360),'mean':(0.485, 0.456, 0.406),'std' :(0.229, 0.224, 0.225),'predResize':True,'numpy':False, 'RGB_convert_first':True,'seg_nclass':2},###分割模型预处理参数
|
||||
'model':stdcModel,
|
||||
'name':'stdc'
|
||||
}
|
||||
],
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.5,
|
||||
"iou_thres": 0.5,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'detModelpara':[{"id":str(x),"config":{"k1":"v1","k2":"v2"}} for x in [0,1,2,3,5,6,7,8,9] ],###控制哪些检测类别显示、输出
|
||||
'segRegionCnt':2,###分割模型结果需要保留的等值线数目
|
||||
"pixScale": 1.2,
|
||||
})
|
||||
|
||||
DROWING_MODEL = ("17", "017", "人员落水模型", 'drowning', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["人头", "人", "船只"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'predResize': True,
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': mixDrowing_water_postprocess,
|
||||
'pars': {
|
||||
'modelSize': (640, 360)
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 9,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
# "../AIlib2/weights/conf/%s/yolov5.pt" % modeType.value[3]
|
||||
'Detweights': "../AIlib2/weights/drowning/yolov5_%s_fp16.engine" % gpuName,
|
||||
# '../AIlib2/weights/conf/%s/stdc_360X640.pth' % modeType.value[3]
|
||||
'Segweights': '../AIlib2/weights/drowning/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
NOPARKING_MODEL = (
|
||||
"18", "018", "城市违章模型", 'noParking', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["车辆", "违停"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 4,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'predResize': True,
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True, ###分割模型预处理参数
|
||||
'mixFunction': {
|
||||
'function': mixNoParking_road_postprocess,
|
||||
'pars': {
|
||||
'modelSize': (640, 360),
|
||||
'roundness': 0.3,
|
||||
'cls': 9,
|
||||
'laneArea': 10,
|
||||
'laneAngleCha': 5,
|
||||
'RoadArea': 16000,
|
||||
'fitOrder':2
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 9,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/noParking/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': '../AIlib2/weights/noParking/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
ILLPARKING_MODEL = ("19", "019", "车辆违停模型", 'illParking', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["车", "T角点", "L角点", "违停"],
|
||||
'trtFlag_seg': False,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 4,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
'mixFunction': {
|
||||
'function': illParking_postprocess,
|
||||
'pars': {}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 9,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/illParking/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
CITYROAD_MODEL = ("20", "020", "城市公路模型", 'cityRoad', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["护栏", "交通标志", "非交通标志", "施工", "施工"],
|
||||
'trtFlag_seg': False,
|
||||
'trtFlag_det': True,
|
||||
'slopeIndex': [],
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 0,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.5,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/cityRoad/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
POTHOLE_MODEL = ("23", "023", "坑槽检测模型", 'pothole', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["坑槽"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/pothole/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None,
|
||||
})
|
||||
|
||||
CHANNEL2_MODEL = ("24", "024", "船只综合检测模型", 'channel2', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
|
||||
'labelnames': ["国旗", "浮标", "船名", "船只","未挂国旗船只","未封仓"], # 保持原来的标签顺序不变,方便后面业务端增加
|
||||
'segRegionCnt': 0,
|
||||
'postProcess':{'function':channel2_post_process,'name':'channel2','pars':{
|
||||
'objs':[2],
|
||||
'wRation':1/6.0,
|
||||
'hRation':1/6.0,
|
||||
'smallId':0, #旗帜
|
||||
'bigId':3, #船只
|
||||
'newId':4, #未挂国旗船只
|
||||
'uncoverId':5, #未封仓标签
|
||||
'recScale':1.2,
|
||||
'target_cls':3.0, #目标种类
|
||||
'filter_cls':4.0 #被过滤的种类
|
||||
}},
|
||||
'models':[
|
||||
{
|
||||
#'weight':'../AIlib2/weights/conf/channel2/yolov5.pt',
|
||||
# 'weight':'../AIlib2/weights/channel2/yolov5_%s_fp16.engine'%(gpuName),
|
||||
|
||||
'weight':'/home/thsw2/jcq/test/AIlib2/weights/channel2/best.pt', # yolov5 原来模型基础上增加了未封仓
|
||||
|
||||
# 'weight':'../AIlib2/weights/channel2/yolov5_%s_fp16.engine'%(gpuName),
|
||||
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.1,'iou_thres':0.45,'allowedList':list(range(20)),'segRegionCnt':1, 'trtFlag_det':False,'trtFlag_seg':False, "score_byClass":{"0":0.7,"1":0.7,"2":0.8,"3":0.6} }
|
||||
},
|
||||
{
|
||||
# 'weight' : '../AIlib2/weights/ocr2/crnn_ch_4090_fp16_192X32.engine',
|
||||
'weight' : '../AIlib2/weights/conf/ocr2/crnn_ch.pth',
|
||||
'name':'ocr',
|
||||
'model':ocrModel,
|
||||
'par':{
|
||||
'char_file':'../AIlib2/weights/conf/ocr2/benchmark.txt',
|
||||
'mode':'ch',
|
||||
'nc':3,
|
||||
'imgH':32,
|
||||
'imgW':192,
|
||||
'hidden':256,
|
||||
'mean':[0.5,0.5,0.5],
|
||||
'std':[0.5,0.5,0.5],
|
||||
'dynamic':False,
|
||||
},
|
||||
} ,
|
||||
|
||||
|
||||
# {
|
||||
# 'weight':'/home/thsw2/jcq/test/AIlib2/weights1/conf/channel2/yolov5_04.pt', # yolov5_04 添加了uncover 0 4 ;标签 yolov5_jcq
|
||||
# 'name':'yolov5',
|
||||
# 'model':yolov5Model,
|
||||
# 'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.15,'iou_thres':0.25,'allowedList':list(range(20)),'segRegionCnt':1, 'trtFlag_det':False,'trtFlag_seg':False, "score_byClass":{"0":0.7,"1":0.7,"2":0.8,"3":0.6} }
|
||||
# }
|
||||
|
||||
|
||||
],
|
||||
'detModelpara':[{"id":str(x),"config":{"k1":"v1","k2":"v2"}} for x in [0,1,2,3]],
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None,
|
||||
})
|
||||
|
||||
RIVERT_MODEL = ("25", "025", "河道检测模型(T)", 'riverT', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["漂浮物", "岸坡垃圾", "排口", "违建", "菜地", "水生植物", "河湖人员", "钓鱼人员", "船只",
|
||||
"蓝藻"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 1,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': riverDetSegMixProcess,
|
||||
'pars': {
|
||||
'slopeIndex': [1, 3, 4, 7],
|
||||
'riverIou': 0.1
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.3,
|
||||
"ovlap_thres_crossCategory": 0.65,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
# "../AIlib2/weights/conf/%s/yolov5.pt" % modeType.value[3]
|
||||
'Detweights': "../AIlib2/weights/riverT/yolov5_%s_fp16.engine" % gpuName,
|
||||
# '../AIlib2/weights/conf/%s/stdc_360X640.pth' % modeType.value[3]
|
||||
'Segweights': '../AIlib2/weights/riverT/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
|
||||
|
||||
FORESTCROWD_FARM_MODEL = ("2", "026", "森林人群模型", 'forestCrowd', lambda device, gpuName: {
|
||||
'labelnames': ["林斑", "病死树", "行人", "火焰", "烟雾","人群"],
|
||||
'postProcess':{'function':gather_post_process,'pars':{'pedestrianId':2,'crowdThreshold':4,'gatherId':5,'distancePersonScale':2.0}},
|
||||
'models':
|
||||
[
|
||||
{
|
||||
'weight':"../AIlib2/weights/forestCrowd/yolov5_%s_fp16.engine"%(gpuName),###检测模型路径
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.5,'allowedList':[0,1,2,3],'segRegionCnt':1, 'trtFlag_det':False,'trtFlag_seg':False, "score_byClass":{ "0":0.25,"1":0.25,"2":0.6,"3":0.6,'4':0.6 ,'5':0.6 } },
|
||||
}
|
||||
|
||||
|
||||
],
|
||||
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'detModelpara':[{"id":str(x),"config":{"k1":"v1","k2":"v2"}} for x in [0,1,2,3,4,5,6,7,8,9] ],###控制哪些检测类别显示、输出
|
||||
'segRegionCnt':2,###分割模型结果需要保留的等值线数目
|
||||
"pixScale": 1.2,
|
||||
|
||||
|
||||
})
|
||||
TRAFFICFORDSJ_FARM_MODEL = ("27", "027", "交通模型-大数据局", 'highWay2T', lambda device, gpuName: {
|
||||
'device': str(device),
|
||||
'labelnames': ["行人", "车辆", "纵向裂缝", "横向裂缝", "修补", "网状裂纹", "坑槽", "块状裂纹", "积水", "影子", "事故", "桥梁外观","设施破损缺失","龙门架","防抛网","标识牌损坏","护栏损坏","钢筋裸露" ],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 3,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'predResize': True,
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': tracfficAccidentMixFunction,
|
||||
'pars': {
|
||||
'modelSize': (640, 360),
|
||||
#'modelSize': (1920,1080),
|
||||
'RoadArea': 16000,
|
||||
'roadVehicleAngle': 15,
|
||||
'speedRoadVehicleAngleMax': 75,
|
||||
'roundness': 1.0,
|
||||
'cls': 9,
|
||||
'vehicleFactor': 0.1,
|
||||
'confThres': 0.25,
|
||||
'roadIou': 0.6,
|
||||
'radius': 50,
|
||||
'vehicleFlag': False,
|
||||
'distanceFlag': False
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 10,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/highWay2/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': '../AIlib2/weights/highWay2/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def checkCode(code):
|
||||
for model in ModelType:
|
||||
if model.value[1] == code:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
'''
|
||||
参数1: 检测目标名称
|
||||
参数2: 检测目标
|
||||
参数3: 初始化百度检测客户端
|
||||
'''
|
||||
|
||||
|
||||
@unique
|
||||
class BaiduModelTarget(Enum):
|
||||
VEHICLE_DETECTION = (
|
||||
"车辆检测", 0, lambda client0, client1, url, request_id: client0.vehicleDetectUrl(url, request_id))
|
||||
|
||||
HUMAN_DETECTION = (
|
||||
"人体检测与属性识别", 1, lambda client0, client1, url, request_id: client1.bodyAttr(url, request_id))
|
||||
|
||||
PEOPLE_COUNTING = ("人流量统计", 2, lambda client0, client1, url, request_id: client1.bodyNum(url, request_id))
|
||||
|
||||
|
||||
BAIDU_MODEL_TARGET_CONFIG = {
|
||||
BaiduModelTarget.VEHICLE_DETECTION.value[1]: BaiduModelTarget.VEHICLE_DETECTION,
|
||||
BaiduModelTarget.HUMAN_DETECTION.value[1]: BaiduModelTarget.HUMAN_DETECTION,
|
||||
BaiduModelTarget.PEOPLE_COUNTING.value[1]: BaiduModelTarget.PEOPLE_COUNTING
|
||||
}
|
||||
|
||||
EPIDEMIC_PREVENTION_CONFIG = {1: "行程码", 2: "健康码"}
|
||||
|
||||
|
||||
# 模型分析方式
|
||||
@unique
|
||||
class ModelMethodTypeEnum(Enum):
|
||||
# 方式一: 正常识别方式
|
||||
NORMAL = 1
|
||||
|
||||
# 方式二: 追踪识别方式
|
||||
TRACE = 2
|
||||
|
|
@ -1,807 +0,0 @@
|
|||
import sys
|
||||
from enum import Enum, unique
|
||||
|
||||
from common.Constant import COLOR
|
||||
|
||||
sys.path.extend(['..', '../AIlib2'])
|
||||
from DMPR import DMPRModel
|
||||
from DMPRUtils.jointUtil import dmpr_yolo
|
||||
from segutils.segmodel import SegModel
|
||||
from utilsK.queRiver import riverDetSegMixProcess
|
||||
from utilsK.crowdGather import gather_post_process
|
||||
from segutils.trafficUtils import tracfficAccidentMixFunction
|
||||
from utilsK.drownUtils import mixDrowing_water_postprocess
|
||||
from utilsK.noParkingUtils import mixNoParking_road_postprocess
|
||||
from utilsK.illParkingUtils import illParking_postprocess
|
||||
from stdc import stdcModel
|
||||
from yolov5 import yolov5Model
|
||||
from DMPRUtils.jointUtil import dmpr_yolo_stdc
|
||||
from AI import default_mix
|
||||
from ocr import ocrModel
|
||||
from utilsK.channel2postUtils import channel2_post_process
|
||||
|
||||
'''
|
||||
参数说明
|
||||
1. 编号
|
||||
2. 模型编号
|
||||
3. 模型名称
|
||||
4. 选用的模型名称
|
||||
5. 模型配置
|
||||
6. 模型引用配置[Detweights文件, Segweights文件, 引用计数]
|
||||
'''
|
||||
|
||||
|
||||
@unique
|
||||
class ModelType(Enum):
|
||||
WATER_SURFACE_MODEL = ("1", "001", "河道模型", 'river', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["排口", "水生植被", "其它", "漂浮物", "污染排口", "菜地", "违建", "岸坡垃圾"],
|
||||
'seg_nclass': 2,
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'segRegionCnt': 1,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': riverDetSegMixProcess,
|
||||
'pars': {
|
||||
'slopeIndex': [5, 6, 7],
|
||||
'riverIou': 0.1
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/river/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': '../AIlib2/weights/river/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
# FOREST_FARM_MODEL = ("2", "002", "森林模型", 'forest2', lambda device, gpuName: {
|
||||
# 'device': device,
|
||||
# 'gpu_name': gpuName,
|
||||
# 'labelnames': ["林斑", "病死树", "行人", "火焰", "烟雾","云朵"],
|
||||
# 'trtFlag_det': True,
|
||||
# 'trtFlag_seg': False,
|
||||
# 'Detweights': "../AIlib2/weights/forest2/yolov5_%s_fp16.engine" % gpuName,
|
||||
# 'seg_nclass': 2,
|
||||
# 'segRegionCnt': 0,
|
||||
# 'slopeIndex': [],
|
||||
# 'segPar': None,
|
||||
# 'postFile': {
|
||||
# "name": "post_process",
|
||||
# "conf_thres": 0.25,
|
||||
# "iou_thres": 0.45,
|
||||
# "classes": 6,
|
||||
# "rainbows": COLOR
|
||||
# },
|
||||
# 'Segweights': None
|
||||
# })
|
||||
|
||||
|
||||
FOREST_FARM_MODEL = ("2", "002", "森林模型", 'forest2', lambda device, gpuName: {
|
||||
'labelnames': ["林斑", "病死树", "行人", "火焰", "烟雾","云朵"],
|
||||
'postProcess':{'function':default_mix,'pars':{}},
|
||||
'models':
|
||||
[
|
||||
{
|
||||
'weight':"../AIlib2/weights/forest2/yolov5_%s_fp16.engine"%(gpuName),###检测模型路径
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.45,'allowedList':[0,1,2,3],'segRegionCnt':1, 'trtFlag_det':False,'trtFlag_seg':False, "score_byClass":{"0":0.25,"1":0.3,"2":0.3,"3":0.3 } },
|
||||
}
|
||||
|
||||
|
||||
],
|
||||
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'detModelpara':[{"id":str(x),"config":{"k1":"v1","k2":"v2"}} for x in [0,1,2,3,4,5,6,7,8,9] ],###控制哪些检测类别显示、输出
|
||||
'segRegionCnt':2,###分割模型结果需要保留的等值线数目
|
||||
"pixScale": 1.2,
|
||||
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
TRAFFIC_FARM_MODEL = ("3", "003", "交通模型", 'highWay2', lambda device, gpuName: {
|
||||
'device': str(device),
|
||||
'labelnames': ["行人", "车辆", "纵向裂缝", "横向裂缝", "修补", "网状裂纹", "坑槽", "块状裂纹", "积水", "影子", "事故"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 3,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
#'modelSize': (640, 360),
|
||||
'modelSize': (1920, 1080),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'predResize': True,
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': tracfficAccidentMixFunction,
|
||||
'pars': {
|
||||
#'modelSize': (640, 360),
|
||||
'modelSize': (1920,1080),
|
||||
'RoadArea': 16000,
|
||||
'roadVehicleAngle': 15,
|
||||
'speedRoadVehicleAngleMax': 75,
|
||||
'roundness': 1.0,
|
||||
'cls': 10,
|
||||
'vehicleFactor': 0.1,
|
||||
'confThres': 0.25,
|
||||
'roadIou': 0.6,
|
||||
'radius': 50,
|
||||
'vehicleFlag': False,
|
||||
'distanceFlag': False
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 10,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/highWay2/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': '../AIlib2/weights/highWay2/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
EPIDEMIC_PREVENTION_MODEL = ("4", "004", "防疫模型", None, None)
|
||||
|
||||
PLATE_MODEL = ("5", "005", "车牌模型", None, None)
|
||||
|
||||
VEHICLE_MODEL = ("6", "006", "车辆模型", 'vehicle', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["车辆"],
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/vehicle/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
PEDESTRIAN_MODEL = ("7", "007", "行人模型", 'pedestrian', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["行人"],
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 0,
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/pedestrian/yolov5_%s_fp16.engine" % gpuName,
|
||||
'slopeIndex': [],
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
SMOGFIRE_MODEL = ("8", "008", "烟火模型", 'smogfire', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["火焰", "烟雾"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/smogfire/yolov5_%s_fp16.engine" % gpuName,
|
||||
'slopeIndex': [],
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
ANGLERSWIMMER_MODEL = ("9", "009", "钓鱼游泳模型", 'AnglerSwimmer', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["钓鱼", "游泳"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/AnglerSwimmer/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
COUNTRYROAD_MODEL = ("10", "010", "乡村模型", 'countryRoad', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["违法种植"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/countryRoad/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
SHIP_MODEL = ("11", "011", "船只模型", 'ship2', lambda device, gpuName: {
|
||||
'model_size': (608, 608),
|
||||
'K': 100,
|
||||
'conf_thresh': 0.18,
|
||||
'device': 'cuda:%s' % device,
|
||||
'down_ratio': 4,
|
||||
'num_classes': 15,
|
||||
'weights': '../AIlib2/weights/ship2/obb_608X608_%s_fp16.engine' % gpuName,
|
||||
'dataset': 'dota',
|
||||
'half': False,
|
||||
'mean': (0.5, 0.5, 0.5),
|
||||
'std': (1, 1, 1),
|
||||
'heads': {'hm': None, 'wh': 10, 'reg': 2, 'cls_theta': 1},
|
||||
'decoder': None,
|
||||
'test_flag': True,
|
||||
"rainbows": COLOR,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'drawBox': False,
|
||||
'label_array': None,
|
||||
'labelnames': ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "船只"),
|
||||
})
|
||||
|
||||
BAIDU_MODEL = ("12", "012", "百度AI图片识别模型", None, None)
|
||||
|
||||
CHANNEL_EMERGENCY_MODEL = ("13", "013", "航道模型", 'channelEmergency', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["人"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/channelEmergency/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
RIVER2_MODEL = ("15", "015", "河道检测模型", 'river2', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["漂浮物", "岸坡垃圾", "排口", "违建", "菜地", "水生植物", "河湖人员", "钓鱼人员", "船只",
|
||||
"蓝藻"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 1,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': riverDetSegMixProcess,
|
||||
'pars': {
|
||||
'slopeIndex': [1, 3, 4, 7],
|
||||
'riverIou': 0.1
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.3,
|
||||
"ovlap_thres_crossCategory": 0.65,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
# "../AIlib2/weights/conf/%s/yolov5.pt" % modeType.value[3]
|
||||
'Detweights': "../AIlib2/weights/river2/yolov5_%s_fp16.engine" % gpuName,
|
||||
# '../AIlib2/weights/conf/%s/stdc_360X640.pth' % modeType.value[3]
|
||||
'Segweights': '../AIlib2/weights/river2/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
CITY_MANGEMENT_MODEL = ("16", "016", "城管模型", 'cityMangement2', lambda device, gpuName: {
|
||||
'labelnames': ["车辆", "垃圾", "商贩", "裸土","占道经营","违停"],
|
||||
'postProcess':{
|
||||
'function':dmpr_yolo_stdc,
|
||||
'pars':{'carCls':0 ,'illCls':5,'scaleRatio':0.5,'border':80}
|
||||
},
|
||||
'models':[
|
||||
{
|
||||
#'weight':'../AIlib2/weights/conf/cityMangement3/yolov5.pt',
|
||||
'weight':'../AIlib2/weights/cityMangement3/yolov5_%s_fp16.engine'%(gpuName),
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.45,'allowedList':[0,1,2,3,4,5],'segRegionCnt':1, 'trtFlag_det':False,'trtFlag_seg':False, "score_byClass":{"0":0.8,"1":0.4,"2":0.5,"3":0.5,"4":0.4,"5":0.5 } }
|
||||
},
|
||||
{
|
||||
'weight':'../AIlib2/weights/conf/cityMangement3/dmpr.pth',
|
||||
'par':{
|
||||
'depth_factor':32,'NUM_FEATURE_MAP_CHANNEL':6,'dmpr_thresh':0.1, 'dmprimg_size':640,
|
||||
'name':'dmpr'
|
||||
},
|
||||
'model':DMPRModel,
|
||||
'name':'dmpr'
|
||||
},
|
||||
{
|
||||
'weight':'../AIlib2/weights/conf/cityMangement3/stdc_360X640.pth',
|
||||
'par':{
|
||||
'modelSize':(640,360),'mean':(0.485, 0.456, 0.406),'std' :(0.229, 0.224, 0.225),'predResize':True,'numpy':False, 'RGB_convert_first':True,'seg_nclass':2},###分割模型预处理参数
|
||||
'model':stdcModel,
|
||||
'name':'stdc'
|
||||
}
|
||||
],
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'detModelpara':[{"id":str(x),"config":{"k1":"v1","k2":"v2"}} for x in [0,1,2,3,5,6,7,8,9] ],###控制哪些检测类别显示、输出
|
||||
'segRegionCnt':2,###分割模型结果需要保留的等值线数目
|
||||
"pixScale": 1.2,
|
||||
})
|
||||
|
||||
DROWING_MODEL = ("17", "017", "人员落水模型", 'drowning', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["人头", "人", "船只"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'predResize': True,
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': mixDrowing_water_postprocess,
|
||||
'pars': {
|
||||
'modelSize': (640, 360)
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 9,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
# "../AIlib2/weights/conf/%s/yolov5.pt" % modeType.value[3]
|
||||
'Detweights': "../AIlib2/weights/drowning/yolov5_%s_fp16.engine" % gpuName,
|
||||
# '../AIlib2/weights/conf/%s/stdc_360X640.pth' % modeType.value[3]
|
||||
'Segweights': '../AIlib2/weights/drowning/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
NOPARKING_MODEL = (
|
||||
"18", "018", "城市违章模型", 'noParking', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["车辆", "违停"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 4,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'predResize': True,
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True, ###分割模型预处理参数
|
||||
'mixFunction': {
|
||||
'function': mixNoParking_road_postprocess,
|
||||
'pars': {
|
||||
'modelSize': (640, 360),
|
||||
'roundness': 0.3,
|
||||
'cls': 9,
|
||||
'laneArea': 10,
|
||||
'laneAngleCha': 5,
|
||||
'RoadArea': 16000,
|
||||
'fitOrder':2
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 9,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/noParking/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': '../AIlib2/weights/noParking/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
ILLPARKING_MODEL = ("19", "019", "车辆违停模型", 'illParking', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["车", "T角点", "L角点", "违停"],
|
||||
'trtFlag_seg': False,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 4,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
'mixFunction': {
|
||||
'function': illParking_postprocess,
|
||||
'pars': {}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 9,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/illParking/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
CITYROAD_MODEL = ("20", "020", "城市公路模型", 'cityRoad', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["护栏", "交通标志", "非交通标志", "施工", "施工"],
|
||||
'trtFlag_seg': False,
|
||||
'trtFlag_det': True,
|
||||
'slopeIndex': [],
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 0,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.8,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/cityRoad/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': None
|
||||
})
|
||||
|
||||
POTHOLE_MODEL = ("23", "023", "坑槽检测模型", 'pothole', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["坑槽"],
|
||||
'seg_nclass': 2, # 分割模型类别数目,默认2类
|
||||
'segRegionCnt': 0,
|
||||
'slopeIndex': [],
|
||||
'trtFlag_det': True,
|
||||
'trtFlag_seg': False,
|
||||
'Detweights': "../AIlib2/weights/pothole/yolov5_%s_fp16.engine" % gpuName,
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None,
|
||||
})
|
||||
|
||||
CHANNEL2_MODEL = ("24", "024", "船只综合检测模型", 'channel2', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'gpu_name': gpuName,
|
||||
'labelnames': ["国旗", "浮标", "船名", "船只","未挂国旗船只"],
|
||||
'segRegionCnt': 0,
|
||||
'postProcess':{'function':channel2_post_process,'name':'channel2','pars':{
|
||||
'objs':[2],
|
||||
'wRation':1/6.0,
|
||||
'hRation':1/6.0,
|
||||
'smallId':0,
|
||||
'bigId':3,
|
||||
'newId':4,
|
||||
'recScale':1.2}},
|
||||
'models':[
|
||||
{
|
||||
#'weight':'../AIlib2/weights/conf/channel2/yolov5.pt',
|
||||
'weight':'../AIlib2/weights/channel2/yolov5_%s_fp16.engine'%(gpuName),
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.1,'iou_thres':0.45,'allowedList':list(range(20)),'segRegionCnt':1, 'trtFlag_det':False,'trtFlag_seg':False, "score_byClass":{"0":0.7,"1":0.7,"2":0.8,"3":0.6} }
|
||||
},
|
||||
{
|
||||
# 'weight' : '../AIlib2/weights/ocr2/crnn_ch_4090_fp16_192X32.engine',
|
||||
'weight' : '../AIlib2/weights/conf/ocr2/crnn_ch.pth',
|
||||
'name':'ocr',
|
||||
'model':ocrModel,
|
||||
'par':{
|
||||
'char_file':'../AIlib2/weights/conf/ocr2/benchmark.txt',
|
||||
'mode':'ch',
|
||||
'nc':3,
|
||||
'imgH':32,
|
||||
'imgW':192,
|
||||
'hidden':256,
|
||||
'mean':[0.5,0.5,0.5],
|
||||
'std':[0.5,0.5,0.5],
|
||||
'dynamic':False,
|
||||
},
|
||||
}
|
||||
],
|
||||
'detModelpara':[{"id":str(x),"config":{"k1":"v1","k2":"v2"}} for x in [0,1,2,3]],
|
||||
'segPar': None,
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Segweights': None,
|
||||
})
|
||||
|
||||
RIVERT_MODEL = ("25", "025", "河道检测模型(T)", 'riverT', lambda device, gpuName: {
|
||||
'device': device,
|
||||
'labelnames': ["漂浮物", "岸坡垃圾", "排口", "违建", "菜地", "水生植物", "河湖人员", "钓鱼人员", "船只",
|
||||
"蓝藻"],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 2,
|
||||
'segRegionCnt': 1,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': riverDetSegMixProcess,
|
||||
'pars': {
|
||||
'slopeIndex': [1, 3, 4, 7],
|
||||
'riverIou': 0.1
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.3,
|
||||
"ovlap_thres_crossCategory": 0.65,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
# "../AIlib2/weights/conf/%s/yolov5.pt" % modeType.value[3]
|
||||
'Detweights': "../AIlib2/weights/riverT/yolov5_%s_fp16.engine" % gpuName,
|
||||
# '../AIlib2/weights/conf/%s/stdc_360X640.pth' % modeType.value[3]
|
||||
'Segweights': '../AIlib2/weights/riverT/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
|
||||
|
||||
FORESTCROWD_FARM_MODEL = ("26", "026", "森林人群模型", 'forestCrowd', lambda device, gpuName: {
|
||||
'labelnames': ["林斑", "病死树", "行人", "火焰", "烟雾","人群"],
|
||||
'postProcess':{'function':gather_post_process,'pars':{'pedestrianId':2,'crowdThreshold':4,'gatherId':5,'distancePersonScale':2.0}},
|
||||
'models':
|
||||
[
|
||||
{
|
||||
'weight':"../AIlib2/weights/forestCrowd/yolov5_%s_fp16.engine"%(gpuName),###检测模型路径
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.45,'allowedList':[0,1,2,3],'segRegionCnt':1, 'trtFlag_det':False,'trtFlag_seg':False, "score_byClass":{ "0":0.25,"1":0.25,"2":0.6,"3":0.6,'4':0.6 ,'5':0.6 } },
|
||||
}
|
||||
|
||||
|
||||
],
|
||||
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.45,
|
||||
"classes": 5,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'detModelpara':[{"id":str(x),"config":{"k1":"v1","k2":"v2"}} for x in [0,1,2,3,4,5,6,7,8,9] ],###控制哪些检测类别显示、输出
|
||||
'segRegionCnt':2,###分割模型结果需要保留的等值线数目
|
||||
"pixScale": 1.2,
|
||||
|
||||
|
||||
})
|
||||
TRAFFICFORDSJ_FARM_MODEL = ("27", "027", "交通模型-大数据局", 'highWay2T', lambda device, gpuName: {
|
||||
'device': str(device),
|
||||
'labelnames': ["行人", "车辆", "纵向裂缝", "横向裂缝", "修补", "网状裂纹", "坑槽", "块状裂纹", "积水", "影子", "事故", "桥梁外观","设施破损缺失","龙门架","防抛网","标识牌损坏","护栏损坏","钢筋裸露" ],
|
||||
'trtFlag_seg': True,
|
||||
'trtFlag_det': True,
|
||||
'seg_nclass': 3,
|
||||
'segRegionCnt': 2,
|
||||
'segPar': {
|
||||
'modelSize': (640, 360),
|
||||
'mean': (0.485, 0.456, 0.406),
|
||||
'std': (0.229, 0.224, 0.225),
|
||||
'predResize': True,
|
||||
'numpy': False,
|
||||
'RGB_convert_first': True,
|
||||
'mixFunction': {
|
||||
'function': tracfficAccidentMixFunction,
|
||||
'pars': {
|
||||
'modelSize': (640, 360),
|
||||
#'modelSize': (1920,1080),
|
||||
'RoadArea': 16000,
|
||||
'roadVehicleAngle': 15,
|
||||
'speedRoadVehicleAngleMax': 75,
|
||||
'roundness': 1.0,
|
||||
'cls': 9,
|
||||
'vehicleFactor': 0.1,
|
||||
'confThres': 0.25,
|
||||
'roadIou': 0.6,
|
||||
'radius': 50,
|
||||
'vehicleFlag': False,
|
||||
'distanceFlag': False
|
||||
}
|
||||
}
|
||||
},
|
||||
'postFile': {
|
||||
"name": "post_process",
|
||||
"conf_thres": 0.25,
|
||||
"iou_thres": 0.25,
|
||||
"classes": 10,
|
||||
"rainbows": COLOR
|
||||
},
|
||||
'Detweights': "../AIlib2/weights/highWay2/yolov5_%s_fp16.engine" % gpuName,
|
||||
'Segweights': '../AIlib2/weights/highWay2/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
SMARTSITE_MODEL = ("28", "028", "智慧工地模型", 'smartSite', lambda device, gpuName: {
|
||||
'labelnames': [ "工人","塔式起重机","悬臂","起重机","压路机","推土机","挖掘机","卡车","装载机","泵车","混凝土搅拌车","打桩","其他车辆" ],
|
||||
'postProcess':{'function':default_mix,'pars':{}},
|
||||
'models':
|
||||
[
|
||||
{
|
||||
'weight':"../AIlib2/weights/smartSite/yolov5_%s_fp16.engine"%(gpuName),###检测模型路径
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.45,'allowedList':list(range(20)),'segRegionCnt':1, 'trtFlag_det':True,'trtFlag_seg':False, "score_byClass":{"0":0.25,"1":0.3,"2":0.3,"3":0.3 } },
|
||||
}
|
||||
|
||||
|
||||
],
|
||||
'postFile': {
|
||||
"rainbows": COLOR
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
RUBBISH_MODEL = ("29", "029", "垃圾模型", 'rubbish', lambda device, gpuName: {
|
||||
'labelnames': [ "建筑垃圾","白色垃圾","其他垃圾"],
|
||||
'postProcess':{'function':default_mix,'pars':{}},
|
||||
'models':
|
||||
[
|
||||
{
|
||||
'weight':"../AIlib2/weights/rubbish/yolov5_%s_fp16.engine"%(gpuName),###检测模型路径
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.45,'allowedList':list(range(20)),'segRegionCnt':1, 'trtFlag_det':True,'trtFlag_seg':False, "score_byClass":{"0":0.25,"1":0.3,"2":0.3,"3":0.3 } },
|
||||
}
|
||||
|
||||
|
||||
],
|
||||
'postFile': {
|
||||
"rainbows": COLOR
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
FIREWORK_MODEL = ("30", "030", "烟花模型", 'firework', lambda device, gpuName: {
|
||||
'labelnames': [ "烟花"],
|
||||
'postProcess':{'function':default_mix,'pars':{}},
|
||||
'models':
|
||||
[
|
||||
{
|
||||
'weight':"../AIlib2/weights/firework/yolov5_%s_fp16.engine"%(gpuName),###检测模型路径
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.45,'allowedList':list(range(20)),'segRegionCnt':1, 'trtFlag_det':True,'trtFlag_seg':False, "score_byClass":{"0":0.25,"1":0.3,"2":0.3,"3":0.3 } },
|
||||
}
|
||||
|
||||
|
||||
],
|
||||
'postFile': {
|
||||
"rainbows": COLOR
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
|
||||
@staticmethod
|
||||
def checkCode(code):
|
||||
for model in ModelType:
|
||||
if model.value[1] == code:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
'''
|
||||
参数1: 检测目标名称
|
||||
参数2: 检测目标
|
||||
参数3: 初始化百度检测客户端
|
||||
'''
|
||||
|
||||
|
||||
@unique
|
||||
class BaiduModelTarget(Enum):
|
||||
VEHICLE_DETECTION = (
|
||||
"车辆检测", 0, lambda client0, client1, url, request_id: client0.vehicleDetectUrl(url, request_id))
|
||||
|
||||
HUMAN_DETECTION = (
|
||||
"人体检测与属性识别", 1, lambda client0, client1, url, request_id: client1.bodyAttr(url, request_id))
|
||||
|
||||
PEOPLE_COUNTING = ("人流量统计", 2, lambda client0, client1, url, request_id: client1.bodyNum(url, request_id))
|
||||
|
||||
|
||||
BAIDU_MODEL_TARGET_CONFIG = {
|
||||
BaiduModelTarget.VEHICLE_DETECTION.value[1]: BaiduModelTarget.VEHICLE_DETECTION,
|
||||
BaiduModelTarget.HUMAN_DETECTION.value[1]: BaiduModelTarget.HUMAN_DETECTION,
|
||||
BaiduModelTarget.PEOPLE_COUNTING.value[1]: BaiduModelTarget.PEOPLE_COUNTING
|
||||
}
|
||||
|
||||
EPIDEMIC_PREVENTION_CONFIG = {1: "行程码", 2: "健康码"}
|
||||
|
||||
|
||||
# 模型分析方式
|
||||
@unique
|
||||
class ModelMethodTypeEnum(Enum):
|
||||
# 方式一: 正常识别方式
|
||||
NORMAL = 1
|
||||
|
||||
# 方式二: 追踪识别方式
|
||||
TRACE = 2
|
||||
|
|
@ -374,8 +374,8 @@ class ModelType(Enum):
|
|||
},
|
||||
'models':[
|
||||
{
|
||||
'weight':'../weights/trt/AIlib2/cityMangement3/yolov5_%s_fp16.engine'%(gpuName),
|
||||
'name':'yolov5',
|
||||
'weight':'../weights/trt/AIlib2/cityMangement3/yolov5_%s_fp16.engine'%(gpuName),
|
||||
'name':'yolov5',
|
||||
'model':yolov5Model,
|
||||
'par':{ 'half':True,'device':'cuda:0' ,'conf_thres':0.25,'iou_thres':0.45,'allowedList':[0,1,2,3,4,5,6,7],'segRegionCnt':1, 'trtFlag_det':True,'trtFlag_seg':True, "score_byClass":{"0":0.8,"1":0.4,"2":0.5,"3":0.5 } }
|
||||
},
|
||||
|
|
@ -633,6 +633,8 @@ class ModelType(Enum):
|
|||
'Segweights': '../weights/trt/AIlib2/riverT/stdc_360X640_%s_fp16.engine' % gpuName
|
||||
})
|
||||
|
||||
|
||||
|
||||
FORESTCROWD_FARM_MODEL = ("26", "026", "森林人群模型", 'forestCrowd', lambda device, gpuName: {
|
||||
'labelnames': ["林斑", "病死树", "行人", "火焰", "烟雾","人群"],
|
||||
'postProcess':{'function':gather_post_process,'pars':{'pedestrianId':2,'crowdThreshold':4,'gatherId':5,'distancePersonScale':2.0}},
|
||||
|
|
@ -974,14 +976,12 @@ class ModelType(Enum):
|
|||
'row': 2,
|
||||
'line': 2,
|
||||
'point_loss_coef': 0.45,
|
||||
'conf': 0.65,
|
||||
'conf': 0.25,
|
||||
'gpu_id': 0,
|
||||
'eos_coef': '0.5',
|
||||
'set_cost_class': 1,
|
||||
'set_cost_point': 0.05,
|
||||
'backbone': 'vgg16_bn',
|
||||
'expend': 10,
|
||||
'psize': 2,
|
||||
'backbone': 'vgg16_bn'
|
||||
},
|
||||
}],
|
||||
})
|
||||
|
|
@ -1006,42 +1006,6 @@ class ModelType(Enum):
|
|||
|
||||
})
|
||||
|
||||
CITY_UNDERBUILDCOUNT_MODEL = ("30", "306", "建筑物下人群计数", 'perUnderBuild', lambda device, gpuName: {
|
||||
'labelnames': ["建筑物下人群"],
|
||||
'device': str(device),
|
||||
'rainbows': COLOR,
|
||||
'models': [
|
||||
{
|
||||
'weight': "../weights/trt/AIlib2/perUnderBuild/yolov5_%s_fp16.engine" % (gpuName), ###检测模型路径
|
||||
'name': 'yolov5',
|
||||
'model': yolov5Model,
|
||||
'par': {'half': True, 'device': 'cuda:0', 'conf_thres': 0.25, 'iou_thres': 0.45,
|
||||
'allowedList': [0,1,2], 'segRegionCnt': 1, 'trtFlag_det': True,
|
||||
'trtFlag_seg': False, "score_byClass": {"0": 0.25, "1": 0.3, "2": 0.3, "3": 0.3}},
|
||||
},
|
||||
{
|
||||
'trtFlag_det': False,
|
||||
'weight': "../weights/pth/AIlib2/DenseCrowd/SHTechA.pth", ###检测模型路径
|
||||
'vggweight': "../weights/pth/AIlib2/DenseCrowd/vgg16_bn-6c64b313.pth", ###检测模型路径
|
||||
'name': 'p2pnet',
|
||||
'model': p2NnetModel,
|
||||
'par': {
|
||||
'device': 'cuda:0',
|
||||
'row': 2,
|
||||
'line': 2,
|
||||
'point_loss_coef': 0.45,
|
||||
'conf': 0.50,
|
||||
'gpu_id': 0,
|
||||
'eos_coef': '0.5',
|
||||
'set_cost_class': 1,
|
||||
'set_cost_point': 0.05,
|
||||
'backbone': 'vgg16_bn',
|
||||
'expend': 10,
|
||||
'psize': 5
|
||||
},
|
||||
}],
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
def checkCode(code):
|
||||
for model in ModelType:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
1.2025.01.21把之前的tuoheng alg仓库代码重新开个仓库
|
||||
(1)在config/service/dsp_test_service.yml里面添加参数,控制存储用的oss还是minio
|
||||
storage_source: 1
|
||||
2.2025.02.06
|
||||
(1)修改代码,把mqtt读取加入到系统中。config/service/dsp_test_service.yml,中添加mqtt_flag,决定是否启用。
|
||||
(2)修改了minio情况下的,文件名命名方式。
|
||||
3.2025.02.12
|
||||
(1)增加了对alg算法开发的代码。可以通过配置文件config/service/dsp_test_service.yml中algSwitch: true,决定是否启用。
|
||||
|
|
@ -0,0 +1,507 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import time,os
|
||||
from os.path import join
|
||||
from traceback import format_exc
|
||||
import json
|
||||
from cerberus import Validator
|
||||
|
||||
from common.Constant import ONLINE_START_SCHEMA, ONLINE_STOP_SCHEMA, OFFLINE_START_SCHEMA, OFFLINE_STOP_SCHEMA, \
|
||||
IMAGE_SCHEMA, RECORDING_START_SCHEMA, RECORDING_STOP_SCHEMA, PULL2PUSH_START_SCHEMA, PULL2PUSH_STOP_SCHEMA
|
||||
from common.YmlConstant import service_yml_path, kafka_yml_path
|
||||
from concurrency.FeedbackThread import FeedbackThread
|
||||
from concurrency.uploadGPU import uploadGPUinfos
|
||||
from concurrency.IntelligentRecognitionProcess2 import OnlineIntelligentRecognitionProcess2, \
|
||||
OfflineIntelligentRecognitionProcess2, PhotosIntelligentRecognitionProcess2
|
||||
from concurrency.Pull2PushStreamProcess import PushStreamProcess
|
||||
from entity.FeedBack import message_feedback, recording_feedback, pull_stream_feedback
|
||||
from enums.AnalysisStatusEnum import AnalysisStatus
|
||||
from enums.AnalysisTypeEnum import AnalysisType
|
||||
from enums.ExceptionEnum import ExceptionType
|
||||
from enums.ModelTypeEnum import ModelMethodTypeEnum, ModelType
|
||||
from enums.RecordingStatusEnum import RecordingStatus
|
||||
from enums.StatusEnum import PushStreamStatus, ExecuteStatus
|
||||
from exception.CustomerException import ServiceException
|
||||
from loguru import logger
|
||||
from multiprocessing import Queue
|
||||
from concurrency.IntelligentRecognitionProcess import OnlineIntelligentRecognitionProcess, \
|
||||
OfflineIntelligentRecognitionProcess, PhotosIntelligentRecognitionProcess, ScreenRecordingProcess
|
||||
from util.CpuUtils import print_cpu_ex_status
|
||||
from util.FileUtils import create_dir_not_exist
|
||||
from util.GPUtils import get_first_gpu_name, print_gpu_ex_status, check_cude_is_available,select_best_server
|
||||
from util.KafkaUtils import CustomerKafkaConsumer
|
||||
from util.QueUtil import put_queue
|
||||
from util.RWUtils import getConfigs
|
||||
from kafka import KafkaProducer, KafkaConsumer
|
||||
'''
|
||||
分发服务
|
||||
'''
|
||||
|
||||
|
||||
class DispatcherService:
|
||||
__slots__ = ('__context', '__feedbackThread', '__listeningProcesses', '__fbQueue', '__topics','__taskType', '__task_type',
|
||||
'__kafka_config', '__recordingProcesses', '__pull2PushProcesses','__topicsPort','__gpuTopic','__role','__uploadGPUThread','__gpuDics','__producer')
|
||||
|
||||
def __init__(self, base_dir, env):
|
||||
# 检测cuda是否活动
|
||||
check_cude_is_available()
|
||||
# 获取全局上下文配置
|
||||
self.__context = getConfigs(join(base_dir, service_yml_path % env))
|
||||
# 创建任务执行, 视频保存路径
|
||||
create_dir_not_exist(join(base_dir, self.__context["video"]["file_path"]))
|
||||
# 将根路径和环境设置到上下文中
|
||||
self.__context["base_dir"], self.__context["env"] = base_dir, env
|
||||
|
||||
# 问题反馈线程
|
||||
self.__feedbackThread,self.__uploadGPUThread, self.__fbQueue = None,None, Queue()
|
||||
# 实时、离线、图片任务进程字典
|
||||
self.__listeningProcesses = {}
|
||||
# 录屏任务进程字典
|
||||
self.__recordingProcesses = {}
|
||||
# 转推流任务进程字典
|
||||
self.__pull2PushProcesses = {}
|
||||
self.__kafka_config = getConfigs(join(base_dir, kafka_yml_path % env))
|
||||
|
||||
self.__producer = KafkaProducer(
|
||||
bootstrap_servers=self.__kafka_config['bootstrap_servers'],#tencent yun
|
||||
value_serializer=lambda v: v.encode('utf-8'))
|
||||
|
||||
self.__gpuDics = { }#用于存储gpu信息的字典
|
||||
self.__role = self.__context["role"]
|
||||
self.__topics = [
|
||||
self.__kafka_config["topic"]["dsp-alg-online-tasks-topic"], # 实时监听topic
|
||||
self.__kafka_config["topic"]["dsp-alg-offline-tasks-topic"], # 离线监听topic
|
||||
self.__kafka_config["topic"]["dsp-alg-image-tasks-topic"], # 图片监听topic
|
||||
self.__kafka_config["topic"]["dsp-recording-task-topic"], # 录屏监听topic
|
||||
self.__kafka_config["topic"]["dsp-push-stream-task-topic"] # 推流监听topic
|
||||
]
|
||||
|
||||
self.__topicsPort = [
|
||||
self.__kafka_config["topicPort"]["dsp-alg-online-tasks-topic"], # 实时监听topic
|
||||
self.__kafka_config["topicPort"]["dsp-alg-offline-tasks-topic"], # 离线监听topic
|
||||
self.__kafka_config["topicPort"]["dsp-alg-image-tasks-topic"], # 图片监听topic
|
||||
self.__kafka_config["topicPort"]["dsp-recording-task-topic"], # 录屏监听topic
|
||||
self.__kafka_config["topicPort"]["dsp-push-stream-task-topic"] # 推流监听topic
|
||||
]
|
||||
self.__gpuTopic = [self.__kafka_config["topicGPU"]]
|
||||
|
||||
if self.__role==1:
|
||||
self.__topics = self.__topics + self.__topicsPort + self.__gpuTopic
|
||||
|
||||
|
||||
# 对应topic的各个lambda表达式
|
||||
self.__task_type = {
|
||||
self.__topics[0]: (AnalysisType.ONLINE.value, lambda x, y: self.online(x, y),
|
||||
lambda x, y, z: self.identify_method(x, y, z)),
|
||||
self.__topics[1]: (AnalysisType.OFFLINE.value, lambda x, y: self.offline(x, y),
|
||||
lambda x, y, z: self.identify_method(x, y, z)),
|
||||
self.__topics[2]: (AnalysisType.IMAGE.value, lambda x, y: self.image(x, y),
|
||||
lambda x, y, z: self.identify_method(x, y, z)),
|
||||
self.__topics[3]: (AnalysisType.RECORDING.value, lambda x, y: self.recording(x, y),
|
||||
lambda x, y, z: self.recording_method(x, y, z)),
|
||||
self.__topics[4]: (AnalysisType.PULLTOPUSH.value, lambda x, y: self.pullStream(x, y),
|
||||
lambda x, y, z: self.push_stream_method(x, y, z))
|
||||
|
||||
}
|
||||
self.__taskType={
|
||||
self.__kafka_config["topic"]["dsp-alg-online-tasks-topic"]:0, # 实时监听topic
|
||||
self.__kafka_config["topic"]["dsp-alg-offline-tasks-topic"]:1, # 离线监听topic
|
||||
self.__kafka_config["topic"]["dsp-alg-image-tasks-topic"]:2, # 图片监听topic
|
||||
self.__kafka_config["topic"]["dsp-recording-task-topic"]:3, # 录屏监听topic
|
||||
self.__kafka_config["topic"]["dsp-push-stream-task-topic"]:4 # 推流监听topic
|
||||
}
|
||||
gpu_name_array = get_first_gpu_name()
|
||||
gpu_array = [g for g in ('3090', '2080', '4090', 'A10') if g in gpu_name_array]
|
||||
gpu_name = '2080Ti'
|
||||
if len(gpu_array) > 0:
|
||||
if gpu_array[0] != '2080':
|
||||
gpu_name = gpu_array[0]
|
||||
else:
|
||||
raise Exception("GPU资源不在提供的模型所支持的范围内!请先提供对应的GPU模型!")
|
||||
logger.info("当前服务环境为: {}, 服务器GPU使用型号: {}", env, gpu_name)
|
||||
self.__context["gpu_name"] = gpu_name
|
||||
self.start_service()
|
||||
|
||||
# 服务调用启动方法
|
||||
def start_service(self):
|
||||
# 初始化kafka监听者
|
||||
customerKafkaConsumer = CustomerKafkaConsumer(self.__kafka_config, topics=self.__topics)
|
||||
####增加一个线程,用于试试监控和发送gpu状态####
|
||||
####
|
||||
logger.info("(♥◠‿◠)ノ゙ DSP【算法调度服务】启动成功 服务器IP:{}".format(self.__kafka_config['bootstrap_servers'] ))
|
||||
while True:
|
||||
try:
|
||||
# 检查任务进程运行情况,去除结束的任务
|
||||
self.check_process_task()
|
||||
# 启动反馈线程
|
||||
self.start_feedback_thread()
|
||||
self.start_uploadGPU_thread()
|
||||
msg = customerKafkaConsumer.poll()
|
||||
if msg is not None and len(msg) > 0:
|
||||
for k, v in msg.items():
|
||||
for m in v:
|
||||
message = m.value
|
||||
#如果收到的信息是gpu状态的话,收到信息后,更新自己的gpu服务器状态,下面不再执行
|
||||
if m.topic in self.__gpuTopic:
|
||||
customerKafkaConsumer.commit_offset(m,'x'*16,False)
|
||||
#更新机器资源现状
|
||||
ip = message['System']['Local IP Address']
|
||||
self.__gpuDics[ip]=message
|
||||
continue
|
||||
#如果收到的信息是门户消息,收到信息后,要根据Gpu状态,转发到对应的机器。
|
||||
elif m.topic in self.__topicsPort:
|
||||
customerKafkaConsumer.commit_offset(m, 'y'*16)
|
||||
#状态分析
|
||||
#recondGpu={'hostname':'thsw2','IP':'192.168.10.66','gpuId':0}
|
||||
recondGpu= select_best_server(self.__gpuDics)
|
||||
if recondGpu is None:
|
||||
print( 'recondGpu:',recondGpu, ' self.__gpuDics: ',self.__gpuDics,' topic:',m.topic, ' message:',message )
|
||||
continue
|
||||
#转发消息
|
||||
message['transmit_topic'] = m.topic + '-' + recondGpu['IP']
|
||||
transmitMsg={'transmit':message}
|
||||
msg_json = json.dumps( message )
|
||||
future = self.__producer.send( message['transmit_topic'] ,msg_json)
|
||||
try:
|
||||
future.get(timeout=2)
|
||||
logger.info( "转发消息成功,消息topic:{},消息内容:{}",message['transmit_topic'],message )
|
||||
except kafka_errors as e:
|
||||
print('------transmitted error:',e)
|
||||
logger.info("转发消息失败")
|
||||
traceback.format_exc()
|
||||
else:
|
||||
requestId = message.get("request_id")
|
||||
if requestId is None:
|
||||
logger.error("请求参数格式错误, 请检查请求体格式是否正确!message:%s"%(message))
|
||||
continue
|
||||
customerKafkaConsumer.commit_offset(m, requestId)
|
||||
logger.info("当前拉取到的消息, topic:{}, offset:{}, partition: {}, body: {}, requestId:{}",
|
||||
m.topic, m.offset, m.partition, message, requestId)
|
||||
|
||||
message['taskType']=self.__taskType[m.topic]
|
||||
topic_method = self.__task_type[m.topic]
|
||||
topic_method[2](topic_method[1], message, topic_method[0])
|
||||
else:
|
||||
print_gpu_ex_status()
|
||||
print_cpu_ex_status(self.__context["base_dir"])
|
||||
time.sleep(1)
|
||||
except Exception:
|
||||
logger.error("主线程异常:{}", format_exc())
|
||||
|
||||
def identify_method(self, handle_method, message, analysisType):
|
||||
try:
|
||||
check_cude_is_available()
|
||||
handle_method(message, analysisType)
|
||||
except ServiceException as s:
|
||||
logger.error("消息监听异常:{}, requestId: {}", s.msg, message["request_id"])
|
||||
put_queue(self.__fbQueue, message_feedback(message["request_id"], AnalysisStatus.FAILED.value, analysisType,
|
||||
s.code, s.msg), timeout=1)
|
||||
except Exception:
|
||||
logger.error("消息监听异常:{}, requestId: {}", format_exc(), message["request_id"])
|
||||
put_queue(self.__fbQueue, message_feedback(message["request_id"], AnalysisStatus.FAILED.value, analysisType,
|
||||
ExceptionType.SERVICE_INNER_EXCEPTION.value[0],
|
||||
ExceptionType.SERVICE_INNER_EXCEPTION.value[1]), timeout=1)
|
||||
finally:
|
||||
del message
|
||||
|
||||
def push_stream_method(self, handle_method, message, analysisType):
|
||||
try:
|
||||
check_cude_is_available()
|
||||
handle_method(message, analysisType)
|
||||
except ServiceException as s:
|
||||
logger.error("消息监听异常:{}, requestId: {}", s.msg, message['request_id'])
|
||||
videoInfo = [{"id": url.get("id"), "status": PushStreamStatus.FAILED.value[0]} for url in
|
||||
message.get("video_urls", []) if url.get("id") is not None]
|
||||
put_queue(self.__fbQueue, pull_stream_feedback(message['request_id'], ExecuteStatus.FAILED.value[0],
|
||||
s.code, s.msg, videoInfo), timeout=1)
|
||||
except Exception:
|
||||
logger.error("消息监听异常:{}, requestId: {}", format_exc(), message['request_id'])
|
||||
videoInfo = [{"id": url.get("id"), "status": PushStreamStatus.FAILED.value[0]} for url in
|
||||
message.get("video_urls", []) if url.get("id") is not None]
|
||||
put_queue(self.__fbQueue, pull_stream_feedback(message.get("request_id"), ExecuteStatus.FAILED.value[0],
|
||||
ExceptionType.SERVICE_INNER_EXCEPTION.value[0],
|
||||
ExceptionType.SERVICE_INNER_EXCEPTION.value[1], videoInfo),
|
||||
timeout=1)
|
||||
finally:
|
||||
del message
|
||||
|
||||
def recording_method(self, handle_method, message, analysisType):
|
||||
try:
|
||||
check_cude_is_available()
|
||||
handle_method(message, analysisType)
|
||||
except ServiceException as s:
|
||||
logger.error("消息监听异常:{}, requestId: {}", s.msg, message["request_id"])
|
||||
put_queue(self.__fbQueue,
|
||||
recording_feedback(message["request_id"], RecordingStatus.RECORDING_FAILED.value[0],
|
||||
error_code=s.code, error_msg=s.msg), timeout=1)
|
||||
except Exception:
|
||||
logger.error("消息监听异常:{}, requestId: {}", format_exc(), message["request_id"])
|
||||
put_queue(self.__fbQueue,
|
||||
recording_feedback(message["request_id"], RecordingStatus.RECORDING_FAILED.value[0],
|
||||
ExceptionType.SERVICE_INNER_EXCEPTION.value[0],
|
||||
ExceptionType.SERVICE_INNER_EXCEPTION.value[1]), timeout=1)
|
||||
finally:
|
||||
del message
|
||||
|
||||
# 开启实时进程
|
||||
def startOnlineProcess(self, msg, analysisType):
|
||||
if self.__listeningProcesses.get(msg["request_id"]):
|
||||
logger.warning("实时重复任务,请稍后再试!requestId:{}", msg["request_id"])
|
||||
return
|
||||
model_type = self.__context["service"]["model"]["model_type"]
|
||||
codes = [model.get("code") for model in msg["models"] if model.get("code")]
|
||||
if ModelMethodTypeEnum.NORMAL.value == model_type or ModelType.ILLPARKING_MODEL.value[1] in codes:
|
||||
coir = OnlineIntelligentRecognitionProcess(self.__fbQueue, msg, analysisType, self.__context)
|
||||
else:
|
||||
coir = OnlineIntelligentRecognitionProcess2(self.__fbQueue, msg, analysisType, self.__context)
|
||||
coir.start()
|
||||
logger.info("开始实时进程!requestId:{},pid:{}, ppid:{}", msg["request_id"],os.getpid(),os.getppid())
|
||||
self.__listeningProcesses[msg["request_id"]] = coir
|
||||
|
||||
# 结束实时进程
|
||||
def stopOnlineProcess(self, msg):
|
||||
ps = self.__listeningProcesses.get(msg["request_id"])
|
||||
if ps is None:
|
||||
logger.warning("未查询到该任务,无法停止任务!requestId:{}", msg["request_id"])
|
||||
return
|
||||
ps.sendEvent({"command": "stop"})
|
||||
|
||||
# 新增该函数用于,向子任务发送命令(algStart,algStop)
|
||||
def sendCmdToChildProcess(self, msg,cmd="algStart"):
|
||||
ps = self.__listeningProcesses.get(msg["request_id"])
|
||||
if ps is None:
|
||||
logger.warning("未查询到该任务,无法停止任务!requestId:{}", msg["request_id"])
|
||||
return
|
||||
ps.sendEvent({"command": cmd})
|
||||
|
||||
@staticmethod
|
||||
def check_process(listeningProcess):
|
||||
for requestId in list(listeningProcess.keys()):
|
||||
if not listeningProcess[requestId].is_alive():
|
||||
del listeningProcess[requestId]
|
||||
|
||||
def check_process_task(self):
|
||||
self.check_process(self.__listeningProcesses)
|
||||
self.check_process(self.__recordingProcesses)
|
||||
self.check_process(self.__pull2PushProcesses)
|
||||
|
||||
# 开启离线进程
|
||||
def startOfflineProcess(self, msg, analysisType):
|
||||
if self.__listeningProcesses.get(msg["request_id"]):
|
||||
logger.warning("离线重复任务,请稍后再试!requestId:{}", msg["request_id"])
|
||||
return
|
||||
model_type = self.__context["service"]["model"]["model_type"]
|
||||
codes = [model.get("code") for model in msg["models"] if model.get("code")]
|
||||
if ModelMethodTypeEnum.NORMAL.value == model_type:
|
||||
first = OfflineIntelligentRecognitionProcess(self.__fbQueue, msg, analysisType, self.__context)
|
||||
else:
|
||||
first = OfflineIntelligentRecognitionProcess2(self.__fbQueue, msg, analysisType, self.__context)
|
||||
first.start()
|
||||
self.__listeningProcesses[msg["request_id"]] = first
|
||||
|
||||
# 结束离线进程
|
||||
def stopOfflineProcess(self, msg):
|
||||
ps = self.__listeningProcesses.get(msg["request_id"])
|
||||
if ps is None:
|
||||
logger.warning("未查询到该任务,无法停止任务!requestId:{}", msg["request_id"])
|
||||
return
|
||||
ps.sendEvent({"command": "stop"})
|
||||
|
||||
# 开启图片分析进程
|
||||
def startImageProcess(self, msg, analysisType):
|
||||
pp = self.__listeningProcesses.get(msg["request_id"])
|
||||
if pp is not None:
|
||||
logger.warning("重复任务,请稍后再试!requestId:{}", msg["request_id"])
|
||||
return
|
||||
model_type = self.__context["service"]["model"]["model_type"]
|
||||
codes = [model.get("code") for model in msg["models"] if model.get("code")]
|
||||
if ModelMethodTypeEnum.NORMAL.value == model_type or ModelType.ILLPARKING_MODEL.value[1] in codes:
|
||||
imaged = PhotosIntelligentRecognitionProcess(self.__fbQueue, msg, analysisType, self.__context)
|
||||
else:
|
||||
imaged = PhotosIntelligentRecognitionProcess2(self.__fbQueue, msg, analysisType, self.__context)
|
||||
# 创建在线识别进程并启动
|
||||
imaged.start()
|
||||
self.__listeningProcesses[msg["request_id"]] = imaged
|
||||
|
||||
'''
|
||||
校验kafka消息
|
||||
'''
|
||||
|
||||
@staticmethod
|
||||
def check_msg(msg, schema):
|
||||
try:
|
||||
v = Validator(schema, allow_unknown=True)
|
||||
result = v.validate(msg)
|
||||
if not result:
|
||||
logger.error("参数校验异常: {}, requestId: {}", v.errors, msg["request_id"])
|
||||
raise ServiceException(ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[0],
|
||||
ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[1])
|
||||
except ServiceException as s:
|
||||
raise s
|
||||
except Exception:
|
||||
logger.error("参数校验异常: {}, requestId: {}", format_exc(), msg["request_id"])
|
||||
raise ServiceException(ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[0],
|
||||
ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[1])
|
||||
|
||||
'''
|
||||
开启反馈线程,用于发送消息
|
||||
'''
|
||||
|
||||
def start_feedback_thread(self):
|
||||
if self.__feedbackThread is None:
|
||||
self.__feedbackThread = FeedbackThread(self.__fbQueue, self.__kafka_config)
|
||||
self.__feedbackThread.setDaemon(True)
|
||||
self.__feedbackThread.start()
|
||||
time.sleep(1)
|
||||
if self.__feedbackThread and not self.__feedbackThread.is_alive():
|
||||
logger.error("反馈线程异常停止, 开始重新启动反馈线程!!!!!")
|
||||
self.__feedbackThread = FeedbackThread(self.__fbQueue, self.__kafka_config)
|
||||
self.__feedbackThread.setDaemon(True)
|
||||
self.__feedbackThread.start()
|
||||
time.sleep(1)
|
||||
|
||||
def start_uploadGPU_thread(self):
|
||||
if self.__uploadGPUThread is None:
|
||||
self.__uploadGPUThread = uploadGPUinfos(self.__context, self.__kafka_config)
|
||||
self.__uploadGPUThread.setDaemon(True)
|
||||
self.__uploadGPUThread.start()
|
||||
time.sleep(1)
|
||||
if self.__uploadGPUThread and not self.__uploadGPUThread.is_alive():
|
||||
logger.error("反馈线程异常停止, 开始重新启动反馈线程!!!!!")
|
||||
self.__uploadGPUThread = uploadGPUinfos(self.__context, self.__kafka_config)
|
||||
self.__uploadGPUThread.setDaemon(True)
|
||||
self.__uploadGPUThread.start()
|
||||
time.sleep(1)
|
||||
|
||||
'''
|
||||
在线分析逻辑
|
||||
'''
|
||||
|
||||
def online0(self, message, analysisType):
|
||||
if "start" == message.get("command"):
|
||||
self.check_msg(message, ONLINE_START_SCHEMA)
|
||||
if len(self.__listeningProcesses) >= int(self.__context['service']["task"]["limit"]):
|
||||
raise ServiceException(ExceptionType.NO_RESOURCES.value[0],
|
||||
ExceptionType.NO_RESOURCES.value[1])
|
||||
self.startOnlineProcess(message, analysisType)
|
||||
elif message.get("command") in ["algStart","algStop"]:
|
||||
self.sendCmdToChildProcess(message,cmd=message.get("command"))
|
||||
elif "stop" == message.get("command"):
|
||||
self.check_msg(message, ONLINE_STOP_SCHEMA)
|
||||
self.stopOnlineProcess(message)
|
||||
else:
|
||||
raise ServiceException(ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[0],
|
||||
ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[1])
|
||||
|
||||
|
||||
def online(self, message, analysisType):
|
||||
if "start" == message.get("command"):
|
||||
self.check_msg(message, ONLINE_START_SCHEMA)
|
||||
if len(self.__listeningProcesses) >= int(self.__context['service']["task"]["limit"]):
|
||||
raise ServiceException(ExceptionType.NO_RESOURCES.value[0],
|
||||
ExceptionType.NO_RESOURCES.value[1])
|
||||
self.startOnlineProcess(message, analysisType)
|
||||
|
||||
elif message.get("command") in ["algStart","algStop"]:
|
||||
|
||||
if message.get("defaultEnabled",True):
|
||||
self.sendCmdToChildProcess(message,cmd=message.get("command"))
|
||||
|
||||
|
||||
elif "stop" == message.get("command"):
|
||||
self.check_msg(message, ONLINE_STOP_SCHEMA)
|
||||
self.stopOnlineProcess(message)
|
||||
else:
|
||||
raise ServiceException(ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[0],
|
||||
ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[1])
|
||||
|
||||
|
||||
|
||||
|
||||
def offline(self, message, analysisType):
|
||||
if "start" == message.get("command"):
|
||||
self.check_msg(message, OFFLINE_START_SCHEMA)
|
||||
if len(self.__listeningProcesses) >= int(self.__context['service']["task"]["limit"]):
|
||||
raise ServiceException(ExceptionType.NO_RESOURCES.value[0],
|
||||
ExceptionType.NO_RESOURCES.value[1])
|
||||
self.startOfflineProcess(message, analysisType)
|
||||
elif message.get("command") in ["algStart","algStop"]:
|
||||
self.sendCmdToChildProcess( message,cmd=message.get("command"))
|
||||
elif "stop" == message.get("command"):
|
||||
self.check_msg(message, OFFLINE_STOP_SCHEMA)
|
||||
self.stopOfflineProcess(message)
|
||||
else:
|
||||
raise ServiceException(ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[0],
|
||||
ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[1])
|
||||
|
||||
def image(self, message, analysisType):
|
||||
if "start" == message.get("command"):
|
||||
self.check_msg(message, IMAGE_SCHEMA)
|
||||
if len(self.__listeningProcesses) >= int(self.__context['service']["task"]["image"]["limit"]):
|
||||
raise ServiceException(ExceptionType.NO_RESOURCES.value[0],
|
||||
ExceptionType.NO_RESOURCES.value[1])
|
||||
self.startImageProcess(message, analysisType)
|
||||
else:
|
||||
raise ServiceException(ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[0],
|
||||
ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[1])
|
||||
|
||||
def recording(self, message, analysisType):
|
||||
if "start" == message.get("command"):
|
||||
self.check_msg(message, RECORDING_START_SCHEMA)
|
||||
if len(self.__recordingProcesses) >= int(self.__context['service']["task"]["limit"]):
|
||||
raise ServiceException(ExceptionType.NO_RESOURCES.value[0],
|
||||
ExceptionType.NO_RESOURCES.value[1])
|
||||
self.startRecordingProcess(message, analysisType)
|
||||
elif "stop" == message.get("command"):
|
||||
self.check_msg(message, RECORDING_STOP_SCHEMA)
|
||||
self.stopRecordingProcess(message)
|
||||
else:
|
||||
raise ServiceException(ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[0],
|
||||
ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[1])
|
||||
|
||||
# 开启录屏进程
|
||||
def startRecordingProcess(self, msg, analysisType):
|
||||
if self.__listeningProcesses.get(msg["request_id"]):
|
||||
logger.warning("重复任务,请稍后再试!requestId:{}", msg["request_id"])
|
||||
return
|
||||
srp = ScreenRecordingProcess(self.__fbQueue, self.__context, msg, analysisType)
|
||||
srp.start()
|
||||
self.__recordingProcesses[msg["request_id"]] = srp
|
||||
|
||||
# 结束录屏进程
|
||||
def stopRecordingProcess(self, msg):
|
||||
rdp = self.__recordingProcesses.get(msg["request_id"])
|
||||
if rdp is None:
|
||||
logger.warning("未查询到该任务,无法停止任务!requestId:{}", msg["request_id"])
|
||||
return
|
||||
rdp.sendEvent({"command": "stop"})
|
||||
|
||||
def pullStream(self, message, analysisType):
|
||||
if "start" == message.get("command"):
|
||||
self.check_msg(message, PULL2PUSH_START_SCHEMA)
|
||||
if len(self.__pull2PushProcesses) >= int(self.__context['service']["task"]["limit"]):
|
||||
raise ServiceException(ExceptionType.NO_RESOURCES.value[0],
|
||||
ExceptionType.NO_RESOURCES.value[1])
|
||||
|
||||
self.startPushStreamProcess(message, analysisType)
|
||||
elif "stop" == message.get("command"):
|
||||
self.check_msg(message, PULL2PUSH_STOP_SCHEMA)
|
||||
self.stopPushStreamProcess(message)
|
||||
else:
|
||||
raise ServiceException(ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[0],
|
||||
ExceptionType.ILLEGAL_PARAMETER_FORMAT.value[1])
|
||||
|
||||
def startPushStreamProcess(self, msg, analysisType):
|
||||
if self.__pull2PushProcesses.get(msg["request_id"]):
|
||||
logger.warning("重复任务,请稍后再试!requestId:{}", msg["request_id"])
|
||||
return
|
||||
srp = PushStreamProcess(self.__fbQueue, self.__context, msg, analysisType)
|
||||
srp.start()
|
||||
self.__pull2PushProcesses[msg["request_id"]] = srp
|
||||
|
||||
# 结束录屏进程
|
||||
def stopPushStreamProcess(self, msg):
|
||||
srp = self.__pull2PushProcesses.get(msg["request_id"])
|
||||
if srp is None:
|
||||
logger.warning("未查询到该任务,无法停止任务!requestId:{}", msg["request_id"])
|
||||
return
|
||||
srp.sendEvent({"command": "stop", "videoIds": msg.get("video_ids", [])})
|
||||
|
|
@ -46,12 +46,8 @@ class OneModel:
|
|||
new_device = select_device(par.get('device'))
|
||||
half = new_device.type != 'cpu'
|
||||
Detweights = par['Detweights']
|
||||
if par['trtFlag_det']:
|
||||
with open(Detweights, "rb") as f, trt.Runtime(trt.Logger(trt.Logger.ERROR)) as runtime:
|
||||
model = runtime.deserialize_cuda_engine(f.read())
|
||||
else:
|
||||
model = attempt_load(Detweights, map_location=new_device) # load FP32 model
|
||||
if half: model.half()
|
||||
with open(Detweights, "rb") as f, trt.Runtime(trt.Logger(trt.Logger.ERROR)) as runtime:
|
||||
model = runtime.deserialize_cuda_engine(f.read())
|
||||
par['segPar']['seg_nclass'] = par['seg_nclass']
|
||||
Segweights = par['Segweights']
|
||||
if Segweights:
|
||||
|
|
@ -406,8 +402,8 @@ class DENSECROWDCOUNTModel:
|
|||
par = modeType.value[4](str(device), gpu_name)
|
||||
rainbows = par["rainbows"]
|
||||
models=[ modelPar['model'](weights=modelPar['weight'],par=modelPar['par']) for modelPar in par['models'] ]
|
||||
postPar = [pp['par'] for pp in par['models']]
|
||||
self.model_conf = (modeType, device, models, postPar, rainbows)
|
||||
postPar = par['models'][0]['par']
|
||||
self.model_conf = (modeType, device, models[0], postPar, rainbows)
|
||||
except Exception:
|
||||
logger.error("模型加载异常:{}, requestId:{}", format_exc(), requestId)
|
||||
raise ServiceException(ExceptionType.MODEL_LOADING_EXCEPTION.value[0],
|
||||
|
|
@ -756,11 +752,4 @@ MODEL_CONFIG = {
|
|||
None,
|
||||
lambda x: cc_process(x)
|
||||
),
|
||||
# 加载建筑物下行人检测模型
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1]: (
|
||||
lambda x, y, r, t, z, h: DENSECROWDCOUNTModel(x, y, r, ModelType.CITY_UNDERBUILDCOUNT_MODEL, t, z, h),
|
||||
ModelType.CITY_UNDERBUILDCOUNT_MODEL,
|
||||
None,
|
||||
lambda x: cc_process(x)
|
||||
),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import cv2
|
|||
import numpy as np
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
import unicodedata
|
||||
from loguru import logger
|
||||
FONT_PATH = "../AIlib2/conf/platech.ttf"
|
||||
|
||||
zhFont = ImageFont.truetype(FONT_PATH, 20, encoding="utf-8")
|
||||
|
|
@ -68,12 +67,6 @@ def xywh2xyxy2(param):
|
|||
# return [(lt, yt), (rt, yt), (rt, yr), (lt, yr)]
|
||||
return np.asarray(param[0][0:4], np.int32), float(param[1]), int(param[2])
|
||||
|
||||
def xy2xyxy(box):
|
||||
if not isinstance(box[0], (list, tuple, np.ndarray)):
|
||||
x1, y1, x2, y2 = int(box[0]), int(box[1]), int(box[2]), int(box[3])
|
||||
# 顺时针
|
||||
box = [(x1, y1), (x2, y1), (x2, y2), (x1, y2)]
|
||||
return box
|
||||
|
||||
def draw_painting_joint(box, img, label_array, score=0.5, color=None, config=None, isNew=False):
|
||||
# 识别问题描述图片的高、宽
|
||||
|
|
@ -225,11 +218,6 @@ def draw_name_joint(box, img, label_array_dict, score=0.5, color=None, config=No
|
|||
cv2.putText(img, label, p3, 0, config[3], [225, 255, 255], thickness=config[4], lineType=cv2.LINE_AA)
|
||||
return img, box
|
||||
|
||||
def draw_name_ocr(box, img, color, line_thickness=2, outfontsize=40):
|
||||
font = ImageFont.truetype(FONT_PATH, outfontsize, encoding='utf-8')
|
||||
# (color=None, label=None, font=None, fontSize=40, unify=False)
|
||||
label_zh = get_label_array(color, box[0], font, outfontsize)
|
||||
return plot_one_box_auto(box[1], img, color, line_thickness, label_zh)
|
||||
|
||||
def filterBox(det0, det1, pix_dis):
|
||||
# det0为 (m1, 11) 矩阵
|
||||
|
|
@ -263,108 +251,8 @@ def filterBox(det0, det1, pix_dis):
|
|||
x_c, y_c = (x3+x4)//2, (y3+y4)//2
|
||||
dis = (x2_c - x_c)**2 + (y2_c - y_c)**2
|
||||
mask = (joint_det[..., 9] == joint_det[..., 20]) & (dis <= pix_dis**2)
|
||||
|
||||
|
||||
# 类别相同 & 中心点在上一帧的框内 判断为True
|
||||
res = np.sum(mask, axis=1)
|
||||
det0_copy[..., -1] = res
|
||||
return det0_copy
|
||||
|
||||
def plot_one_box_auto(box, img, color=None, line_thickness=2, label_array=None):
|
||||
# print("省略 :%s, box:%s"%('+++' * 10, box))
|
||||
# 识别问题描述图片的高、宽
|
||||
lh, lw = label_array.shape[0:2]
|
||||
# print("省略 :%s, lh:%s, lw:%s"%('+++' * 10, lh, lw))
|
||||
# 图片的长度和宽度
|
||||
imh, imw = img.shape[0:2]
|
||||
box = xy2xyxy(box)
|
||||
# 框框左上的位置
|
||||
x0, y1 = box[0][0], box[0][1]
|
||||
# print("省略 :%s, x0:%s, y1:%s"%('+++' * 10, x0, y1))
|
||||
x1, y0 = x0 + lw, y1 - lh
|
||||
# 如果y0小于0, 说明超过上边框
|
||||
if y0 < 0:
|
||||
y0 = 0
|
||||
# y1等于文字高度
|
||||
y1 = y0 + lh
|
||||
# 如果y1框框的高大于图片高度
|
||||
if y1 > imh:
|
||||
# y1等于图片高度
|
||||
y1 = imh
|
||||
# y0等于y1减去文字高度
|
||||
y0 = y1 - lh
|
||||
# 如果x0小于0
|
||||
if x0 < 0:
|
||||
x0 = 0
|
||||
x1 = x0 + lw
|
||||
if x1 > imw:
|
||||
x1 = imw
|
||||
x0 = x1 - lw
|
||||
# box_tl = max(int(round(imw / 1920 * 3)), 1) or round(0.002 * (imh + imw) / 2) + 1
|
||||
'''
|
||||
1. img(array) 为ndarray类型(可以为cv.imread)直接读取的数据
|
||||
2. box(array):为所画多边形的顶点坐标
|
||||
3. 所画四边形是否闭合,通常为True
|
||||
4. color(tuple):BGR三个通道的值
|
||||
5. thickness(int):画线的粗细
|
||||
6. shift:顶点坐标中小数的位数
|
||||
'''
|
||||
# Plots one bounding box on image img
|
||||
tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 # line/font thickness
|
||||
box1 = np.asarray(box, np.int32)
|
||||
cv2.polylines(img, [box1], True, color, tl)
|
||||
img[y0:y1, x0:x1, :] = label_array
|
||||
|
||||
return img, box
|
||||
|
||||
|
||||
def draw_name_crowd(dets, img, color, outfontsize=20):
|
||||
font = ImageFont.truetype(FONT_PATH, outfontsize, encoding='utf-8')
|
||||
if len(dets) == 2:
|
||||
label = '当前人数:%d'%len(dets[0])
|
||||
detP = dets[0]
|
||||
line = dets[1]
|
||||
for p in detP:
|
||||
img = cv2.circle(img, (int(p[0]), int(p[1])), line, color, -1)
|
||||
label_arr = get_label_array(color, label, font, outfontsize)
|
||||
lh, lw = label_arr.shape[0:2]
|
||||
img[0:lh, 0:lw, :] = label_arr
|
||||
elif len(dets) == 3:
|
||||
detP = dets[1]
|
||||
line = dets[2]
|
||||
for p in detP:
|
||||
img = cv2.circle(img, (int(p[0]), int(p[1])), line, color, -1)
|
||||
|
||||
detM = dets[0]
|
||||
h, w = img.shape[:2]
|
||||
for b in detM:
|
||||
label = '该建筑下行人及数量:%d'%(int(b[4]))
|
||||
label_arr = get_label_array(color, label, font, outfontsize)
|
||||
lh, lw = label_arr.shape[0:2]
|
||||
# 框框左上的位置
|
||||
x0, y1 = int(b[0]), int(b[1])
|
||||
# print("省略 :%s, x0:%s, y1:%s"%('+++' * 10, x0, y1))
|
||||
x1, y0 = x0 + lw, y1 - lh
|
||||
# 如果y0小于0, 说明超过上边框
|
||||
if y0 < 0:
|
||||
y0 = 0
|
||||
# y1等于文字高度
|
||||
y1 = y0 + lh
|
||||
# 如果y1框框的高大于图片高度
|
||||
if y1 > h:
|
||||
# y1等于图片高度
|
||||
y1 = h
|
||||
# y0等于y1减去文字高度
|
||||
y0 = y1 - lh
|
||||
# 如果x0小于0
|
||||
if x0 < 0:
|
||||
x0 = 0
|
||||
x1 = x0 + lw
|
||||
if x1 > w:
|
||||
x1 = w
|
||||
x0 = x1 - lw
|
||||
|
||||
cv2.polylines(img, [np.asarray(xy2xyxy(b), np.int32)], True, (0, 128, 255), 2)
|
||||
img[y0:y1, x0:x1, :] = label_arr
|
||||
|
||||
|
||||
return img, dets
|
||||
return det0_copy
|
||||
Loading…
Reference in New Issue