Преглед на файлове

吊篮新增d4,d5,d6检测

dxc преди 8 месеца
родител
ревизия
7012aac5e2
променени са 4 файла, в които са добавени 320 реда и са изтрити 5 реда
  1. 161 0
      app5.py
  2. 132 0
      basket_cleaning_detect.py
  3. 21 4
      config.py
  4. 6 1
      globals.py

+ 161 - 0
app5.py

@@ -0,0 +1,161 @@
+import re
+import threading
+import time
+from flask import Flask, jsonify,send_from_directory
+
+from basket_cleaning_detect import start_basket_cleaning_detection
+from platform_remove_detect import start_platform_remove_detection,init_platform_remove_detection
+from globals import inference_thread, stop_event,redis_client
+
+
+app = Flask(__name__)
+
+
+# Define the /wearing_detection endpoint
+
+@app.route('/basket_cleaning_detection', methods=['GET'])
+def basket_cleaning_detection():#开启平台搭设检测
+    global inference_thread#当全局变量需要重新赋值时,需要用global关键字声明
+
+    if inference_thread is None or not inference_thread.is_alive():#防止重复开启检测服务
+        #redis_client.set("log_in_flag",'False')
+
+        stop_event.clear()
+
+        start_events = []#给每个线程一个事件,让我知道某个线程是否开始检测
+        inference_thread = threading.Thread(target=start_basket_cleaning_detection,args=(start_events,))
+        inference_thread.start()
+        
+            
+        app.logger.info('start_platform_setup_detection')
+        #init_platform_setup_detection()
+
+
+        # 等待所有YOLO线程开始检测
+        for event in start_events:
+            event.wait()
+
+        return jsonify({"status": "SUCCESS"}), 200
+    
+    else:
+        app.logger.info("reset_detection already running")   
+        return jsonify({"status": "ALREADY_RUNNING"}), 200    
+
+# @app.route('/basket_cleaning_status', methods=['GET']) 
+# def basket_cleaning_status():#获取平台搭设状态状态
+#     if not redis_client.exists('platform_setup_order'):#平台搭设步骤还没有一个完成
+#         app.logger.info('platform_setup_order is none')
+
+#         return jsonify({"status": "NONE"}), 200
+    
+#     else:
+
+#         platform_setup_order = redis_client.lrange("platform_setup_order", 0, -1)
+
+#         json_array = []
+#         for value in platform_setup_order:
+#             match = re.search(r'platform_setup_(\d+)', value)
+#             step_number = match.group(1)
+#             json_object = {"step": step_number, "image": redis_client.get(f"platform_setup_{step_number}_img"),'number':redis_client.get(f"platform_setup_{step_number}")}
+#             json_array.append(json_object) 
+
+#         return jsonify({"status": "SUCCESS","data":json_array}), 200
+
+
+# @app.route('/basket_cleaning_finish', methods=['GET']) 
+# def basket_cleaning_finish():#开始登录时,检测是否需要复位,若需要,则发送复位信息,否则开始焊接检测
+
+#     stop_inference_internal()
+#     app.logger.info('platform_setup_finish')
+#     return jsonify({"status": "SUCCESS"}), 200
+
+            
+
+# @app.route('/platform_remove_detection', methods=['GET']) 
+# def platform_remove_detection():#开始登录时,检测是否需要复位,若需要,则发送复位信息,否则开始焊接检测
+#     global inference_thread#当全局变量需要重新赋值时,需要用global关键字声明
+
+#     if inference_thread is None or not inference_thread.is_alive():#防止重复开启检测服务
+#         #redis_client.set("log_in_flag",'False')
+
+#         stop_event.clear()
+
+#         start_events = []#给每个线程一个事件,让我知道某个线程是否开始检测
+#         inference_thread = threading.Thread(target=start_platform_remove_detection,args=(start_events,))
+#         inference_thread.start()
+        
+            
+#         app.logger.info('start_platform_remove_detection')
+#         init_platform_remove_detection()
+
+
+#         # 等待所有YOLO线程开始检测
+#         for event in start_events:
+#             event.wait()
+
+#         return jsonify({"status": "SUCCESS"}), 200
+    
+#     else:
+#         app.logger.info("reset_detection already running")   
+#         return jsonify({"status": "ALREADY_RUNNING"}), 200    
+    
+# @app.route('/platform_remove_status', methods=['GET']) 
+# def platform_remove_status():#开始登录时,检测是否需要复位,若需要,则发送复位信息,否则开始焊接检测
+#     if not redis_client.exists('platform_remove_order'):#平台搭设步骤还没有一个完成
+#         app.logger.info('platform_remove_order is none')
+
+#         return jsonify({"status": "NONE"}), 200
+    
+#     else:
+
+#         platform_setup_order = redis_client.lrange("platform_remove_order", 0, -1)
+
+#         json_array = []
+#         for num in platform_setup_order:
+
+#             json_object = {"step": num, "image": redis_client.get(f"platform_remove_{num}_img")}
+#             json_array.append(json_object) 
+
+#         return jsonify({"status": "SUCCESS","data":json_array}), 200
+
+# @app.route('/platform_remove_finish', methods=['GET'])#点击考试结束按钮,停止检测,并复位
+# def platform_remove_finish():
+#     stop_inference_internal()
+#     app.logger.info('platform_remove_finish')
+#     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)
+    return send_from_directory('static/images', filename)
+
+
+if __name__ == '__main__':
+
+    # Start the Flask server
+    app.run(debug=False, host='172.16.20.163', port=5005)

