compressed_oxygen_detect.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import torch
  2. import cv2
  3. import threading
  4. from datetime import datetime
  5. from ultralytics import YOLO
  6. from globals import stop_event,redis_client,steps,hand_box,head_box
  7. from config import VIDEO_SOURCE,MODEL_PATH
  8. def init_compressed_oxygen_detection():
  9. for i, step in enumerate(steps):
  10. redis_client.set(f"compressed_oxygen_step_{i+1}",'False')
  11. def start_compressed_oxygen_detection(start_events):
  12. event = threading.Event()
  13. start_events.append(event)
  14. thread = threading.Thread(target=process_video, args=(MODEL_PATH,VIDEO_SOURCE,event))
  15. thread.daemon=True
  16. thread.start()
  17. thread.join()
  18. def IoU(box1, box2):
  19. '''
  20. 计算两个矩形框的交并比
  21. :param box1: list,第一个矩形框的左上角和右下角坐标
  22. :param box2: list,第二个矩形框的左上角和右下角坐标
  23. :return: 两个矩形框的交并比iou
  24. '''
  25. x1 = max(box1[0], box2[0]) # 交集左上角x
  26. x2 = min(box1[2], box2[2]) # 交集右下角x
  27. y1 = max(box1[1], box2[1]) # 交集左上角y
  28. y2 = min(box1[3], box2[3]) # 交集右下角y
  29. overlap = max(0., x2-x1) * max(0., y2-y1)
  30. union = (box1[2]-box1[0]) * (box1[3]-box1[1]) \
  31. + (box2[2]-box2[0]) * (box2[3]-box2[1]) \
  32. - overlap
  33. return overlap/union
  34. def process_video(model_path, video_source, start_event):
  35. model = YOLO(model_path)
  36. cap = cv2.VideoCapture(video_source)
  37. while cap.isOpened():
  38. # Read a frame from the video
  39. success, frame = cap.read()
  40. if stop_event.is_set():#控制停止推理
  41. break
  42. if success:
  43. if cap.get(cv2.CAP_PROP_POS_FRAMES) % 10 != 0:#跳帧检测,
  44. continue
  45. global step,hand_box,head_box
  46. results = model.predict(frame,conf=0.2,verbose=False)
  47. for r in results:
  48. boxes = r.boxes.xyxy # 提取所有检测到的边界框坐标
  49. confidences = r.boxes.conf # 提取所有检测到的置信度
  50. classes = r.boxes.cls # 提取所有检测到的类别索引
  51. head_box=[0,0,0,0]
  52. hand_box=[0,0,0,0]
  53. step4_flag=False
  54. air_make_up_flag=False
  55. for i in range(len(boxes)):
  56. x1, y1, x2, y2 = boxes[i].tolist()
  57. confidence = confidences[i].item()
  58. cls = int(classes[i].item())
  59. label = model.names[cls]
  60. #print("label:",label)
  61. if(label=='head'):head_box=[x1,y1,x2,y2]
  62. if(label=='hand'):hand_box=[x1,y1,x2,y2]
  63. if(label=='aerostat_gasbag'):
  64. if steps[0]==False:
  65. steps[0]=True
  66. print("steps[0]:",steps[0])
  67. if(IoU(head_box,[x1,y1,x2,y2])>0 and steps[2]==False):
  68. steps[2]=True
  69. print("steps[2]:",steps[2])
  70. if(IoU(hand_box,[x1,y1,x2,y2])>0 and steps[4]==False):
  71. step4_flag=True
  72. #steps[4]=True
  73. #print("steps[4]:",steps[4])
  74. if(label=='neckband'):
  75. if(IoU(head_box,[x1,y1,x2,y2])>0 and steps[1]==False and steps[0]==True):
  76. steps[1]=True
  77. print("steps[1]:",steps[1])
  78. if(label=='valve'):
  79. if(IoU(hand_box,[x1,y1,x2,y2])>0 and steps[3]==False):
  80. steps[3]=True
  81. print("steps[3]:",steps[3])
  82. if(label=='air make-up'):
  83. air_make_up_flag=True
  84. if steps[0]==False:
  85. steps[0]=True
  86. print("steps[0]:",steps[0])
  87. if(label=='nose clip' and steps[5]==False):
  88. steps[5]=True
  89. print("steps[5]:",steps[5])
  90. if step4_flag and not air_make_up_flag and steps[3]:
  91. steps[4]=True
  92. print("steps[4]:",steps[4])
  93. 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:
  94. steps[5]=True
  95. print("steps[5]:",steps[5])
  96. for i, step in enumerate(steps):
  97. if step and redis_client.get(f"compressed_oxygen_step_{i+1}")=='False':
  98. redis_client.rpush("compressed_oxygen_order", f"{i+1}")
  99. redis_client.set(f"compressed_oxygen_step_{i+1}",'True')
  100. start_event.set()
  101. else:
  102. # Break the loop if the end of the video is reached
  103. break
  104. # Release the video capture object and close the display window
  105. cap.release()
  106. if torch.cuda.is_available():
  107. torch.cuda.empty_cache()
  108. del model