diff --git a/concurrency/FileUploadThread.py b/concurrency/FileUploadThread.py index d662512..1be5139 100644 --- a/concurrency/FileUploadThread.py +++ b/concurrency/FileUploadThread.py @@ -19,22 +19,21 @@ 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 @@ -44,15 +43,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 @@ -65,8 +64,7 @@ class ImageFileUpload(FileUpload): 模型编号:modeCode 检测目标:detectTargetCode ''' - print('*'*100,' mqtt_list:',len(self._mqtt_list)) - + print('*' * 100, ' mqtt_list:', len(self._mqtt_list)) model_info = [] # 更加模型编码解析数据 @@ -78,12 +76,10 @@ class ImageFileUpload(FileUpload): for target in target_list: # 自研车牌模型判断 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 + 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]) else: draw_painting_joint(target[1], aFrame, target[3], target[2], target[4], font_config, target[5]) @@ -115,13 +111,15 @@ 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() @@ -137,12 +135,14 @@ 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,6 +235,7 @@ 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): """ @@ -256,9 +257,10 @@ class ImageTypeImageFileUpload(Thread): for target in target_list: # 自研车牌模型判断 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]) + 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]) else: draw_painting_joint(target[1], aiFrame, target[3], target[2], target[4], font_config) @@ -287,8 +289,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) @@ -313,14 +315,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, @@ -336,12 +338,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()) @@ -357,14 +359,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, @@ -389,12 +391,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)) @@ -406,7 +408,8 @@ 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: diff --git a/concurrency/IntelligentRecognitionProcess.py b/concurrency/IntelligentRecognitionProcess.py index 2160aa8..663878b 100644 --- a/concurrency/IntelligentRecognitionProcess.py +++ b/concurrency/IntelligentRecognitionProcess.py @@ -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,8 +92,6 @@ class IntelligentRecognitionProcess(Process): return hb_thread - - class OnlineIntelligentRecognitionProcess(IntelligentRecognitionProcess): __slots__ = () @@ -112,19 +110,16 @@ 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() @@ -145,7 +140,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): @@ -225,7 +220,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 @@ -240,14 +235,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) @@ -300,7 +295,8 @@ 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): + ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\ + ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code): if draw_config.get(code) is None: draw_config[code] = {} draw_config["font_config"] = model_conf[4] @@ -331,11 +327,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: @@ -447,12 +443,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) @@ -626,7 +622,8 @@ 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): + ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\ + ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1] == str(code): if draw_config.get(code) is None: draw_config[code] = {} draw_config["font_config"] = model_conf[4] @@ -766,7 +763,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): @@ -943,7 +940,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 @@ -982,7 +979,6 @@ 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("当前页面无人") @@ -1271,7 +1267,8 @@ 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]: + elif model[1] == ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] or \ + model[1] == ModelType.CITY_UNDERBUILDCOUNT_MODEL.value[1]: result = t.submit(self.denscrowdcountRec, imageUrls, model, image_queue, request_id) task_list.append(result) else: @@ -1486,9 +1483,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) diff --git a/concurrency/PushVideoStreamProcess.py b/concurrency/PushVideoStreamProcess.py index 39acd89..724f189 100644 --- a/concurrency/PushVideoStreamProcess.py +++ b/concurrency/PushVideoStreamProcess.py @@ -151,35 +151,35 @@ class OnPushStreamProcess(PushStreamProcess): # 自研车牌模型处理 if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code): cls = 0 - ocrlabel, xybox = qs - box = xy2xyxy(xybox) + box = xy2xyxy(qs[1]) 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): + 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): 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, points, copy_frame, color, crowdlabel) + rr = t.submit(draw_name_crowd, qs, copy_frame, color) 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,17 +261,18 @@ 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 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 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) @@ -393,22 +394,21 @@ class OffPushStreamProcess(PushStreamProcess): # 自研车牌模型处理 if ModelType.CITY_CARPLATE_MODEL.value[1] == str(code): cls = 0 - ocrlabel, xybox = qs - box = xy2xyxy(xybox) + box = xy2xyxy(qs[1]) score = None color = rainbows[cls] label_array = None label_arrays = [None] - rr = t.submit(draw_name_ocr,xybox,copy_frame,color,ocrlabel) + rr = t.submit(draw_name_ocr, qs, copy_frame, color) - elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code): + elif ModelType.CITY_DENSECROWDCOUNT_MODEL.value[1] == str(code) or\ + ModelType.CITY_UNDERBUILDCOUNT_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) + rr = t.submit(draw_name_crowd, qs, copy_frame, color) else: box, score, cls = xywh2xyxy2(qs) @@ -500,16 +500,15 @@ class OffPushStreamProcess(PushStreamProcess): 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 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 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) diff --git a/enums/ModelTypeEnum-jcq.py b/enums/ModelTypeEnum-jcq.py new file mode 100644 index 0000000..aa7de0a --- /dev/null +++ b/enums/ModelTypeEnum-jcq.py @@ -0,0 +1,768 @@ +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 diff --git a/enums/ModelTypeEnum-raw.py b/enums/ModelTypeEnum-raw.py new file mode 100644 index 0000000..79fd69c --- /dev/null +++ b/enums/ModelTypeEnum-raw.py @@ -0,0 +1,807 @@ +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 diff --git a/enums/ModelTypeEnum.py b/enums/ModelTypeEnum.py index fada509..d2adeba 100644 --- a/enums/ModelTypeEnum.py +++ b/enums/ModelTypeEnum.py @@ -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,8 +633,6 @@ 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}}, @@ -976,12 +974,14 @@ class ModelType(Enum): 'row': 2, 'line': 2, 'point_loss_coef': 0.45, - 'conf': 0.25, + 'conf': 0.65, 'gpu_id': 0, 'eos_coef': '0.5', 'set_cost_class': 1, 'set_cost_point': 0.05, - 'backbone': 'vgg16_bn' + 'backbone': 'vgg16_bn', + 'expend': 10, + 'psize': 2, }, }], }) @@ -1006,6 +1006,42 @@ 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: diff --git a/util/ModelUtils.py b/util/ModelUtils.py index a5e6c9f..4dd2f7e 100644 --- a/util/ModelUtils.py +++ b/util/ModelUtils.py @@ -46,8 +46,12 @@ class OneModel: new_device = select_device(par.get('device')) half = new_device.type != 'cpu' Detweights = par['Detweights'] - with open(Detweights, "rb") as f, trt.Runtime(trt.Logger(trt.Logger.ERROR)) as runtime: - model = runtime.deserialize_cuda_engine(f.read()) + 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() par['segPar']['seg_nclass'] = par['seg_nclass'] Segweights = par['Segweights'] if Segweights: @@ -402,8 +406,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 = par['models'][0]['par'] - self.model_conf = (modeType, device, models[0], postPar, rainbows) + postPar = [pp['par'] for pp in par['models']] + self.model_conf = (modeType, device, models, postPar, rainbows) except Exception: logger.error("模型加载异常:{}, requestId:{}", format_exc(), requestId) raise ServiceException(ExceptionType.MODEL_LOADING_EXCEPTION.value[0], @@ -752,4 +756,11 @@ 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) + ), } diff --git a/util/PlotsUtils.py b/util/PlotsUtils.py index 372b4a8..943305d 100644 --- a/util/PlotsUtils.py +++ b/util/PlotsUtils.py @@ -2,6 +2,7 @@ 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") @@ -224,11 +225,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): +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, label, font, outfontsize) - return plot_one_box_auto(box, img, color, line_thickness, label_zh) + # (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) 矩阵 @@ -262,7 +263,7 @@ 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 @@ -316,21 +317,54 @@ def plot_one_box_auto(box, img, color=None, line_thickness=2, label_array=None): return img, box -def draw_name_crowd(dets, img, color, label, line_thickness=2, outfontsize=20): +def draw_name_crowd(dets, img, color, 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 + 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) - # img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) + 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 - 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