+ 132 - 0
basket_cleaning_detect.py

@@ -0,0 +1,132 @@
+import cv2
+import torch
+from shapely.geometry import box, Polygon
+import threading
+import numpy as np
+from datetime import datetime
+from ultralytics import YOLO
+
+from utils.tool import IoU
+from globals import stop_event,redis_client
+from config import SAVE_IMG_PATH,POST_IMG_PATH4,BASKET_CLEANING_VIDEO_SOURCES,BASKET_CLEANING_MODEL_SOURCES
+from globals import basket_suspension_flag,basket_warning_zone_flag,basket_steel_wire_flag
+
+
+def init_basket_cleaning_detection():
+    # global platform_setup_steps_detect_num,platform_setup_final_result,platform_setup_steps_img
+    # platform_setup_final_result=[0]*14
+    # platform_setup_steps_detect_num=[0]*14
+    # platform_setup_steps_img=[False]*14
+    # redis_client.delete("platform_setup_order")
+    # for i in range(1, 14):
+    #     redis_client.delete(f"platform_setup_{i}")
+    #     redis_client.delete(f"platform_setup_{i}_img")
+    pass
+
+def start_basket_cleaning_detection(start_events):
+    threads = []
+    for model_path, video_source in zip(BASKET_CLEANING_VIDEO_SOURCES, BASKET_CLEANING_MODEL_SOURCES):
+        event = threading.Event()
+        start_events.append(event)
+        thread = threading.Thread(target=process_video, args=(model_path, video_source,event))
+        threads.append(thread)
+        thread.daemon=True
+        thread.start()
+
+    # Wait for all threads to complete
+    for thread in threads:
+        thread.join()
+        print("吊篮清洗子线程运行结束")
+
+
+def point_in_region(point, region):#判断点是否在多边形内
+    is_inside = cv2.pointPolygonTest(region.reshape((-1, 1, 2)), point, False)
+    return is_inside >= 0
+
+def process_video(model_path, video_source,start_event):
+    model = YOLO(model_path)
+    cap = cv2.VideoCapture(video_source)
+    while cap.isOpened():
+        if stop_event.is_set():#控制停止推理
+            break
+
+        success, frame = cap.read()
+        if success:
+            # Run YOLOv8 inference on the frame
+            if cap.get(cv2.CAP_PROP_POS_FRAMES) % 25 != 0:
+                continue
+
+            results = model.predict(frame,conf=0.6,verbose=False)
+
+            
+            #悬挂机构区域,分为四个区域
+            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)
+            
+            STEEL_WIRE_REGION = np.array([[[0, 0], [0, 0], [0, 0], [0, 0]],[[668, 310], [800, 310], [800, 1070], [668, 1070]],[[0, 0], [0, 0], [0, 0], [0, 0]],[[668, 310], [800, 310], [800, 1070], [668, 1070]]], np.int32)#钢丝绳区域,暂时没有钢丝绳的区域
+
+            global basket_suspension_flag,basket_warning_zone_flag,basket_steel_wire_flag
+            for r in results:
+                if model_path==BASKET_CLEANING_MODEL_SOURCES[0] and not basket_suspension_flag:#D4悬挂机构
+                    boxes=r.boxes.xyxy#人体的检测框
+                    keypoints = r.keypoints.xy  
+                    confidences = r.keypoints.conf  
+                    for i in range(len(boxes)):
+                        left_elbow, right_elbow, left_wrist, right_wrist = keypoints[i][7:11].tolist()#获取左右手腕和左右肘的坐标
+                        points = [left_elbow, right_elbow, left_wrist, right_wrist]
+                        is_inside1 = all(point_in_region(point, SUSPENSION_REGION[0]) for point in points)
+                        is_inside2 = all(point_in_region(point, SUSPENSION_REGION[1]) for point in points)
+                        is_inside3 = all(point_in_region(point, SUSPENSION_REGION[2]) for point in points)
+                        is_inside4 = all(point_in_region(point, SUSPENSION_REGION[3]) for point in points)
+                        if is_inside1 or is_inside2 or is_inside3 or is_inside4:
+                            basket_suspension_flag=True#悬挂机构
+                            
+                elif model_path==BASKET_CLEANING_MODEL_SOURCES[1]:#D5吊篮悬挂
+
+                    boxes = r.boxes.xyxy  
+                    confidences = r.boxes.conf 
+                    classes = r.boxes.cls  
+
+                    basket_warning_zone_flag=False#当检测不到则为False
+                    for i in range(len(boxes)):
+                        x1, y1, x2, y2 = boxes[i].tolist()
+                        confidence = confidences[i].item()
+                        cls = int(classes[i].item())
+                        label = model.names[cls]
+                        if label=='warning_zone':
+                            basket_warning_zone_flag=True
+
+                elif model_path==BASKET_CLEANING_MODEL_SOURCES[2]:#D6,pose
+                    boxes=r.boxes.xyxy#人体的检测框
+                    keypoints = r.keypoints.xy  
+                    confidences = r.keypoints.conf  
+                    for i in range(len(boxes)):
+                        left_elbow, right_elbow, left_wrist, right_wrist = keypoints[i][7:11].tolist()#获取左右手腕和左右肘的坐标
+                        points = [left_elbow, right_elbow, left_wrist, right_wrist]
+                        is_inside1 = all(point_in_region(point, STEEL_WIRE_REGION[0]) for point in points)
+                        is_inside2 = all(point_in_region(point, STEEL_WIRE_REGION[1]) for point in points)
+                        is_inside3 = all(point_in_region(point, STEEL_WIRE_REGION[2]) for point in points)
+                        is_inside4 = all(point_in_region(point, STEEL_WIRE_REGION[3]) for point in points)
+                        if is_inside1 or is_inside2 or is_inside3 or is_inside4:
+                            basket_steel_wire_flag=True#悬挂机构
+            
+
+
+                start_event.set()          
+        else:
+            # Break the loop if the end of the video is reached
+            break
+
+    # Release the video capture object and close the display window
+    cap.release()
+    if torch.cuda.is_available():
+        torch.cuda.empty_cache()
+    del model
+
+
+
+        
+
+    

