1
0

25 کامیت‌ها ad6ec809b4 ... c4ab11c603

نویسنده SHA1 پیام تاریخ
  Xuecheng Dong c4ab11c603 Merge pull request #14 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc ecf470f735 修改status逻辑 9 ماه پیش
  Xuecheng Dong fa09baf96b Merge pull request #13 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc 5627a38616 修改初始化代码 9 ماه پیش
  Xuecheng Dong 9061920ddc Merge pull request #12 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc 759c6e53c0 增加post demo 9 ماه پیش
  Xuecheng Dong c337286d50 Merge pull request #11 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc 456adcb262 修改部分逻辑 9 ماه پیش
  Xuecheng Dong b3a2acacbc Delete weights directory 9 ماه پیش
  Xuecheng Dong a490498531 Merge pull request #10 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc aa9492ccfd 修改后端逻辑 9 ماه پیش
  Xuecheng Dong 722bf1c586 Merge pull request #9 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc 1af333fa31 修改bug 9 ماه پیش
  Xuecheng Dong 9eae8a845c Merge pull request #8 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc a13f06e830 增加p2权重 9 ماه پیش
  Xuecheng Dong a2ba87c579 Merge pull request #7 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc 69e903b7e4 完成初步识别逻辑 9 ماه پیش
  Xuecheng Dong 0a9cba4d1a Merge pull request #6 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc 4996316ec1 增加权重文件,修改部分代码 9 ماه پیش
  MrLu18 a4dcb2855f Merge pull request #5 from dongxuecheng/lxd 9 ماه پیش
  MEF e118147d24 tow 9 ماه پیش
  MEF 6a6e50a40e hello lxd 9 ماه پیش
  Xuecheng Dong 4c729dea42 Merge pull request #4 from dongxuecheng/dxc/basic_frame 9 ماه پیش
  dxc fbf77e9d28 删除不必要代码 9 ماه پیش
  dxc 41653d128b 基础框架搭建 9 ماه پیش
8فایلهای تغییر یافته به همراه332 افزوده شده و 4 حذف شده
  1. 1 0
      .gitignore
  2. 25 4
      README.md
  3. 95 0
      app.py
  4. 144 0
      compressed_oxygen_detect.py
  5. 20 0
      config.py
  6. 25 0
      globals.py
  7. 11 0
      post_demo.py
  8. 11 0
      post_demo1.py

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
+weights/
 # Byte-compiled / optimized / DLL files
 __pycache__/
 *.py[cod]

+ 25 - 4
README.md

@@ -1,5 +1,26 @@
 # self_rescuer
-自救器
-# 测试-dxc-9-2
-测试-dxc-9-2
-# 测试协同
+## 压缩氧
+## 过程
+1. 外壳去掉
+2. 脖带戴好 
+3. 咬口具
+4. 氧气瓶开启
+5. 补气
+6. 带鼻夹
+
+## 模型label名称
+- chemical_oxygen_self-rescuer
+- aerostat_gasbag
+- neckband
+- head
+- mouthpiece
+- valve
+- air make-up
+- hand
+- noseclip
+- compressed_oxygen_self_rescuer
+- cloth_cover
+- compression_airbags
+- starter_pin
+- activate
+- pin

+ 95 - 0
app.py

