dxc 7 сар өмнө
parent
commit
41653d128b
3 өөрчлөгдсөн 395 нэмэгдсэн , 0 устгасан
  1. 109 0
      app.py
  2. 193 0
      config.py
  3. 93 0
      globals.py

+ 109 - 0
app.py

@@ -0,0 +1,109 @@
+import threading
+import time
+from flask import Flask, jsonify,send_from_directory
+from welding_wearing_detect import start_wearing_detection,init_wearing_detection
+from globals import inference_thread, stop_event,lock,redis_client
+
+#焊接考核的穿戴
+app = Flask(__name__)
+
+
+# Define the /wearing_detection endpoint
+@app.route('/wearing_detection', methods=['GET'])
+def wearing_detection():
+    global inference_thread#当全局变量需要重新赋值时,需要用global关键字声明
+
+    if inference_thread is None or not inference_thread.is_alive():
+        stop_event.clear()#stop_event不用global声明,因为不需要重新赋值,他只是调用了其方法,并没有重新赋值
+        
+        start_events = []#给每个线程一个事件,让我知道某个线程是否开始检测
+        inference_thread = threading.Thread(target=start_wearing_detection,args=(start_events,))
+        inference_thread.start()
+        init_wearing_detection()
+
+        # 等待所有YOLO线程开始检测,两个线程检测完毕时,才返回SUCCESS
+        for event in start_events:
+            event.wait()
+
+        app.logger.info('start_wearing_detection')
+        return jsonify({"status": "SUCCESS"}), 200
+    
+    else:
+        app.logger.info("start_wearing_detection already running")   
+        return jsonify({"status": "ALREADY_RUNNING"}), 200
+    
+
+@app.route('/human_postion_status', methods=['GET']) 
+def human_postion_status():#开始登录时,检测是否需要复位,若需要,则发送复位信息,否则开始焊接检测
+    #global inference_thread
+    if redis_client.get("welding_wearing_human_in_postion")=='False':
+        app.logger.info('NOT_IN_POSTION')
+        return jsonify({"status": "NOT_IN_POSTION"}), 200
+    else:
+        app.logger.info('IN_POSTION')
+        return jsonify({"status": "IN_POSTION"}), 200
+
+@app.route('/wearing_status', methods=['GET']) 
+def wearing_status():#开始登录时,检测是否需要复位,若需要,则发送复位信息,否则开始焊接检测
+    #global inference_thread
+    with lock:   
+        #TODO 若出现异常再发送FAIL.
+        redis_client.set("welding_wearing_detection_img_flag",'True')
+        time.sleep(1)
+        if not redis_client.exists("welding_wearing_items_nums") or not redis_client.exists("welding_wearing_detection_img"):
+            return jsonify({"status": "NONE"}), 200##表示穿戴检测线程还未检测完
+        
+        wearing_items_nums = redis_client.lrange("welding_wearing_items_nums", 0, -1)
+        wearing_items_list = ['pants', 'jacket', 'helmet', 'gloves', 'shoes']
+        json_array = []
+        for num, item in zip(wearing_items_nums, wearing_items_list):
+            json_object = {"name": item, "number": num}
+            json_array.append(json_object)
+
+        app.logger.info(json_array)
+        image=redis_client.get("welding_wearing_detection_img")
+        app.logger.info(image)
+
+        return jsonify({"status": "SUCCESS","data":json_array,"image":image}), 200
+
+               
+@app.route('/end_wearing_exam', methods=['GET'])
+def end_wearing_exam():
+    init_wearing_detection()
+    return jsonify({"status": "SUCCESS"}), 200
+
+    
+
+def stop_inference_internal():
+    global inference_thread
+    if inference_thread is not None and inference_thread.is_alive():
+        stop_event.set()  # 设置停止事件标志,通知推理线程停止运行
+        inference_thread.join()  # 等待推理线程结束
+        inference_thread = None  # 释放线程资源
+        app.logger.info('detection stopped')
+        return True
+    else:
+        app.logger.info('No inference stopped')
+        return False
+
+@app.route('/stop_detection', methods=['GET'])
+def stop_inference():
+    #global inference_thread
+    if stop_inference_internal():
+        app.logger.info('detection stopped')
+        return jsonify({"status": "DETECTION_STOPPED"}), 200
+    else:
+        app.logger.info('No_detection_running')
+        return jsonify({"status": "No_detection_running"}), 200
+
+@app.route('/images/<filename>')
+def get_image(filename):
+    app.logger.info('get_image'+filename)
+    #pdb.set_trace()
+    return send_from_directory('static/images', filename)
+
+
+if __name__ == '__main__':
+
+    # Start the Flask server
+    app.run(debug=False, host='172.16.20.163', port=5001)

