diff --git a/apps/ai/BeiHangGrpc.proto b/apps/ai/BeiHangGrpc.proto index 526a5037..165fe66c 100644 --- a/apps/ai/BeiHangGrpc.proto +++ b/apps/ai/BeiHangGrpc.proto @@ -14,6 +14,9 @@ service Fire_Reg { rpc sendFire_Info(JinYu_Request) returns (BHFire_Response){} } +service FA_Reg { + rpc sendFA_Info(JinYu_Request) returns (BHFA_Response){} +} message JinYu_Request { int64 zzid = 1; //业务唯一ID @@ -28,9 +31,13 @@ message BHhelmet_Response { message BHFire_Response { int64 zzid = 1; //业务唯一ID - repeated FireInfo FireinfoList = 2; //0:灭火器 1:气瓶 + repeated FireInfo FireinfoList = 2; //0:灭火器 1:气瓶 2:隔离符 3.气瓶倾倒 4.气瓶正常放置 } +message BHFA_Response { + int64 zzid = 1; //业务唯一ID + bool FAinfo = 2; //是否身穿防烫服 False:炉口开时穿着不规范 True:其它情况 +} message Point { @@ -50,7 +57,8 @@ message HelmetInfo { } message FireInfo { - int64 fire = 1; //类别:0:灭火器 1:气瓶 + int64 fire = 1; //0:灭火器 1:气瓶 2:隔离符 3.气瓶倾倒 4.气瓶正常放置 double conf = 2; //置信度 Rectangle coord = 3; //矩形坐标 -} \ No newline at end of file +} + diff --git a/apps/ai/BeiHangGrpc_pb2.py b/apps/ai/BeiHangGrpc_pb2.py index 32ac5b7a..b60db2b9 100644 --- a/apps/ai/BeiHangGrpc_pb2.py +++ b/apps/ai/BeiHangGrpc_pb2.py @@ -14,13 +14,14 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11\x42\x65iHangGrpc.proto\"A\n\rJinYu_Request\x12\x0c\n\x04zzid\x18\x01 \x01(\x03\x12\x12\n\nimgsbase64\x18\x02 \x01(\t\x12\x0e\n\x06imgUrl\x18\x03 \x01(\t\"F\n\x11\x42Hhelmet_Response\x12\x0c\n\x04zzid\x18\x01 \x01(\x03\x12#\n\x0ehelmetinfoList\x18\x02 \x03(\x0b\x32\x0b.HelmetInfo\"@\n\x0f\x42HFire_Response\x12\x0c\n\x04zzid\x18\x01 \x01(\x03\x12\x1f\n\x0c\x46ireinfoList\x18\x02 \x03(\x0b\x32\t.FireInfo\"\x1d\n\x05Point\x12\t\n\x01x\x18\x01 \x01(\x01\x12\t\n\x01y\x18\x02 \x01(\x01\":\n\tRectangle\x12\x15\n\x05uleft\x18\x01 \x01(\x0b\x32\x06.Point\x12\x16\n\x06lright\x18\x02 \x01(\x0b\x32\x06.Point\"J\n\nHelmetInfo\x12\x13\n\x0bhead_helmet\x18\x01 \x01(\x03\x12\x0c\n\x04\x63onf\x18\x02 \x01(\x01\x12\x19\n\x05\x63oord\x18\x03 \x01(\x0b\x32\n.Rectangle\"A\n\x08\x46ireInfo\x12\x0c\n\x04\x66ire\x18\x01 \x01(\x03\x12\x0c\n\x04\x63onf\x18\x02 \x01(\x01\x12\x19\n\x05\x63oord\x18\x03 \x01(\x0b\x32\n.Rectangle2E\n\nHelmet_Reg\x12\x37\n\x0fsendHelmet_Info\x12\x0e.JinYu_Request\x1a\x12.BHhelmet_Response\"\x00\x32?\n\x08\x46ire_Reg\x12\x33\n\rsendFire_Info\x12\x0e.JinYu_Request\x1a\x10.BHFire_Response\"\x00\x42,\n\x17\x63om.lyzh.aiservice.grpcB\x0c\x42\x65iHangProtoP\x01\x88\x01\x01\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11\x42\x65iHangGrpc.proto\"A\n\rJinYu_Request\x12\x0c\n\x04zzid\x18\x01 \x01(\x03\x12\x12\n\nimgsbase64\x18\x02 \x01(\t\x12\x0e\n\x06imgUrl\x18\x03 \x01(\t\"F\n\x11\x42Hhelmet_Response\x12\x0c\n\x04zzid\x18\x01 \x01(\x03\x12#\n\x0ehelmetinfoList\x18\x02 \x03(\x0b\x32\x0b.HelmetInfo\"@\n\x0f\x42HFire_Response\x12\x0c\n\x04zzid\x18\x01 \x01(\x03\x12\x1f\n\x0c\x46ireinfoList\x18\x02 \x03(\x0b\x32\t.FireInfo\"-\n\rBHFA_Response\x12\x0c\n\x04zzid\x18\x01 \x01(\x03\x12\x0e\n\x06\x46\x41info\x18\x02 \x01(\x08\"\x1d\n\x05Point\x12\t\n\x01x\x18\x01 \x01(\x01\x12\t\n\x01y\x18\x02 \x01(\x01\":\n\tRectangle\x12\x15\n\x05uleft\x18\x01 \x01(\x0b\x32\x06.Point\x12\x16\n\x06lright\x18\x02 \x01(\x0b\x32\x06.Point\"J\n\nHelmetInfo\x12\x13\n\x0bhead_helmet\x18\x01 \x01(\x03\x12\x0c\n\x04\x63onf\x18\x02 \x01(\x01\x12\x19\n\x05\x63oord\x18\x03 \x01(\x0b\x32\n.Rectangle\"A\n\x08\x46ireInfo\x12\x0c\n\x04\x66ire\x18\x01 \x01(\x03\x12\x0c\n\x04\x63onf\x18\x02 \x01(\x01\x12\x19\n\x05\x63oord\x18\x03 \x01(\x0b\x32\n.Rectangle2E\n\nHelmet_Reg\x12\x37\n\x0fsendHelmet_Info\x12\x0e.JinYu_Request\x1a\x12.BHhelmet_Response\"\x00\x32?\n\x08\x46ire_Reg\x12\x33\n\rsendFire_Info\x12\x0e.JinYu_Request\x1a\x10.BHFire_Response\"\x00\x32\x39\n\x06\x46\x41_Reg\x12/\n\x0bsendFA_Info\x12\x0e.JinYu_Request\x1a\x0e.BHFA_Response\"\x00\x42,\n\x17\x63om.lyzh.aiservice.grpcB\x0c\x42\x65iHangProtoP\x01\x88\x01\x01\x62\x06proto3') _JINYU_REQUEST = DESCRIPTOR.message_types_by_name['JinYu_Request'] _BHHELMET_RESPONSE = DESCRIPTOR.message_types_by_name['BHhelmet_Response'] _BHFIRE_RESPONSE = DESCRIPTOR.message_types_by_name['BHFire_Response'] +_BHFA_RESPONSE = DESCRIPTOR.message_types_by_name['BHFA_Response'] _POINT = DESCRIPTOR.message_types_by_name['Point'] _RECTANGLE = DESCRIPTOR.message_types_by_name['Rectangle'] _HELMETINFO = DESCRIPTOR.message_types_by_name['HelmetInfo'] @@ -46,6 +47,13 @@ BHFire_Response = _reflection.GeneratedProtocolMessageType('BHFire_Response', (_ }) _sym_db.RegisterMessage(BHFire_Response) +BHFA_Response = _reflection.GeneratedProtocolMessageType('BHFA_Response', (_message.Message,), { + 'DESCRIPTOR' : _BHFA_RESPONSE, + '__module__' : 'BeiHangGrpc_pb2' + # @@protoc_insertion_point(class_scope:BHFA_Response) + }) +_sym_db.RegisterMessage(BHFA_Response) + Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), { 'DESCRIPTOR' : _POINT, '__module__' : 'BeiHangGrpc_pb2' @@ -76,6 +84,7 @@ _sym_db.RegisterMessage(FireInfo) _HELMET_REG = DESCRIPTOR.services_by_name['Helmet_Reg'] _FIRE_REG = DESCRIPTOR.services_by_name['Fire_Reg'] +_FA_REG = DESCRIPTOR.services_by_name['FA_Reg'] if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None @@ -86,16 +95,20 @@ if _descriptor._USE_C_DESCRIPTORS == False: _BHHELMET_RESPONSE._serialized_end=158 _BHFIRE_RESPONSE._serialized_start=160 _BHFIRE_RESPONSE._serialized_end=224 - _POINT._serialized_start=226 - _POINT._serialized_end=255 - _RECTANGLE._serialized_start=257 - _RECTANGLE._serialized_end=315 - _HELMETINFO._serialized_start=317 - _HELMETINFO._serialized_end=391 - _FIREINFO._serialized_start=393 - _FIREINFO._serialized_end=458 - _HELMET_REG._serialized_start=460 - _HELMET_REG._serialized_end=529 - _FIRE_REG._serialized_start=531 - _FIRE_REG._serialized_end=594 + _BHFA_RESPONSE._serialized_start=226 + _BHFA_RESPONSE._serialized_end=271 + _POINT._serialized_start=273 + _POINT._serialized_end=302 + _RECTANGLE._serialized_start=304 + _RECTANGLE._serialized_end=362 + _HELMETINFO._serialized_start=364 + _HELMETINFO._serialized_end=438 + _FIREINFO._serialized_start=440 + _FIREINFO._serialized_end=505 + _HELMET_REG._serialized_start=507 + _HELMET_REG._serialized_end=576 + _FIRE_REG._serialized_start=578 + _FIRE_REG._serialized_end=641 + _FA_REG._serialized_start=643 + _FA_REG._serialized_end=700 # @@protoc_insertion_point(module_scope) diff --git a/apps/ai/BeiHangGrpc_pb2_grpc.py b/apps/ai/BeiHangGrpc_pb2_grpc.py index 338e7b84..f7f0d1bc 100644 --- a/apps/ai/BeiHangGrpc_pb2_grpc.py +++ b/apps/ai/BeiHangGrpc_pb2_grpc.py @@ -125,3 +125,64 @@ class Fire_Reg(object): BeiHangGrpc__pb2.BHFire_Response.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + +class FA_RegStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.sendFA_Info = channel.unary_unary( + '/FA_Reg/sendFA_Info', + request_serializer=BeiHangGrpc__pb2.JinYu_Request.SerializeToString, + response_deserializer=BeiHangGrpc__pb2.BHFA_Response.FromString, + ) + + +class FA_RegServicer(object): + """Missing associated documentation comment in .proto file.""" + + def sendFA_Info(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_FA_RegServicer_to_server(servicer, server): + rpc_method_handlers = { + 'sendFA_Info': grpc.unary_unary_rpc_method_handler( + servicer.sendFA_Info, + request_deserializer=BeiHangGrpc__pb2.JinYu_Request.FromString, + response_serializer=BeiHangGrpc__pb2.BHFA_Response.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'FA_Reg', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class FA_Reg(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def sendFA_Info(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/FA_Reg/sendFA_Info', + BeiHangGrpc__pb2.JinYu_Request.SerializeToString, + BeiHangGrpc__pb2.BHFA_Response.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/apps/ai/client.py b/apps/ai/client.py index 3f0133e2..b7cc8c22 100644 --- a/apps/ai/client.py +++ b/apps/ai/client.py @@ -33,10 +33,12 @@ def helmet(ip: str, pic_url: str): pic_url (_type_): _description_ """ channel = grpc.insecure_channel(ip+':2000') # 监听频道 - stub = BeiHangGrpc_pb2_grpc.Helmet_RegStub(channel) # 客户端使用Stub类发送请求,参数为频道,为了绑定链接 - image_id = 3 + stub = BeiHangGrpc_pb2_grpc.Helmet_RegStub( + channel) # 客户端使用Stub类发送请求,参数为频道,为了绑定链接 + image_id = 1 img_path = save_dahua_pic(pic_url) - request = BeiHangGrpc_pb2.JinYu_Request(zzid=image_id, imgUrl=settings.BASE_URL_OUT + img_path) + request = BeiHangGrpc_pb2.JinYu_Request( + zzid=image_id, imgUrl=settings.BASE_URL_OUT + img_path) response = stub.sendHelmet_Info(request) if response.helmetinfoList: for i in response.helmetinfoList: @@ -53,10 +55,12 @@ def helmet2(ip: str, pic_url: str): pic_url (_type_): _description_ """ channel = grpc.insecure_channel(ip+':2002') # 监听频道 - stub = BeiHangGrpc_pb2_grpc.Helmet_RegStub(channel) # 客户端使用Stub类发送请求,参数为频道,为了绑定链接 - image_id = 3 + stub = BeiHangGrpc_pb2_grpc.Helmet_RegStub( + channel) # 客户端使用Stub类发送请求,参数为频道,为了绑定链接 + image_id = 2 img_path = save_dahua_pic(pic_url) - request = BeiHangGrpc_pb2.JinYu_Request(zzid=image_id, imgUrl=settings.BASE_URL_OUT + img_path) + request = BeiHangGrpc_pb2.JinYu_Request( + zzid=image_id, imgUrl=settings.BASE_URL_OUT + img_path) response = stub.sendHelmet_Info(request) os.remove(settings.BASE_DIR + img_path) if response.helmetinfoList: @@ -76,7 +80,8 @@ def fire1(ip: str, pic_url: str): # resized_img = cv2.resize(img, None, fx=0.25, fy=0.25) # resized_img = cv2.imencode('.png', resized_img)[1] # image_base64 = str(base64.b64encode(resized_img))[2:-1] - request = BeiHangGrpc_pb2.JinYu_Request(zzid=image_id, imgUrl=settings.BASE_URL_OUT + img_path) + request = BeiHangGrpc_pb2.JinYu_Request( + zzid=image_id, imgUrl=settings.BASE_URL_OUT + img_path) response = stub.sendFire_Info(request) os.remove(settings.BASE_DIR + img_path) # 删除临时图片 if response.FireinfoList: @@ -86,9 +91,59 @@ def fire1(ip: str, pic_url: str): return True, response +def fangtang(ip: str, pic_url: str): + # 未穿防烫服事件 + channel = grpc.insecure_channel(ip+':2003') + stub = BeiHangGrpc_pb2_grpc.FA_RegStub(channel) + image_id = 4 + img_path = save_dahua_pic(pic_url) + request = BeiHangGrpc_pb2.JinYu_Request( + zzid=image_id, imgUrl=settings.BASE_URL_OUT + img_path) + response = stub.sendFire_Info(request) + os.remove(settings.BASE_DIR + img_path) # 删除临时图片 + if response.FAinfo == False: + return True, response + return False, response + + +def jingjiedai(ip: str, pic_url: str): + # 未配置警戒带事件 + channel = grpc.insecure_channel(ip+':2001') + stub = BeiHangGrpc_pb2_grpc.Fire_RegStub(channel) + image_id = 3 + img_path = save_dahua_pic(pic_url) + request = BeiHangGrpc_pb2.JinYu_Request( + zzid=image_id, imgUrl=settings.BASE_URL_OUT + img_path) + response = stub.sendFire_Info(request) + os.remove(settings.BASE_DIR + img_path) # 删除临时图片 + if response.FireinfoList: + for i in response.FireinfoList: + if i.fire == 2: # 配置了警戒带 + return False, response + return True, response + + +def qiping(ip: str, pic_url: str): + # 气瓶倾倒事件 + channel = grpc.insecure_channel(ip+':2001') + stub = BeiHangGrpc_pb2_grpc.Fire_RegStub(channel) + image_id = 3 + img_path = save_dahua_pic(pic_url) + request = BeiHangGrpc_pb2.JinYu_Request( + zzid=image_id, imgUrl=settings.BASE_URL_OUT + img_path) + response = stub.sendFire_Info(request) + os.remove(settings.BASE_DIR + img_path) # 删除临时图片 + if response.FireinfoList: + for i in response.FireinfoList: + if i.fire == 3: # 发现气瓶倾倒 + return True, response + return False, response + + if __name__ == "__main__": path = 'http://10.99.5.24/evo-apigw/evo-oss/6ad010cf-ce45-11ec-9715-e4246c7d1635/20220826/1/dsf_3de82501-2521-11ed-884a-e4246c7d1635_7236037_7245601.jpg?token=399773e6-71f7-4202-b234-ff5aa8d2492c' - base64img = str(base64.b64encode(BytesIO(requests.get(url=path, verify=False).content).read()), 'utf-8') + base64img = str(base64.b64encode(BytesIO(requests.get( + url=path, verify=False).content).read()), 'utf-8') with open('face_test.txt', 'w') as f: f.write(base64img) is_happend, res = analyse( diff --git a/apps/ai/main.py b/apps/ai/main.py index 6f03638e..d01f5e34 100644 --- a/apps/ai/main.py +++ b/apps/ai/main.py @@ -7,7 +7,10 @@ myLogger = logging.getLogger('log') algo_dict = { "helmet": "apps.ai.client.helmet", - "fire1": "apps.ai.client.fire1" + "fire1": "apps.ai.client.fire1", + "fangtang": "apps.ai.client.fangtang", + "jingjiedai": "apps.ai.jingjiedai", + "qiping": "apps.ai.qiping" } @@ -19,14 +22,14 @@ def ai_analyse(codes: list, global_img: str, face_img: str = None): global_img (str): 全景图片地址 face_img (str): 人脸图片地址 """ - results = {} + results = {} # dict key: 触发的事件标识字符 value: 多个矩形框坐标列表 for i in codes: - if i in algo_dict: # 如果算法支持 + if i in algo_dict and i not in results: # 如果算法支持且没有识别过 module, func = algo_dict[i].rsplit(".", 1) m = importlib.import_module(module) f = getattr(m, func) try: - is_happend, res = False, None + is_happend, res, rectangle_dict = False, None, {} if i == 'helmet': # 如果是安全帽抠图识别 if face_img: is_happend, res = f(ip=settings.AI_IP, pic_url=face_img) @@ -34,8 +37,23 @@ def ai_analyse(codes: list, global_img: str, face_img: str = None): is_happend, res = getattr(m, 'helmet2')(ip=settings.AI_IP, pic_url=global_img) else: is_happend, res = f(ip=settings.AI_IP, pic_url=global_img) - if is_happend: - results.update({i: res}) + if i in ['fire1', 'jingjiedai', 'qiping']: # 如果是这3类算法就无需再识别,都在一个算法里处理了 + for x in res.FireinfoList: + has_fire = False # 默认没有灭火器 + has_jingjiedai = False # 默认没有警戒带 + qiping_qd = False # 气瓶倾倒未发生 + rectangle_dict .update({'qiping':[]}) # 气瓶倾倒的坐标字典 + if x.fire == 3 and 'qiping' in codes: # 气瓶倾倒 + qiping_qd = True + rectangle_dict['qiping'].append([x.coord.x, x.coord.y]) # 加入矩形框 + if x.fire == 0: + has_fire = True + if x.fire == 2: + has_jingjiedai = True + if (i == 'fire1' and not has_fire) or (i == 'jingjiedai' and not has_jingjiedai) or (i == 'qiping' and qiping_qd): + results.update({i: {'rectangles':rectangle_dict.get(i, [])}}) + if is_happend and (i not in results): + results.update({i: {'rectangles':rectangle_dict.get(i, [])}}) except Exception: myLogger.error('算法处理错误', exc_info=True) return results diff --git a/apps/hrm/serializers.py b/apps/hrm/serializers.py index 3d474f15..044c284c 100755 --- a/apps/hrm/serializers.py +++ b/apps/hrm/serializers.py @@ -25,7 +25,7 @@ class EmployeeSimpleSerializer(CustomModelSerializer): class Meta: model = Employee - fields = ['id', 'type', 'name', 'belong_dept', 'belong_dept_name', 'post', 'post_name', 'photo', 'third_info'] + fields = ['id', 'type', 'name', 'belong_dept', 'belong_dept_name', 'post', 'post_name', 'photo', 'third_info', 'number', 'id_number'] # class EmployeeBaseSerializer(CustomModelSerializer):