@@ -0,0 +1,95 @@
+import threading
+from flask import Flask, jsonify
+from compressed_oxygen_detect import init_compressed_oxygen_detection,start_compressed_oxygen_detection
+from globals import inference_thread, stop_event,lock,redis_client
+
+#焊接考核的穿戴
+app = Flask(__name__)
+
+
+# Define the /wearing_detection endpoint
+@app.route('/compressed_oxygen_detection', methods=['GET'])
+def compressed_oxygen_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_compressed_oxygen_detection,args=(start_events,))
+        inference_thread.start()
+        init_compressed_oxygen_detection()
+
+        # 等待所有YOLO线程开始检测,两个线程检测完毕时,才返回SUCCESS
+        for event in start_events:
+            event.wait()
+
+        app.logger.info('start_compressed_oxygen_detection')
+        return jsonify({"status": "SUCCESS"}), 200
+    
+    else:
+        app.logger.info("start_compressed_oxygen_detection already running")   
+        return jsonify({"status": "ALREADY_RUNNING"}), 200
+    
+
+
+@app.route('/compressed_oxygen_status', methods=['GET']) 
+def compressed_oxygen_status():#开始登录时,检测是否需要复位,若需要,则发送复位信息,否则开始焊接检测
+    #global inference_thread
+    if not redis_client.exists('compressed_oxygen_order'):
+        app.logger.info('compressed_oxygen_order is none')
+
+        return jsonify({"status": "NONE"}), 200
+    
+    else:           
+        compressed_oxygen_order = redis_client.lrange("compressed_oxygen_order", 0, -1)
+        json_array = []
+        for step in compressed_oxygen_order:
+            json_object = {"step": step}
+            json_array.append(json_object)
+
+        app.logger.info(json_array)
+
+        return jsonify({"status": "SUCCESS","data":json_array}), 200
+
+               
+@app.route('/end_compressed_oxygen_detection', methods=['GET'])
+def end_wearing_exam():
+    init_compressed_oxygen_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='127.0.0.1', port=5007)

+ 144 - 0
compressed_oxygen_detect.py