+ 21 - 4
config.py

@@ -96,8 +96,25 @@ PLATFORM_WEARING_VIDEO_SOURCES=PLATFORM_CH1_RTSP
 PLATFORM_SETUP_VIDEO_SOURCES=PLATFORM_CH2_RTSP
 PLATFORM_SETUP_MODEL=PLATFORM_CH2_MODEL
 
-# 焊件是否在焊台上,焊台的多边形
-#REGION4 = np.array([[1614, 630], [1712, 961], [1963, 953], [1841, 643]], np.int32)
+#吊篮清洗
 
-# task1_finish=0 #劳保任务完成标志,当前逻辑是为3则劳保任务完成
-# task1_sava_img=False #劳保任务图片保存标志
+
+BASKET_CLEANING_CH4_POSE_MODEL='/mnt/xcd/code/ai_test/weights/yolov8s-pose.pt'
+BASKET_CLEANING_CH5_DETECT_MODEL='/mnt/xcd/code/ai_test/weights/detect.pt'
+
+BASKET_CLEANING_CH6_POSE_MODEL='/mnt/xcd/code/ai_test/weights/yolov8s-pose.pt'
+BASKET_CLEANING_CH6_DETECT_MODEL='/mnt/xcd/code/ai_test/weights/detect.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_MODEL_SOURCES=[BASKET_CLEANING_CH4_POSE_MODEL,
+                               BASKET_CLEANING_CH5_DETECT_MODEL,
+                               BASKET_CLEANING_CH6_POSE_MODEL,
+                               BASKET_CLEANING_CH6_DETECT_MODEL]

+ 6 - 1
globals.py

@@ -72,4 +72,9 @@ platform_remove_final_result=[0]*14
 platform_remove_steps_img=[False]*14
 
 remove_detection_timers = [time.time()] * 14  # 初始化计时器
-remove_detection_status = [False]*14 # 初始化检
+remove_detection_status = [False]*14 # 初始化检
+
+#吊篮清洗
+basket_suspension_flag=False
+basket_warning_zone_flag=False
+basket_steel_wire_flag=False