equipment_cleaning_detect.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import cv2
  2. import torch
  3. from shapely.geometry import box, Polygon
  4. import threading
  5. import numpy as np
  6. from datetime import datetime
  7. from ultralytics import YOLO
  8. from utils.tool import IoU
  9. from globals import stop_event,redis_client
  10. from config import SAVE_IMG_PATH,POST_IMG_PATH6,EQUIPMENT_CLEANING_VIDEO_SOURCES,EQUIPMENT_CLEANING_MODEL_SOURCES
  11. from config import EQUIPMENT_SAFETY_ROPE_REGION,EQUIPMENT_WORK_ROPE_REGION,EQUIPMENT_ANCHOR_DEVICE_REGION,EQUIPMENT_CLEANING_OPERATION_REGION
  12. from globals import equipment_cleaning_flag
  13. def init_equipment_cleaning_detection():
  14. global equipment_cleaning_flag
  15. equipment_cleaning_flag=[False]*12
  16. for i in range(1, 12):
  17. redis_client.delete(f"equipment_step_{i}")
  18. redis_client.delete("equipment_cleaning_order")
  19. pass
  20. def start_equipment_cleaning_detection(start_events):
  21. threads = []
  22. for model_path, video_source in zip(EQUIPMENT_CLEANING_MODEL_SOURCES,EQUIPMENT_CLEANING_VIDEO_SOURCES):
  23. event = threading.Event()
  24. start_events.append(event)
  25. thread = threading.Thread(target=process_video, args=(model_path, video_source,event))
  26. threads.append(thread)
  27. thread.daemon=True
  28. thread.start()
  29. print("单人吊具清洗子线程运行中")
  30. # Wait for any threads to complete
  31. for thread in threads:
  32. thread.join()
  33. print("单人吊具清洗子线程运行结束")
  34. def point_in_region(point, region):#判断点是否在多边形内
  35. is_inside = cv2.pointPolygonTest(region.reshape((-1, 1, 2)), point, False)
  36. return is_inside >= 0
  37. def save_image_and_redis(redis_client, results, step_name, save_path, post_path):
  38. save_time = datetime.now().strftime('%Y%m%d_%H%M')
  39. imgpath = f"{save_path}/{step_name}_{save_time}.jpg"
  40. annotated_frame = results[0].plot()
  41. # if step_name == "equipment_step_2":
  42. # annotated_frame = cv2.polylines(annotated_frame, [region.reshape(-1, 1, 2) for region in BASKET_SUSPENSION_REGION], isClosed=True, color=(0, 255, 0), thickness=4)
  43. # elif step_name == "equipment_step_3":
  44. # annotated_frame = cv2.polylines(annotated_frame, [region.reshape(-1, 1, 2) for region in BASKET_STEEL_WIRE_REGION], isClosed=True, color=(0, 255, 0), thickness=4)
  45. # elif step_name == "equipment_step_4":
  46. # annotated_frame = cv2.polylines(annotated_frame, BASKET_PLATFORM_REGION.reshape(-1, 1, 2), isClosed=True, color=(0, 255, 0), thickness=4)
  47. # elif step_name == "equipment_step_6":
  48. # annotated_frame = cv2.polylines(annotated_frame, [region.reshape(-1, 1, 2) for region in BASKET_SAFETY_LOCK_REGION], isClosed=True, color=(0, 255, 0), thickness=4)
  49. cv2.imwrite(imgpath, annotated_frame)
  50. redis_client.set(step_name, post_path)
  51. redis_client.rpush("equipment_cleaning_order", step_name)
  52. def process_video(model_path, video_source,start_event):
  53. model = YOLO(model_path)
  54. cap = cv2.VideoCapture(video_source)
  55. #cap.set(cv2.CAP_PROP_BUFFERSIZE, 100) # 设置缓冲区大小为 10 帧
  56. while cap.isOpened():
  57. if stop_event.is_set():#控制停止推理
  58. break
  59. success, frame = cap.read()
  60. if success:
  61. # Run YOLOv8 inference on the frame
  62. if cap.get(cv2.CAP_PROP_POS_FRAMES) % 25 != 0:
  63. continue
  64. results = model.predict(frame,conf=0.6,verbose=False)
  65. global equipment_cleaning_flag
  66. for r in results:
  67. if model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[0]:#D3 detect
  68. boxes = r.boxes.xyxy
  69. confidences = r.boxes.conf
  70. classes = r.boxes.cls
  71. # basket_warning_zone_flag=False#当检测不到则为False
  72. # basket_cleaning_up_flag=False
  73. equipment_cleaning_flag[0]=False
  74. for i in range(len(boxes)):
  75. x1, y1, x2, y2 = boxes[i].tolist()
  76. confidence = confidences[i].item()
  77. cls = int(classes[i].item())
  78. label = model.names[cls]
  79. if label=='warning_zone':
  80. equipment_cleaning_flag[0]=True
  81. elif label=='person':
  82. centerx=(x1+x2)/2
  83. centery=(y1+y2)/2
  84. point_in_region_flag=point_in_region([centerx,centery],EQUIPMENT_ANCHOR_DEVICE_REGION)#挂点装置是否检测到人
  85. if point_in_region_flag:
  86. equipment_cleaning_flag[1]=True
  87. elif label=='seating_plate':
  88. equipment_cleaning_flag[2]=True
  89. elif label=='self_locking':
  90. equipment_cleaning_flag[5]=True
  91. equipment_cleaning_flag[6]=True
  92. elif label=='brush':
  93. equipment_cleaning_flag[10]=True
  94. elif not equipment_cleaning_flag[0]:#当检测不到警戒区时,判定未拆除警戒区域
  95. equipment_cleaning_flag[11]=True
  96. elif model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[1]:#D8,pose
  97. boxes=r.boxes.xyxy#人体的检测框
  98. keypoints = r.keypoints.xy
  99. confidences = r.keypoints.conf
  100. basket_person_flag=False#当检测不到则为False
  101. for i in range(len(boxes)):
  102. #当有检测框,则说明有人
  103. #basket_person_flag=True
  104. left_wrist, right_wrist = keypoints[i][9:11].tolist()#获取左右手腕和左右肘的坐标
  105. points = [left_wrist, right_wrist]
  106. if not equipment_cleaning_flag[3]:
  107. is_inside1 = any(point_in_region(point, EQUIPMENT_WORK_ROPE_REGION[0]) for point in points)
  108. if is_inside1:
  109. equipment_cleaning_flag[3]=True#工作绳
  110. print("工作绳")
  111. if not equipment_cleaning_flag[4]:
  112. is_inside = any(point_in_region(point, EQUIPMENT_SAFETY_ROPE_REGION) for point in points)
  113. if is_inside:
  114. equipment_cleaning_flag[4]=True#安全绳
  115. print("安全绳")
  116. else:#d8 目标检测
  117. boxes = r.boxes.xyxy
  118. confidences = r.boxes.conf
  119. classes = r.boxes.cls
  120. #basket_safety_lock_flag=False#当检测不到则为False
  121. for i in range(len(boxes)):
  122. x1, y1, x2, y2 = boxes[i].tolist()
  123. confidence = confidences[i].item()
  124. cls = int(classes[i].item())
  125. label = model.names[cls]
  126. if label=='safety_belt':
  127. equipment_cleaning_flag[8]=True
  128. elif label=='brush':
  129. is_inside = any(point_in_region(point,EQUIPMENT_CLEANING_OPERATION_REGION) for point in points)#刷子是否在指定区域
  130. if is_inside:
  131. equipment_cleaning_flag[9]=True
  132. if model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[0]:
  133. if equipment_cleaning_flag[0] and not redis_client.exists("equipment_step_1"):
  134. save_image_and_redis(redis_client, results, "equipment_step_1", SAVE_IMG_PATH, POST_IMG_PATH6)
  135. if equipment_cleaning_flag[1] and not redis_client.exists("equipment_step_2"):
  136. save_image_and_redis(redis_client, results, "equipment_step_2", SAVE_IMG_PATH, POST_IMG_PATH6)
  137. if equipment_cleaning_flag[2] and not redis_client.exists("equipment_step_3"):
  138. save_image_and_redis(redis_client, results, "equipment_step_3", SAVE_IMG_PATH, POST_IMG_PATH6)
  139. if equipment_cleaning_flag[5] and not redis_client.exists("equipment_step_6"):
  140. save_image_and_redis(redis_client, results, "equipment_step_6", SAVE_IMG_PATH, POST_IMG_PATH6)
  141. if equipment_cleaning_flag[10] and not redis_client.exists("equipment_step_11"):
  142. save_image_and_redis(redis_client, results, "equipment_step_11", SAVE_IMG_PATH, POST_IMG_PATH6)
  143. if equipment_cleaning_flag[11] and not redis_client.exists("equipment_step_12"):
  144. save_image_and_redis(redis_client, results, "equipment_step_12", SAVE_IMG_PATH, POST_IMG_PATH6)
  145. elif model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[1]:
  146. if equipment_cleaning_flag[3] and not redis_client.exists("equipment_step_4"):
  147. save_image_and_redis(redis_client, results, "equipment_step_4", SAVE_IMG_PATH, POST_IMG_PATH6)
  148. if equipment_cleaning_flag[4] and not redis_client.exists("equipment_step_5"):
  149. save_image_and_redis(redis_client, results, "equipment_step_5", SAVE_IMG_PATH, POST_IMG_PATH6)
  150. else:#d6目标检测
  151. if equipment_cleaning_flag[8] and not redis_client.exists("equipment_step_9"):
  152. save_image_and_redis(redis_client, results, "equipment_step_9", SAVE_IMG_PATH, POST_IMG_PATH6)
  153. if equipment_cleaning_flag[9] and not redis_client.exists("equipment_step_10"):
  154. save_image_and_redis(redis_client, results, "equipment_step_10", SAVE_IMG_PATH, POST_IMG_PATH6)
  155. start_event.set()
  156. else:
  157. # Break the loop if the end of the video is reached
  158. break
  159. # Release the video capture object and close the display window
  160. cap.release()
  161. if torch.cuda.is_available():
  162. torch.cuda.empty_cache()
  163. del model