@@ -0,0 +1,144 @@
+import torch
+import cv2
+import threading
+from datetime import datetime
+from ultralytics import YOLO
+from globals import stop_event,redis_client,steps,hand_box,head_box
+from config import VIDEO_SOURCE,MODEL_PATH
+
+
+def init_compressed_oxygen_detection():
+    for i, step in enumerate(steps):
+        redis_client.set(f"compressed_oxygen_step_{i+1}",'False')
+    redis_client.delete("compressed_oxygen_order")
+
+def start_compressed_oxygen_detection(start_events):
+        
+    event = threading.Event()
+    start_events.append(event)
+    thread = threading.Thread(target=process_video, args=(MODEL_PATH,VIDEO_SOURCE,event))
+    thread.daemon=True
+    thread.start()
+    thread.join()
+
+def IoU(box1, box2):
+    '''
+    计算两个矩形框的交并比
+    :param box1: list,第一个矩形框的左上角和右下角坐标
+    :param box2: list,第二个矩形框的左上角和右下角坐标
+    :return: 两个矩形框的交并比iou
+    '''
+    x1 = max(box1[0], box2[0])   # 交集左上角x
+    x2 = min(box1[2], box2[2])   # 交集右下角x
+    y1 = max(box1[1], box2[1])   # 交集左上角y
+    y2 = min(box1[3], box2[3])   # 交集右下角y
+ 
+    overlap = max(0., x2-x1) * max(0., y2-y1)
+    union = (box1[2]-box1[0]) * (box1[3]-box1[1]) \
+            + (box2[2]-box2[0]) * (box2[3]-box2[1]) \
+            - overlap
+ 
+    return overlap/union
+
+def process_video(model_path, video_source, start_event):
+
+    
+    model = YOLO(model_path)
+    cap = cv2.VideoCapture(video_source)
+    while cap.isOpened():
+    # Read a frame from the video
+        success, frame = cap.read()
+        if stop_event.is_set():#控制停止推理
+            break
+        if success:
+            
+            if cap.get(cv2.CAP_PROP_POS_FRAMES) % 10 != 0:#跳帧检测,
+                continue
+
+            global step,hand_box,head_box
+            results = model.predict(frame,conf=0.2,verbose=False)
+
+            for r in results:
+                boxes = r.boxes.xyxy  # 提取所有检测到的边界框坐标
+                confidences = r.boxes.conf  # 提取所有检测到的置信度
+                classes = r.boxes.cls  # 提取所有检测到的类别索引
+
+                head_box=[0,0,0,0]
+                hand_box=[0,0,0,0]
+                step4_flag=False
+                air_make_up_flag=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]
+                    #print("label:",label)
+
+                    if(label=='head'):head_box=[x1,y1,x2,y2]
+                    if(label=='hand'):hand_box=[x1,y1,x2,y2]
+
+                    if(label=='aerostat_gasbag'):
+                        if steps[0]==False:
+                            steps[0]=True
+                            print("steps[0]:",steps[0])
+
+                        if(IoU(head_box,[x1,y1,x2,y2])>0 and steps[2]==False):
+                            steps[2]=True
+                            print("steps[2]:",steps[2])
+                        if(IoU(hand_box,[x1,y1,x2,y2])>0 and steps[4]==False):
+                            step4_flag=True
+                            #steps[4]=True
+                            #print("steps[4]:",steps[4])
+
+                    if(label=='neckband'):
+                        
+                        if(IoU(head_box,[x1,y1,x2,y2])>0 and steps[1]==False and steps[0]==True):
+                            steps[1]=True
+                            print("steps[1]:",steps[1])
+
+
+                    if(label=='valve'):
+                        if(IoU(hand_box,[x1,y1,x2,y2])>0 and steps[3]==False):
+                            steps[3]=True
+                            print("steps[3]:",steps[3])
+                    
+                    if(label=='air make-up'):
+                        air_make_up_flag=True
+                        if steps[0]==False:
+                            steps[0]=True
+                            print("steps[0]:",steps[0])
+
+
+
+                    if(label=='nose clip' and steps[5]==False):
+                        steps[5]=True
+                        print("steps[5]:",steps[5])
+                
+                if step4_flag and not air_make_up_flag and steps[3]:
+                    steps[4]=True
+                    print("steps[4]:",steps[4])
+
+                if head_box != [0, 0, 0, 0] and hand_box != [0, 0, 0, 0] and IoU(head_box, hand_box) > 0 and steps[5] == False:
+                    steps[5]=True
+                    print("steps[5]:",steps[5])
+                    
+                for i, step in enumerate(steps):
+                    if step and redis_client.get(f"compressed_oxygen_step_{i+1}")=='False':
+                        redis_client.rpush("compressed_oxygen_order", f"{i+1}")
+                        redis_client.set(f"compressed_oxygen_step_{i+1}",'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
+
+

+ 20 - 0
config.py

@@ -0,0 +1,20 @@
+# 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
+
+VIDEO_SOURCE = 'rtsp://admin:yaoan1234@192.168.1.114/cam/realmonitor?channel=1&subtype=0'  # 视频源路径
+#焊接考核视频流
+# Define paths to RTSP streams
+
+
+MODEL_PATH="weights/yolov8m-p2-self.pt"
+
+
+
+

+ 25 - 0
globals.py

@@ -0,0 +1,25 @@
+import threading
+# 全局变量来控制推理线程
+import redis
+import time
+# 连接到 Redis 服务器
+redis_client = redis.StrictRedis(host='127.0.0.1', port=6379, db=0,decode_responses=True)
+
+inference_thread = None
+stop_event = threading.Event()
+lock=threading.Lock()
+
+###############焊接考核
+#为True时,表示某一步骤完成,并保存图片post
+steps = [False] * 6
+head_box=[0,0,0,0]
+hand_box=[0,0,0,0]
+
+# 压缩氧
+# 1 = 外壳去掉
+# 2 = 脖带戴好 
+# 3 = 咬口具
+# 4 = 氧气瓶开启
+# 5 = 补气
+# 6 = 带鼻夹
+

+ 11 - 0
post_demo.py

@@ -0,0 +1,11 @@
+import requests
+
+url = 'http://127.0.0.1:5007/compressed_oxygen_detection'
+
+
+response = requests.get(url)
+
+if response.status_code == 200:
+    print(response.text)
+else:
+    print(response.text)

+ 11 - 0
post_demo1.py

@@ -0,0 +1,11 @@
+import requests
+
+url = 'http://127.0.0.1:5007/compressed_oxygen_status'
+
+
+response = requests.get(url)
+
+if response.status_code == 200:
+    print(response.text)
+else:
+    print(response.text)