diff --git a/concurrency/FileUploadThread.py b/concurrency/FileUploadThread.py index f328e53..d662512 100644 --- a/concurrency/FileUploadThread.py +++ b/concurrency/FileUploadThread.py @@ -8,12 +8,13 @@ from loguru import logger import cv2 from entity.FeedBack import message_feedback from enums.ExceptionEnum import ExceptionType +from enums.ModelTypeEnum import ModelType 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.PlotsUtils import draw_painting_joint, draw_name_ocr, draw_name_crowd from util.QueUtil import put_queue, get_no_block_queue, clear_queue import io from util.LocationUtils import locate_byMqtt @@ -42,19 +43,11 @@ class FileUpload(Thread): print("执行替代程序(defaultEnabled=False)") # 这里放非默认逻辑的代码 self._algSwitch = False - + print("---line46 :FileUploadThread.py---",self._algSwitch) - - - - - - - - - - -#如果任务是在线、离线处理,则用此类 + + +#如果任务是在线、离线处理,则用此类 class ImageFileUpload(FileUpload): __slots__ = () @@ -74,7 +67,7 @@ class ImageFileUpload(FileUpload): ''' print('*'*100,' mqtt_list:',len(self._mqtt_list)) - + model_info = [] # 更加模型编码解析数据 for code, det_list in det_xywh.items(): @@ -83,15 +76,27 @@ class ImageFileUpload(FileUpload): 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]) - igH,igW = aFrame.shape[0:2] - if len(self._mqtt_list)>=1: - #camParas = self._mqtt_list[0]['data'] + # 自研车牌模型判断 + if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code): + 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]) + + igH, igW = aFrame.shape[0:2] + if len(self._mqtt_list) >= 1: + # camParas = self._mqtt_list[0]['data'] camParas = self._mqtt_list[0] - gps = locate_byMqtt(target[1],igW,igH,camParas,outFormat='wgs84') + gps = locate_byMqtt(target[1], igW, igH, camParas, outFormat='wgs84') else: - gps=[None,None] - model_info.append({"modelCode": str(code), "detectTargetCode": str(cls), "aFrame": aFrame,'gps':gps}) + gps = [None, None] + model_info.append( + {"modelCode": str(code), "detectTargetCode": str(cls), "aFrame": aFrame, 'gps': gps}) if len(model_info) > 0: image_result = { "or_frame": frame, @@ -130,7 +135,7 @@ class ImageFileUpload(FileUpload): # 获取队列中的消息 image_msg = get_no_block_queue(image_queue) if image_msg is not None: - + if image_msg[0] == 2: logger.info("图片上传线程收到命令:{}, requestId: {}",image_msg[1] ,request_id) if 'stop' == image_msg[1]: @@ -138,7 +143,7 @@ class ImageFileUpload(FileUpload): 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 image_msg[0] == 1: image_result = self.handle_image(image_msg[1], frame_step) if image_result is not None: @@ -148,7 +153,7 @@ class ImageFileUpload(FileUpload): image_result["last_frame"], analyse_type, "OR", "0", "0", request_id) - if self._storage_source==1: + 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()) @@ -164,13 +169,13 @@ 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) 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, @@ -194,7 +199,7 @@ class ImageFileUpload(FileUpload): longitude=model_info['gps'][0], latitude=model_info['gps'][1], ) ) - + 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) @@ -220,7 +225,7 @@ def build_image_name(*args): 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): @@ -249,12 +254,20 @@ class ImageTypeImageFileUpload(Thread): 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 ModelType.CITY_CARPLATE_MODEL.value[1] == str(code): + 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) + + model_info.append({ + "modelCode": str(code), + "detectTargetCode": str(cls), + "frame": aiFrame + }) + if len(model_info) > 0: image_result = { "or_frame": copy_frame, @@ -278,7 +291,7 @@ class ImageTypeImageFileUpload(Thread): minioSdk = MinioSdk(base_dir, env, request_id ) else: aliyunOssSdk = AliyunOssSdk(base_dir, env, request_id) - + start_time = time() while True: try: @@ -299,12 +312,12 @@ class ImageTypeImageFileUpload(Thread): 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: + + 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, @@ -318,7 +331,7 @@ class ImageTypeImageFileUpload(Thread): 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")) @@ -326,8 +339,8 @@ class ImageTypeImageFileUpload(Thread): image_result.get("last_frame"), analyse_type, "OR", "0", "O", request_id) - - if self._storage_source==1: + + 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, @@ -344,9 +357,9 @@ class ImageTypeImageFileUpload(Thread): model_info.get("modelCode"), model_info.get("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) - else: + else: ai_future = t.submit(aliyunOssSdk.put_object, ai_image_name, ai_image.tobytes()) task.append(ai_future) @@ -362,9 +375,8 @@ class ImageTypeImageFileUpload(Thread): remote_url_list = [] for thread_result in task: remote_url_list.append(thread_result.result()) - - - #以下代码是为了获取图像上传后,返回的全路径地址 + + # 以下代码是为了获取图像上传后,返回的全路径地址 if det_xywh is None: msg_list.append(message_feedback(request_id, AnalysisStatus.RUNNING.value, @@ -396,11 +408,7 @@ class ImageTypeImageFileUpload(Thread): model_info_list[ii].get('modelCode'), model_info_list[ii].get('detectTargetCode'), analyse_results=result)) - - - - for msg in msg_list: put_queue(fb_queue, msg, timeout=2, is_ex=False) else: diff --git a/concurrency/IntelligentRecognitionProcess.py b/concurrency/IntelligentRecognitionProcess.py index 7c40632..2160aa8 100644 --- a/concurrency/IntelligentRecognitionProcess.py +++ b/concurrency/IntelligentRecognitionProcess.py @@ -91,8 +91,7 @@ class IntelligentRecognitionProcess(Process): hb_thread.start() return hb_thread - - + class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): @@ -229,7 +228,7 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): # 事件队列、拉流队列、心跳队列、反馈队列 event_queue, pull_queue, hb_queue, fb_queue = self.event_queue, self._pull_queue, self._hb_queue, self._fb_queue - + # 推流队列、推流异常队列、图片队列 push_queue, push_ex_queue, image_queue = self._push_queue, self._push_ex_queue, self._image_queue try: @@ -237,16 +236,15 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): init_log(base_dir, env) # 打印启动日志 logger.info("开始启动实时分析进程!requestId: {}", request_id) - + # 启动拉流进程(包含拉流线程, 图片上传线程,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, # 启动心跳线程 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, + + # 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 @@ -273,7 +271,7 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): raise ServiceException(push_status[1], push_status[2]) # 获取停止指令 event_result = get_no_block_queue(event_queue) - + if event_result: cmdStr = event_result.get("command") #接收到算法开启、或者关闭的命令 @@ -281,7 +279,7 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): logger.info("发送向推流进程发送算法命令, requestId: {}, {}", request_id,cmdStr ) put_queue(push_queue, (2, cmdStr), timeout=1, is_ex=True) pull_process.sendCommand({"command": cmdStr}) - + # 接收到停止指令 if "stop" == cmdStr: logger.info("实时任务开始停止, requestId: {}", request_id) @@ -301,20 +299,31 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): task_status[0] = 1 for i, model in enumerate(model_array): model_conf, code = model - model_param = model_conf[1] - # (modeType, model_param, allowedList, names, rainbows) - MODEL_CONFIG[code][2](frame_list[0].shape[1], frame_list[0].shape[0], - model_conf) - if draw_config.get("font_config") is None: - draw_config["font_config"] = model_param['font_config'] - if draw_config.get(code) is None: - draw_config[code] = {} - draw_config[code]["allowedList"] = model_conf[2] - draw_config[code]["rainbows"] = model_conf[4] - draw_config[code]["label_arrays"] = model_param['label_arraylist'] - if "label_dict" in model_param: - draw_config[code]["label_dict"] = model_param['label_dict'] - #print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno) + if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code) or \ + 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] + draw_config[code]["allowedList"] = 0 + draw_config[code]["label_arrays"] = [None] + draw_config[code]["rainbows"] = model_conf[4] + else: + model_param = model_conf[1] + # (modeType, model_param, allowedList, names, rainbows) + MODEL_CONFIG[code][2](frame_list[0].shape[1], frame_list[0].shape[0], + model_conf) + if draw_config.get("font_config") is None: + draw_config["font_config"] = model_param['font_config'] + if draw_config.get(code) is None: + draw_config[code] = {} + draw_config[code]["allowedList"] = model_conf[2] + draw_config[code]["rainbows"] = model_conf[4] + draw_config[code]["label_arrays"] = model_param['label_arraylist'] + if "label_dict" in model_param: + draw_config[code]["label_dict"] = model_param['label_dict'] + + + # print_cpu_status(requestId=request_id,lineNum=inspect.currentframe().f_lineno) # 多线程并发处理, 经过测试两个线程最优 det_array = [] for i, frame in enumerate(frame_list): @@ -437,23 +446,23 @@ class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): class OfflineIntelligentRecognitionProcess(IntelligentRecognitionProcess): __slots__ = () - + 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 ) upload_video_thread_ai = Common(minioSdk.put_object, aiFilePath, "ai_online_%s.mp4" % request_id) else: aliyunVodSdk = ThAliyunVodSdk(base_dir, env, request_id) upload_video_thread_ai = Common(aliyunVodSdk.get_play_url, aiFilePath, "ai_online_%s" % request_id) - + upload_video_thread_ai.setDaemon(True) upload_video_thread_ai.start() ai_url = upload_video_thread_ai.get_result() return ai_url - + ''' @staticmethod def upload_video(base_dir, env, request_id, aiFilePath): @@ -602,7 +611,7 @@ class OfflineIntelligentRecognitionProcess(IntelligentRecognitionProcess): logger.info("发送向推流进程发送算法命令, requestId: {}, {}", request_id,cmdStr ) put_queue(push_queue, (2, cmdStr), timeout=1, is_ex=True) pull_process.sendCommand({"command": cmdStr}) - + pull_result = get_no_block_queue(pull_queue) if pull_result is None: sleep(1) @@ -616,19 +625,31 @@ class OfflineIntelligentRecognitionProcess(IntelligentRecognitionProcess): task_status[0] = 1 for i, model in enumerate(model_array): model_conf, code = model - model_param = model_conf[1] - # (modeType, model_param, allowedList, names, rainbows) - MODEL_CONFIG[code][2](frame_list[0].shape[1], frame_list[0].shape[0], - model_conf) - if draw_config.get("font_config") is None: - draw_config["font_config"] = model_param['font_config'] - if draw_config.get(code) is None: - draw_config[code] = {} - draw_config[code]["allowedList"] = model_conf[2] - draw_config[code]["rainbows"] = model_conf[4] - draw_config[code]["label_arrays"] = model_param['label_arraylist'] - if "label_dict" in model_param: - draw_config[code]["label_dict"] = model_param['label_dict'] + if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code) or \ + 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] + draw_config[code]["allowedList"] = 0 + draw_config[code]["label_arrays"] = [None] + draw_config[code]["rainbows"] = model_conf[4] + + else: + model_param = model_conf[1] + # (modeType, model_param, allowedList, names, rainbows) + MODEL_CONFIG[code][2](frame_list[0].shape[1], frame_list[0].shape[0], + model_conf) + if draw_config.get("font_config") is None: + draw_config["font_config"] = model_param['font_config'] + if draw_config.get(code) is None: + draw_config[code] = {} + draw_config[code]["allowedList"] = model_conf[2] + draw_config[code]["rainbows"] = model_conf[4] + draw_config[code]["label_arrays"] = model_param['label_arraylist'] + if "label_dict" in model_param: + draw_config[code]["label_dict"] = model_param['label_dict'] + + det_array = [] for i, frame in enumerate(frame_list): det_result = t.submit(self.obj_det, self, model_array, frame, task_status, @@ -922,6 +943,63 @@ 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 + model_conf, code = mod + modeType, device, modelList, detpar, rainbows = model_conf + image = url2Array(imageUrl) + dets = {code: {}} + # param = [image, new_device, model, par, img_type, request_id] + # model_conf, frame, device, requestId + dataBack = MODEL_CONFIG[code][3]([[modeType, device, modelList, detpar], image, request_id])[0][2] + dets[code][0] = dataBack + if not dataBack: + logger.info("车牌识别为空") + + # for ai_result in dataBack: + # label, box = ai_result + # color = rainbows + + if len(dataBack) > 0: + put_queue(image_queue, (1, (dets, imageUrl, image, rainbows, "")), timeout=2, is_ex=False) + + except ServiceException as s: + raise s + except Exception as e: + logger.error("模型分析异常: {}, requestId: {}", format_exc(), request_id) + raise e + + #密集人群计数 + def denscrowdcount_rec(self, imageUrl, mod, image_queue, request_id): + try: + # model_conf: modeType, allowedList, detpar, ocrmodel, rainbows + model_conf, code = mod + modeType, device, model, postPar, rainbows = model_conf + image = url2Array(imageUrl) + dets = {code: {}} + # 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("当前页面无人") + + # for ai_result in dataBack: + # label, box = ai_result + # color = rainbows + + if len(dataBack) > 0: + put_queue(image_queue, (1, (dets, imageUrl, image, rainbows, '')), timeout=2, is_ex=False) + + except ServiceException as s: + raise s + except Exception as e: + logger.error("模型分析异常: {}, requestId: {}", format_exc(), request_id) + raise e + ''' # 防疫模型 ''' @@ -936,6 +1014,26 @@ class PhotosIntelligentRecognitionProcess(Process): for r in obj_list: r.result(60) + # 自研车牌识别模型: + def carpalteRec(self, imageUrls, model, image_queue, request_id): + with ThreadPoolExecutor(max_workers=2) as t: + obj_list = [] + for imageUrl in imageUrls: + obj = t.submit(self.carplate_rec, imageUrl, model, image_queue, request_id) + obj_list.append(obj) + for r in obj_list: + r.result(60) + + # 密集人群计数:CITY_DENSECROWDCOUNT_MODEL + def denscrowdcountRec(self, imageUrls, model, image_queue, request_id): + with ThreadPoolExecutor(max_workers=2) as t: + obj_list = [] + for imageUrl in imageUrls: + obj = t.submit(self.denscrowdcount_rec, imageUrl, model, image_queue, request_id) + obj_list.append(obj) + for r in obj_list: + r.result(60) + def image_recognition(self, imageUrl, mod, image_queue, logo, request_id): try: model_conf, code = mod @@ -1125,7 +1223,7 @@ class PhotosIntelligentRecognitionProcess(Process): except requests.exceptions.RequestException as e: # 捕获请求过程中可能出现的异常(如网络问题、超时等) return False,str(e) - + def run(self): fb_queue, msg, analyse_type, context = self._fb_queue, self._msg, self._analyse_type, self._context request_id, logo, image_queue = msg["request_id"], context['logo'], self._image_queue @@ -1136,7 +1234,7 @@ class PhotosIntelligentRecognitionProcess(Process): valFlag=True for url in imageUrls: valFlag,ret = self.check_ImageUrl_Vaild(url,timeout=1) - + if not valFlag: logger.error("图片分析异常: {}, requestId:{},url:{}",ret, request_id,url) #print("AnalysisStatus.FAILED.value:{},ExceptionType.URL_ADDRESS_ACCESS_FAILED.value[0]:{},ExceptionType.URL_ADDRESS_ACCESS_FAILED.value[1]:{}".format(AnalysisStatus.FAILED.value,ExceptionType.URL_ADDRESS_ACCESS_FAILED.value[0],ExceptionType.URL_ADDRESS_ACCESS_FAILED.value[1] ) ) @@ -1168,6 +1266,14 @@ class PhotosIntelligentRecognitionProcess(Process): elif model[1] == ModelType.PLATE_MODEL.value[1]: result = t.submit(self.epidemicPrevention, imageUrls, model, base_dir, env, request_id) task_list.append(result) + # 自研车牌模型 + elif model[1] == ModelType.CITY_CARPLATE_MODEL.value[1]: + result = t.submit(self.carpalteRec, imageUrls, model, image_queue, request_id) + task_list.append(result) + # 人群计数模型 + 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: result = t.submit(self.publicIdentification, imageUrls, model, image_queue, logo, request_id) task_list.append(result) @@ -1214,7 +1320,7 @@ class ScreenRecordingProcess(Process): put_queue(self._fb_queue, recording_feedback(self._msg["request_id"], RecordingStatus.RECORDING_WAITING.value[0]), timeout=1, is_ex=True) - self._storage_source = self._context['service']['storage_source'] + self._storage_source = self._context['service']['storage_source'] def sendEvent(self, result): put_queue(self._event_queue, result, timeout=2, is_ex=True) @@ -1380,9 +1486,6 @@ 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 ) @@ -1390,7 +1493,7 @@ class ScreenRecordingProcess(Process): else: aliyunVodSdk = ThAliyunVodSdk(base_dir, env, request_id) upload_video_thread_ai = Common(aliyunVodSdk.get_play_url, aiFilePath, "ai_online_%s" % request_id) - + upload_video_thread_ai.setDaemon(True) upload_video_thread_ai.start() or_url = upload_video_thread_ai.get_result() diff --git a/concurrency/PushVideoStreamProcess.py b/concurrency/PushVideoStreamProcess.py index d10841c..39acd89 100644 --- a/concurrency/PushVideoStreamProcess.py +++ b/concurrency/PushVideoStreamProcess.py @@ -23,7 +23,7 @@ from util.Cv2Utils import video_conjuncing, write_or_video, write_ai_video, push from util.ImageUtils import url2Array, add_water_pic from util.LogUtils import init_log -from util.PlotsUtils import draw_painting_joint, filterBox, xywh2xyxy2, draw_name_joint +from util.PlotsUtils import draw_painting_joint, filterBox, xywh2xyxy2, xy2xyxy, draw_name_joint, plot_one_box_auto, draw_name_ocr,draw_name_crowd from util.QueUtil import get_no_block_queue, put_queue, clear_queue @@ -37,7 +37,7 @@ class PushStreamProcess(Process): self._msg, self._push_queue, self._image_queue, self._push_ex_queue, self._hb_queue, self._context = args self._algStatus = False # 默认关闭 self._algSwitch = self._context['service']['algSwitch'] - + #0521: default_enabled = str(self._msg.get("defaultEnabled", "True")).lower() == "true" @@ -49,16 +49,9 @@ class PushStreamProcess(Process): print("执行替代程序(defaultEnabled=False)") # 这里放非默认逻辑的代码 self._algSwitch = False - - + print("---line53 :PushVideoStreamProcess.py---",self._algSwitch) - - - - - - - + def build_logo_url(self): logo = None if self._context["video"]["video_add_water"]: @@ -155,17 +148,39 @@ class OnPushStreamProcess(PushStreamProcess): font_config, allowedList = draw_config["font_config"], draw_config[code]["allowedList"] rainbows, label_arrays = draw_config[code]["rainbows"], draw_config[code]["label_arrays"] for qs in det_result: - 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]) + # 自研车牌模型处理 + if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code): + cls = 0 + ocrlabel, xybox = qs + box = xy2xyxy(xybox) + score = None + color = rainbows[cls] + label_array = None + 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 + box = [(0, 0), (0, 0), (0, 0), (0, 0)] + score = None + color = rainbows[cls] + label_array = None + rr = t.submit(draw_name_crowd, points, copy_frame, color, crowdlabel) 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: det_xywh[code] = {} @@ -184,17 +199,17 @@ class OnPushStreamProcess(PushStreamProcess): box[2][0], box[2][1], box[3][0], box[3][1], score, cls, code],dtype=np.float32) qs_np = np.row_stack((qs_np, result_li)) - + if logo: frame = add_water_pic(frame, logo, request_id) copy_frame = add_water_pic(copy_frame, logo, request_id) if len(thread_p) > 0: for r in thread_p: r.result() - #print('----line173:',self._algSwitch,self._algStatus) + #print('----line173:',self._algSwitch,self._algStatus) if self._algSwitch and (not self._algStatus): frame_merge = video_conjuncing(frame, frame.copy()) - else: + else: frame_merge = video_conjuncing(frame, copy_frame) # 写原视频到本地 write_or_video_result = t.submit(write_or_video, frame, orFilePath, or_video_file, @@ -207,7 +222,7 @@ class OnPushStreamProcess(PushStreamProcess): # 如果有问题, 走下面的逻辑 if qs_np is not None: if len(qs_np.shape) == 1: - qs_np = qs_np[np.newaxis,...] + qs_np = qs_np[np.newaxis,...] qs_np_id = qs_np.copy() b = np.ones(qs_np_id.shape[0]) qs_np_id = np.column_stack((qs_np_id,b)) @@ -233,7 +248,7 @@ class OnPushStreamProcess(PushStreamProcess): if q[11] >= 1: cls = int(q[9]) if not (cls in new_lab): - continue # 为了防止其他类别被带出 + continue # 为了防止其他类别被带出 code = str(int(q[10])).zfill(3) if det_xywh2.get(code) is None: det_xywh2[code] = {} @@ -246,6 +261,11 @@ class OnPushStreamProcess(PushStreamProcess): is_new = False if q[11] == 1: is_new = True + 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]] else: @@ -268,7 +288,7 @@ class OnPushStreamProcess(PushStreamProcess): ex_status = False logger.info("停止推流进程, requestId: {}", request_id) break - + del push_r else: sleep(1) @@ -363,24 +383,45 @@ class OffPushStreamProcess(PushStreamProcess): qs_reurn = [] for det in push_objs[i]: code, det_result = det - + # 每个单独模型处理 # 模型编号、100帧的所有问题, 检测目标、颜色、文字图片 if len(det_result) > 0: font_config, allowedList = draw_config["font_config"], draw_config[code]["allowedList"] rainbows, label_arrays = draw_config[code]["rainbows"], draw_config[code]["label_arrays"] for qs in det_result: - box, score, cls = xywh2xyxy2(qs) - - 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]) + # 自研车牌模型处理 + if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code): + cls = 0 + ocrlabel, xybox = qs + box = xy2xyxy(xybox) + score = None + color = rainbows[cls] + label_array = None + label_arrays = [None] + 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 + box = [(0,0),(0,0),(0,0),(0,0)] + score = None + color = rainbows[cls] + label_array = None + rr = t.submit(draw_name_crowd, points, copy_frame, color, crowdlabel) + else: - rr = t.submit(draw_painting_joint, box, copy_frame, label_array, score, color, font_config) + box, score, cls = xywh2xyxy2(qs) + 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: det_xywh[code] = {} cd = det_xywh[code].get(cls) @@ -388,17 +429,17 @@ class OffPushStreamProcess(PushStreamProcess): if cd is None: det_xywh[code][cls] = [[cls, box, score, label_array, color]] else: - det_xywh[code][cls].append([cls, box, score, label_array, color]) + det_xywh[code][cls].append([cls, box, score, label_array, color]) if qs_np is None: - qs_np = np.array([box[0][0], box[0][1], box[1][0], box[1][1], - box[2][0], box[2][1], box[3][0], box[3][1], + qs_np = np.array([box[0][0], box[0][1], box[1][0], box[1][1], + box[2][0], box[2][1], box[3][0], box[3][1], score, cls, code],dtype=np.float32) else: - result_li = np.array([box[0][0], box[0][1], box[1][0], box[1][1], + result_li = np.array([box[0][0], box[0][1], box[1][0], box[1][1], box[2][0], box[2][1], box[3][0], box[3][1], score, cls, code],dtype=np.float32) qs_np = np.row_stack((qs_np, result_li)) - + if logo: frame = add_water_pic(frame, logo, request_id) copy_frame = add_water_pic(copy_frame, logo, request_id) @@ -407,7 +448,7 @@ class OffPushStreamProcess(PushStreamProcess): r.result() if self._algSwitch and (not self._algStatus): frame_merge = video_conjuncing(frame, frame.copy()) - else: + else: frame_merge = video_conjuncing(frame, copy_frame) # 写识别视频到本地 write_ai_video_result = t.submit(write_ai_video, frame_merge, aiFilePath, @@ -416,10 +457,9 @@ class OffPushStreamProcess(PushStreamProcess): push_stream_result = t.submit(push_video_stream, frame_merge, push_p, push_url, p_push_status, request_id) - if qs_np is not None: if len(qs_np.shape) == 1: - qs_np = qs_np[np.newaxis,...] + qs_np = qs_np[np.newaxis,...] qs_np_id = qs_np.copy() b = np.ones(qs_np_id.shape[0]) qs_np_id = np.column_stack((qs_np_id,b)) @@ -446,7 +486,7 @@ class OffPushStreamProcess(PushStreamProcess): if q[11] >= 1: cls = int(q[9]) if not (cls in new_lab): - continue # 为了防止其他类别被带出 + continue # 为了防止其他类别被带出 code = str(int(q[10])).zfill(3) if det_xywh2.get(code) is None: det_xywh2[code] = {} @@ -459,6 +499,13 @@ class OffPushStreamProcess(PushStreamProcess): is_new = False if q[11] == 1: is_new = True + + 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]] else: diff --git a/enums/ModelTypeEnum.py b/enums/ModelTypeEnum.py index 1f89471..fada509 100644 --- a/enums/ModelTypeEnum.py +++ b/enums/ModelTypeEnum.py @@ -16,6 +16,7 @@ from utilsK.illParkingUtils import illParking_postprocess from utilsK.pannelpostUtils import pannel_post_process from stdc import stdcModel from yolov5 import yolov5Model +from p2pNet import p2NnetModel from DMPRUtils.jointUtil import dmpr_yolo_stdc from AI import default_mix from ocr import ocrModel @@ -66,7 +67,7 @@ class ModelType(Enum): 'Detweights': "../weights/trt/AIlib2/river/yolov5_%s_fp16.engine" % gpuName, 'Segweights': '../weights/trt/AIlib2/river/stdc_360X640_%s_fp16.engine' % gpuName }) - + # FOREST_FARM_MODEL = ("2", "002", "森林模型", 'forest2', lambda device, gpuName: { # 'device': device, # 'gpu_name': gpuName, @@ -87,7 +88,7 @@ class ModelType(Enum): # }, # 'Segweights': None # }) - + FOREST_FARM_MODEL = ("2", "002", "森林模型", 'forest2', lambda device, gpuName: { 'labelnames': ["林斑", "病死树", "行人", "火焰", "烟雾","云朵"], @@ -100,10 +101,10 @@ class ModelType(Enum): '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, @@ -115,7 +116,7 @@ class ModelType(Enum): 'segRegionCnt':2,###分割模型结果需要保留的等值线数目 "pixScale": 1.2, - + }) @@ -361,14 +362,14 @@ class ModelType(Enum): }) CITY_MANGEMENT_MODEL = ("16", "016", "城管模型", 'cityMangement2', lambda device, gpuName: { - 'labelnames': [ "车辆", "垃圾", "商贩", "违停","占道经营","裸土","未覆盖裸土" ], + 'labelnames': [ "车辆", "垃圾", "商贩", "违停","占道经营","裸土","未覆盖裸土","违建" ], 'postProcess':{ 'function':dmpr_yolo_stdc, 'pars':{ - 'carCls':0 ,'illCls':6,'scaleRatio':0.5,'border':80, - #车辆","垃圾","商贩","裸土","占道经营","违停"---> - #"车辆","垃圾","商贩","违停","占道经营","裸土" - 'classReindex':{ 0:0,1:1,2:2,3:6,4:4,5:5,6:3} + 'carCls':0 ,'illCls':7,'scaleRatio':0.5,'border':80, + #"车辆","垃圾","商贩","裸土","占道经营","未覆盖裸土","违建" + # key:实际训练index value:展示index + 'classReindex':{ 0:0,1:1,2:2,7:3,4:4,3:5,5:6,6:7} } }, 'models':[ @@ -376,7 +377,7 @@ class ModelType(Enum): '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],'segRegionCnt':1, 'trtFlag_det':True,'trtFlag_seg':True, "score_byClass":{"0":0.8,"1":0.4,"2":0.5,"3":0.5 } } + '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 } } }, { 'weight':'../weights/pth/AIlib2/cityMangement3/dmpr.pth', @@ -384,25 +385,25 @@ class ModelType(Enum): 'depth_factor':32,'NUM_FEATURE_MAP_CHANNEL':6,'dmpr_thresh':0.1, 'dmprimg_size':640, 'name':'dmpr' }, - 'model':DMPRModel, + 'model':DMPRModel, 'name':'dmpr' }, - { + { 'weight':'../weights/trt/AIlib2/cityMangement3/stdc_360X640_%s_fp16.engine'%(gpuName), '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':3},###分割模型预处理参数 'model':stdcModel, - 'name':'stdc' - } + 'name':'stdc' + } ], 'postFile': { "name": "post_process", "conf_thres": 0.25, "iou_thres": 0.45, - "classes": 6, + "classes": 8, "rainbows": COLOR }, - 'detModelpara':[{"id":str(x),"config":{"k1":"v1","k2":"v2"}} for x in [0,1,2,3,5,6,7,8,9] ],###控制哪些检测类别显示、输出 + '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, }) @@ -569,7 +570,7 @@ class ModelType(Enum): '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' : '../weights/pth/AIlib2/ocr2/crnn_ch.pth', 'name':'ocr', 'model':ocrModel, @@ -584,7 +585,7 @@ class ModelType(Enum): '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,4,5,6]], 'segPar': None, @@ -597,7 +598,7 @@ class ModelType(Enum): }, 'Segweights': None, }) - + RIVERT_MODEL = ("25", "025", "河道检测模型(T)", 'riverT', lambda device, gpuName: { 'device': device, 'labelnames': ["漂浮物", "岸坡垃圾", "排口", "违建", "菜地", "水生植物", "河湖人员", "钓鱼人员", "船只", @@ -664,7 +665,8 @@ class ModelType(Enum): }) TRAFFICFORDSJ_FARM_MODEL = ("27", "027", "交通模型-大数据局", 'highWay2T', lambda device, gpuName: { 'device': str(device), - 'labelnames': ["行人", "车辆", "纵向裂缝", "横向裂缝", "修补", "网状裂纹", "坑槽", "块状裂纹", "积水", "影子", "事故", "桥梁外观","设施破损缺失","龙门架","防抛网","标识牌损坏","护栏损坏","钢筋裸露" ], + 'labelnames': ["行人", "车辆", "纵向裂缝", "横向裂缝", "修补", "网状裂纹", "坑槽", "块状裂纹", "积水", "影子", + "事故", "桥梁外观","设施破损缺失","龙门架","防抛网","标识牌损坏","护栏损坏","钢筋裸露" ], 'trtFlag_seg': True, 'trtFlag_det': True, 'seg_nclass': 3, @@ -718,13 +720,13 @@ class ModelType(Enum): '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: { @@ -738,15 +740,15 @@ class ModelType(Enum): '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':{}}, @@ -758,13 +760,13 @@ class ModelType(Enum): '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 }, - + }) TRAFFIC_SPILL_MODEL = ("50", "501", "高速公路抛洒物模型", 'highWaySpill', lambda device, gpuName: { @@ -958,6 +960,52 @@ class ModelType(Enum): }) + CITY_DENSECROWDCOUNT_MODEL = ("30", "304", "密集人群计数", 'DenseCrowdCount', lambda device, gpuName: { + 'labelnames': ["人群计数"], + 'device': str(device), + 'rainbows': COLOR, + 'models': [ + { + '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.25, + 'gpu_id': 0, + 'eos_coef': '0.5', + 'set_cost_class': 1, + 'set_cost_point': 0.05, + 'backbone': 'vgg16_bn' + }, + }], + }) + + CITY_DENSECROWDESTIMATION_MODEL = ("30", "305", "密集人群密度估计", 'DenseCrowdEstimation', lambda device, gpuName: { + 'labelnames': ["密度"], + 'models': + [ + { + 'weight': "../weights/pth/AIlib2/DenseCrowd/SHTechA.pth", ###检测模型路径 + 'name': 'yolov5', + 'model': yolov5Model, + 'par': {'half': True, 'device': 'cuda:0', 'conf_thres': 0.50, 'iou_thres': 0.45, + 'allowedList': list(range(20)), 'segRegionCnt': 1, 'trtFlag_det': True, + 'trtFlag_seg': False, "score_byClass": {"0": 0.50, "1": 0.3, "2": 0.3, "3": 0.3}}, + } + + ], + 'postFile': { + "rainbows": COLOR + }, + + }) + @staticmethod def checkCode(code): for model in ModelType: diff --git a/util/ModelUtils.py b/util/ModelUtils.py index 9154274..a5e6c9f 100644 --- a/util/ModelUtils.py +++ b/util/ModelUtils.py @@ -17,7 +17,7 @@ from util.PlotsUtils import get_label_arrays, get_label_array_dict from util.TorchUtils import select_device sys.path.extend(['..', '../AIlib2']) -from AI import AI_process, AI_process_forest, get_postProcess_para, ocr_process, AI_process_N, AI_process_C +from AI import AI_process, AI_process_forest, get_postProcess_para, ocr_process, AI_process_N, AI_process_C,AI_process_Ocr,AI_process_Crowd from stdc import stdcModel from segutils.segmodel import SegModel from models.experimental import attempt_load @@ -241,7 +241,7 @@ def channel2_process(args): logger.error("算法模型分析异常:{}, requestId:{}", format_exc(), request_id) raise ServiceException(ExceptionType.MODEL_ANALYSE_EXCEPTION.value[0], ExceptionType.MODEL_ANALYSE_EXCEPTION.value[1]) - + def get_label_arraylist(*args): width, height, names, rainbows = args # line = int(round(0.002 * (height + width) / 2) + 1) @@ -354,6 +354,73 @@ def im_process(args): raise ServiceException(ExceptionType.MODEL_ANALYSE_EXCEPTION.value[0], ExceptionType.MODEL_ANALYSE_EXCEPTION.value[1]) +def immulti_process(args): + model_conf, frame, requestId = args + device, modelList, detpar = model_conf[1], model_conf[2], model_conf[3] + try: + # new_device = torch.device(device) + # img, padInfos = pre_process(frame, new_device) + # pred = model(img) + # boxes = post_process(pred, padInfos, device, conf_thres=pardet['conf_thres'], + # iou_thres=pardet['iou_thres'], nc=pardet['nc']) # 后处理 + return AI_process_Ocr([frame], modelList, device, detpar) + except ServiceException as s: + raise s + except Exception: + logger.error("算法模型分析异常:{}, requestId:{}", format_exc(), requestId) + raise ServiceException(ExceptionType.MODEL_ANALYSE_EXCEPTION.value[0], + ExceptionType.MODEL_ANALYSE_EXCEPTION.value[1]) + +class CARPLATEModel: + __slots__ = "model_conf" + def __init__(self, device, allowedList=None, requestId=None, modeType=None, gpu_name=None, base_dir=None, + env=None): + try: + logger.info("########################加载{}########################, requestId:{}", modeType.value[2], + requestId) + par = modeType.value[4](str(device), gpu_name) + modelList=[ modelPar['model'](weights=modelPar['weight'],par=modelPar['par']) for modelPar in par['models'] ] + detpar = par['models'][0]['par'] + # new_device = torch.device(par['device']) + # modelList=[ modelPar['model'](weights=modelPar['weight'],par=modelPar['par']) for modelPar in par['models'] ] + logger.info("########################加载 plate_yolov5s_v3.jit 成功 ########################, requestId:{}", + requestId) + self.model_conf = (modeType, device, modelList, detpar, par['rainbows']) + except Exception: + logger.error("模型加载异常:{}, requestId:{}", format_exc(), requestId) + raise ServiceException(ExceptionType.MODEL_LOADING_EXCEPTION.value[0], + ExceptionType.MODEL_LOADING_EXCEPTION.value[1]) + + +class DENSECROWDCOUNTModel: + __slots__ = "model_conf" + + def __init__(self, device, allowedList=None, requestId=None, modeType=None, gpu_name=None, base_dir=None, env=None): + try: + logger.info("########################加载{}########################, requestId:{}", modeType.value[2], + requestId) + 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 = 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], + ExceptionType.MODEL_LOADING_EXCEPTION.value[1]) + +def cc_process(args): + model_conf, frame, requestId = args + device, model, postPar = model_conf[1], model_conf[2], model_conf[3] + try: + return AI_process_Crowd([frame], model, device, postPar) + except ServiceException as s: + raise s + except Exception: + logger.error("算法模型分析异常:{}, requestId:{}", format_exc(), requestId) + raise ServiceException(ExceptionType.MODEL_ANALYSE_EXCEPTION.value[0], + ExceptionType.MODEL_ANALYSE_EXCEPTION.value[1]) + # 百度AI图片识别模型 class BaiduAiImageModel: @@ -470,7 +537,7 @@ MODEL_CONFIG = { lambda x, y, z: one_label(x, y, z), lambda x: detSeg_demo2(x) ), - + # 加载交通模型 ModelType.TRAFFIC_FARM_MODEL.value[1]: ( lambda x, y, r, t, z, h: OneModel(x, y, r, ModelType.TRAFFIC_FARM_MODEL, t, z, h), @@ -613,22 +680,22 @@ MODEL_CONFIG = { lambda x, y, z: one_label(x, y, z), lambda x: model_process(x) ), - # 加载智慧工地模型 + # 加载智慧工地模型 ModelType.SMARTSITE_MODEL.value[1]: ( lambda x, y, r, t, z, h: cityManagementModel(x, y, r, ModelType.SMARTSITE_MODEL, t, z, h), ModelType.SMARTSITE_MODEL, lambda x, y, z: one_label(x, y, z), lambda x: detSeg_demo2(x) ), - - # 加载垃圾模型 + + # 加载垃圾模型 ModelType.RUBBISH_MODEL.value[1]: ( lambda x, y, r, t, z, h: cityManagementModel(x, y, r, ModelType.RUBBISH_MODEL, t, z, h), ModelType.RUBBISH_MODEL, lambda x, y, z: one_label(x, y, z), lambda x: detSeg_demo2(x) ), - + # 加载烟花模型 ModelType.FIREWORK_MODEL.value[1]: ( lambda x, y, r, t, z, h: cityManagementModel(x, y, r, ModelType.FIREWORK_MODEL, t, z, h), @@ -657,6 +724,13 @@ MODEL_CONFIG = { lambda x, y, z: one_label(x, y, z), lambda x: detSeg_demo2(x) ), + # 加载自研车牌检测模型 + ModelType.CITY_CARPLATE_MODEL.value[1]: ( + lambda x, y, r, t, z, h: CARPLATEModel(x, y, r, ModelType.CITY_CARPLATE_MODEL, t, z, h), + ModelType.CITY_CARPLATE_MODEL, + None, + lambda x: immulti_process(x) + ), # 加载红外行人检测模型 ModelType.CITY_INFRAREDPERSON_MODEL.value[1]: ( lambda x, y, r, t, z, h: cityManagementModel(x, y, r, ModelType.CITY_INFRAREDPERSON_MODEL, t, z, h), @@ -670,5 +744,12 @@ MODEL_CONFIG = { ModelType.CITY_NIGHTFIRESMOKE_MODEL, lambda x, y, z: one_label(x, y, z), lambda x: detSeg_demo2(x) - ), + ), + # 加载密集人群计数检测模型 + ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1]: ( + lambda x, y, r, t, z, h: DENSECROWDCOUNTModel(x, y, r, ModelType.CITY_DENSECROWDCOUNT_MODEL, t, z, h), + ModelType.CITY_DENSECROWDCOUNT_MODEL, + None, + lambda x: cc_process(x) + ), } diff --git a/util/PlotsUtils.py b/util/PlotsUtils.py index ddbbce3..372b4a8 100644 --- a/util/PlotsUtils.py +++ b/util/PlotsUtils.py @@ -67,6 +67,12 @@ 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): # 识别问题描述图片的高、宽 @@ -218,6 +224,11 @@ 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, label, 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, label, font, outfontsize) + return plot_one_box_auto(box, img, color, line_thickness, label_zh) def filterBox(det0, det1, pix_dis): # det0为 (m1, 11) 矩阵 @@ -255,4 +266,71 @@ def filterBox(det0, det1, pix_dis): # 类别相同 & 中心点在上一帧的框内 判断为True res = np.sum(mask, axis=1) det0_copy[..., -1] = res - return det0_copy \ No newline at end of file + 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, label, line_thickness=2, outfontsize=20): + font = ImageFont.truetype(FONT_PATH, outfontsize, encoding='utf-8') + H,W = img.shape[:2] + # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) + # img = Image.fromarray(img) + # width, height = img.size + Wrate = W // 128 * 128/W + Hrate = H // 128 * 128/H + + # img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) + + for p in dets: + img = cv2.circle(img, (int(p[0]/Wrate), int(p[1]/Hrate)), line_thickness, color, -1) + Calc_label_arr = get_label_array(color, label, font, outfontsize) + lh, lw = Calc_label_arr.shape[0:2] + img[0:lh, 0:lw, :] = Calc_label_arr + + return img, dets \ No newline at end of file