+ 193 - 0
config.py

@@ -0,0 +1,193 @@
+import numpy as np
+
+
+#CLIENT_URL = 'http://172.16.20.23:8081/'
+
+SAVE_IMG_PATH = '/mnt/xcd/code/ai_test/static/images'  # 图片保存在服务器的实际位置
+
+POST_IMG_PATH1 = 'http://172.16.20.163:5001/images'  # 通过端口映射post发送能够访问的位置 焊接考核科目1
+POST_IMG_PATH2 = 'http://172.16.20.163:5002/images' #焊接考核科目2
+POST_IMG_PATH3 = 'http://172.16.20.163:5003/images' #平台搭设科目1,劳保穿戴
+POST_IMG_PATH4 = 'http://172.16.20.163:5004/images' #平台搭设科目2,搭建和拆除
+POST_IMG_PATH5 = 'http://172.16.20.163:5005/images'#吊篮清洗
+POST_IMG_PATH6 = 'http://172.16.20.163:5006/images'#吊具清洗
+
+#焊接考核视频流
+# Define paths to RTSP streams
+WELDING_CH1_RTSP = 'rtsp://admin:yaoan1234@172.16.22.230/cam/realmonitor?channel=1&subtype=0'#焊机开关视频
+WELDING_CH2_RTSP = 'rtsp://admin:yaoan1234@172.16.22.231/cam/realmonitor?channel=1&subtype=0'#焊台视频
+WELDING_CH3_RTSP = 'rtsp://admin:yaoan1234@172.16.22.233/cam/realmonitor?channel=1&subtype=0'#检查油桶视频
+WELDING_CH4_RTSP = 'rtsp://admin:yaoan1234@172.16.22.232/cam/realmonitor?channel=1&subtype=0'#检查总开关视频
+WELDING_CH5_RTSP = 'rtsp://admin:yaoan1234@172.16.22.234/cam/realmonitor?channel=1&subtype=0'#检查面具手套接地线视频
+WELDING_CH6_RTSP = 'rtsp://admin:yaoan1234@172.16.22.235/cam/realmonitor?channel=1&subtype=0'#劳保用品穿戴视频
+
+WELDING_CH1_MODEL="/mnt/xcd/code/ai_test/weights/ch1_welding_switch_813.pt"
+WELDING_CH2_MODEL="/mnt/xcd/code/ai_test/weights/ch2_welding_desk_cls_813.pt"
+WELDING_CH3_MODEL="/mnt/xcd/code/ai_test/weights/ch3_oil_barrel_detect_813.pt"
+WELDING_CH4_MODEL="/mnt/xcd/code/ai_test/weights/ch4_main_switch_cls_813.pt"
+WELDING_CH5_MODEL="/mnt/xcd/code/ai_test/weights/ch5_mask_gloves_wire_detect_813.pt"
+WELDING_CH6_MODEL='/mnt/xcd/code/ai_test/weights/ch6_wearing_detect_813.pt'
+
+HUMAN_DETECTION_MODEL="/mnt/xcd/code/ai_test/weights/yolov8n.pt"#人体检测模型
+
+# Define paths to models
+WELDING_MODEL_PATHS = [
+    WELDING_CH1_MODEL,
+    WELDING_CH2_MODEL,
+    WELDING_CH3_MODEL,
+    WELDING_CH4_MODEL,
+    WELDING_CH5_MODEL
+]
+
+WELDING_VIDEO_SOURCES = [
+    WELDING_CH1_RTSP,
+    WELDING_CH2_RTSP,
+    WELDING_CH3_RTSP,
+    WELDING_CH4_RTSP,
+    WELDING_CH5_RTSP
+]
+
+
+
+WELDING_WEARING_MODEL=[
+    HUMAN_DETECTION_MODEL,
+    WELDING_CH6_MODEL
+]
+
+WELDING_WEARING_VIDEO_SOURCES= WELDING_CH6_RTSP
+
+#WEAR_DETECTION_VIDEO_SOURCES= "/home/dxc/special_test/ch1.mp4"
+
+# 劳保用品 指定要检测的区域 (xmin, ymin, xmax, ymax)
+WEAR_DETECTION_AREA = (350, 0, 1400, 1080)
+
+
+# 头盔检测区域(xmin, ymin, xmax, ymax)
+
+WELDING_REGION1=(1499,339,1839,723)
+# 油桶危险区域(多边形)
+
+WELDING_REGION2 = np.array([[607, 555], [454, 0], [2560, 0], [2560, 1440], [430, 1440]], np.int32)
+
+# 搭铁夹连接焊台位置
+
+WELDING_REGION3 = np.array([[1613, 627], [1601, 658], [1697, 987], [1710, 962]], np.int32)
+
+
+####平台搭设视频流
+PLATFORM_CH1_RTSP='rtsp://admin:yaoan1234@172.16.22.241/cam/realmonitor?channel=1&subtype=0'#检测穿戴
+
+PLATFORM_CH2_RTSP='rtsp://admin:yaoan1234@172.16.22.240/cam/realmonitor?channel=1&subtype=0'#脚手架搭建
+# PLATFORM_CH3_RTSP='rtsp://admin:yaoan1234@172.16.22.243/cam/realmonitor?channel=1&subtype=0'#脚手架搭建
+PLATFORM_CH4_RTSP='rtsp://admin:yaoan1234@172.16.22.233/cam/realmonitor?channel=1&subtype=0'#脚手架搭建
+
+PLATFORM_CH1_MODEL='/mnt/xcd/code/ai_test/weights/platform_ch1_wearing.pt'
+
+PLATFORM_SETUP_MODEL='/mnt/xcd/code/ai_test/weights/obb_9_2.pt'
+PLATFORM_SETUP_VIDEO_SOURCES=[PLATFORM_CH2_RTSP,
+                              #PLATFORM_CH3_RTSP,
+                              PLATFORM_CH4_RTSP
+]
+
+PLATFORM_WEARING_MODEL=[
+    HUMAN_DETECTION_MODEL,
+    PLATFORM_CH1_MODEL    
+]
+
+PLATFORM_WEARING_VIDEO_SOURCES=PLATFORM_CH1_RTSP
+
+#PLATFORM_CH2_MODEL='/mnt/xcd/code/ai_test/weights/high_work_obb_final.pt'
+
+# Define paths to input videos
+
+
+#焊接劳保检测相关参数
+
+#################平台搭设检测相关参数
+
+# PLATFORM_SETUP_VIDEO_SOURCES=PLATFORM_CH2_RTSP
+# PLATFORM_SETUP_MODEL=PLATFORM_SETUP_MODEL
+
+#吊篮清洗
+
+
+BASKET_CLEANING_CH4_POSE_MODEL='/mnt/xcd/code/ai_test/weights/yolov8s-pose1.pt'
+BASKET_CLEANING_CH5_DETECT_MODEL='/mnt/xcd/code/ai_test/weights/yolov8s1.pt'
+BASKET_CLEANING_CH6_POSE_MODEL='/mnt/xcd/code/ai_test/weights/yolov8s-pose2.pt'
+BASKET_CLEANING_CH6_DETECT_MODEL='/mnt/xcd/code/ai_test/weights/ch6detect_basket.pt'
+BASKET_CLEANING_CH6_SEG_MODEL='/mnt/xcd/code/ai_test/weights/basket_seg.pt'
+
+BASKET_CLEANING_CH4_RTSP='rtsp://admin:yaoan1234@172.16.22.237/cam/realmonitor?channel=1&subtype=0'
+#BASKET_CLEANING_CH5_RTSP='rtsp://admin:yaoan1234@172.16.22.239/cam/realmonitor?channel=1&subtype=0'
+BASKET_CLEANING_CH6_RTSP='rtsp://admin:yaoan1234@172.16.22.242/cam/realmonitor?channel=1&subtype=0'
+
+BASKET_CLEANING_VIDEO_SOURCES=[BASKET_CLEANING_CH4_RTSP,
+                               #BASKET_CLEANING_CH5_RTSP,
+                               BASKET_CLEANING_CH6_RTSP,
+                               BASKET_CLEANING_CH6_RTSP,
+                               BASKET_CLEANING_CH6_RTSP]
+
+BASKET_CLEANING_MODEL_SOURCES=[BASKET_CLEANING_CH4_POSE_MODEL,
+                               #BASKET_CLEANING_CH5_DETECT_MODEL,
+                               BASKET_CLEANING_CH6_POSE_MODEL,
+                               BASKET_CLEANING_CH6_DETECT_MODEL,
+                               BASKET_CLEANING_CH6_SEG_MODEL]
+
+#
+
+#悬挂机构区域,分为四个区域 D4
+BASKET_SUSPENSION_REGION = np.array([
+    [[668, 310], [800, 310], [800, 1070], [668, 1070]],
+    [[1690, 310], [1750, 310], [1750, 710], [1690, 710]],
+    [[1350, 340], [1405, 340], [1405, 720], [1350, 720]],
+    [[550, 385], [635, 385], [635, 880], [550, 880]]
+], np.int32)
+
+BASKET_STEEL_WIRE_REGION = np.array([
+    [(374, 846), (601, 970), (630, 900), (441, 786)],  # 右一多边形区域
+    [(1518, 736), (1649, 945), (2005, 917), (1888, 677)]  # 右二多边形区域
+    # [(1293, 0), (1867, 935), (1904, 906), (1354, 9)],  # 左边多边形区域
+], np.int32)#钢丝绳区域,暂时没有钢丝绳的区域
+
+BASKET_PLATFORM_REGION = np.array([], np.int32)
+BASKET_LIFTING_REGION = np.array([]
+,np.int32)
+
+BASKET_SAFETY_LOCK_REGION = np.array([
+    [[1635, 813], [1742, 927], [1955, 910], [1906, 747]],
+    [[650, 944], [800, 1000], [800, 923], [680, 872]]
+    ], np.int32)
+BASKET_ELECTRICAL_SYSTEM_REGION = np.array([], np.int32)
+BASKET_CLEANING_OPERATION_REGION = np.array([[8, 1038], [14, 1423], [1910, 1432], [1894, 1129]], np.int32)
+BASKET_EMPTY_LOAD_REGION = np.array([(752, 855), (712, 969), (836, 1020), (896, 918)], np.int32)
+
+
+#单人吊具
+EQUIPMENT_CLEANING_CH3_RTSP='rtsp://admin:yaoan1234@172.16.22.238/cam/realmonitor?channel=1&subtype=0'
+EQUIPMENT_CLEANING_CH8_RTSP='rtsp://admin:yaoan1234@172.16.22.44/cam/realmonitor?channel=1&subtype=0'
+
+
+EQUIPMENT_CLEANING_CH3_DETECT_MODEL='/mnt/xcd/code/ai_test/weights/ch6detect_basket.pt'
+EQUIPMENT_CLEANING_CH8_POSE_MODEL='/mnt/xcd/code/ai_test/weights/yolov8s-pose2.pt'
+EQUIPMENT_CLEANING_CH8_DETECT_MODEL='/mnt/xcd/code/ai_test/weights/ch6detect_basket.pt'
+
+EQUIPMENT_CLEANING_VIDEO_SOURCES=[EQUIPMENT_CLEANING_CH3_RTSP,
+                                  EQUIPMENT_CLEANING_CH8_RTSP,
+                                  EQUIPMENT_CLEANING_CH8_RTSP
+]
+
+EQUIPMENT_CLEANING_MODEL_SOURCES=[EQUIPMENT_CLEANING_CH3_DETECT_MODEL,
+                                  EQUIPMENT_CLEANING_CH8_POSE_MODEL,
+                                  EQUIPMENT_CLEANING_CH8_DETECT_MODEL
+]
+
+EQUIPMENT_ANCHOR_DEVICE_REGION = np.array([
+    [[913, 6], [914, 520], [1350, 523], [1351, 9]],
+], np.int32)
+EQUIPMENT_WORK_ROPE_REGION = np.array([
+    [[1466, 1187], [1416, 1248], [2500, 1162], [2502, 1063]],
+], np.int32)
+EQUIPMENT_SAFETY_ROPE_REGION = np.array([
+    [[1466, 1187], [1416, 1248], [2500, 1162], [2502, 1063]],
+], np.int32)
+EQUIPMENT_CLEANING_OPERATION_REGION=np.array([[1697, 930], [1055, 1253], [2000, 1420], [2450, 1000]], np.int32)

+ 93 - 0
globals.py

@@ -0,0 +1,93 @@
+import threading
+# 全局变量来控制推理线程
+import redis
+import time
+# 连接到 Redis 服务器
+redis_client = redis.StrictRedis(host='localhost', port=5050, db=0,decode_responses=True)
+
+inference_thread = None
+stop_event = threading.Event()
+lock=threading.Lock()
+
+#condition = threading.Condition()
+###############焊接考核
+#为True时,表示某一步骤完成,并保存图片post
+step1=False #危险源排除
+step2=False
+step3=False
+step4=False
+step5=False
+step6=False #危险源排除
+step7=False
+step8=False
+step9=False
+step10=False
+step11=False
+step12=False
+step13=False
+
+steps = [False] * 13
+
+oil_barrel=None
+main_switch=None
+grounding_wire=None
+welding_machine_switch=None
+welding_components=None
+mask=None
+welding=None
+gloves=None
+sweep=None
+
+sweep_detect_num=0
+welding_detect_num=0
+###############
+
+
+
+
+###########检测物品是否复位
+oil_barrel_flag=False
+main_switch_flag=False
+ground_wire_flag=False
+welding_components_flag=False
+welding_machine_switch_flag=False
+
+oil_barrel_save_img=False
+main_switch_save_img=False
+ground_wire_save_img=False
+welding_components_save_img=False
+welding_machine_switch_save_img=False
+
+
+reset_all=None
+log_in_flag=False#登录标志,如前端未登录,不允许保存图片并post
+###############################
+###############平台搭设考核
+platform_setup_steps_detect_num=[0]*14
+platform_setup_final_result=[0]*14
+platform_setup_steps_img=[False]*14
+################平台拆除考核
+platform_remove_steps_detect_num=[0]*14
+platform_remove_final_result=[0]*14
+platform_remove_steps_img=[False]*14
+
+remove_detection_timers = [time.time()] * 14  # 初始化计时器
+remove_detection_status = [False]*14 # 初始化检
+
+#吊篮清洗
+basket_person_flag=False#吊篮区域是否存在人员
+basket_suspension_flag=False#吊篮悬挂机构
+basket_warning_zone_flag=False#吊篮警戒区
+basket_steel_wire_flag=False#吊篮钢丝绳
+basket_platform_flag=False#吊篮平台
+basket_lifting_flag=False#吊篮升降机构
+basket_safety_lock_flag=False#吊篮安全锁
+basket_electrical_system_flag=False#吊篮电气系统
+basket_empty_load_flag=False#吊篮空载
+basket_safety_belt_flag=False#吊篮安全带挂设
+
+basket_cleaning_operation_flag=False#吊篮清洗操作,检查刷子是否在指定区域
+basket_cleaning_up_flag=False#吊篮清理现场
+
+#单人吊具
+equipment_cleaning_flag=[False]*12