equipment_cleaning_detect.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 EQUIPMENT_ANCHOR_DEVICE_REGION], isClosed=True, color=(0, 255, 0), thickness=4)
  43. elif step_name == "equipment_step_4":
  44. annotated_frame = cv2.polylines(annotated_frame, [region.reshape(-1, 1, 2) for region in EQUIPMENT_WORK_ROPE_REGION], isClosed=True, color=(0, 255, 0), thickness=4)
  45. elif step_name == "equipment_step_5":
  46. annotated_frame = cv2.polylines(annotated_frame, [region.reshape(-1, 1, 2) for region in EQUIPMENT_SAFETY_ROPE_REGION], isClosed=True, color=(0, 255, 0), thickness=4)
  47. elif step_name == "equipment_step_10":
  48. annotated_frame = cv2.polylines(annotated_frame, [region.reshape(-1, 1, 2) for region in EQUIPMENT_CLEANING_OPERATION_REGION], isClosed=True, color=(0, 255, 0), thickness=4)
  49. # elif step_name == "equipment_step_4":
  50. # annotated_frame = cv2.polylines(annotated_frame, BASKET_PLATFORM_REGION.reshape(-1, 1, 2), isClosed=True, color=(0, 255, 0), thickness=4)
  51. # elif step_name == "equipment_step_6":
  52. # 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)
  53. cv2.imwrite(imgpath, annotated_frame)
  54. redis_client.set(step_name, post_path)
  55. redis_client.rpush("equipment_cleaning_order", step_name)
  56. def process_video(model_path, video_source,start_event):
  57. model = YOLO(model_path)
  58. cap = cv2.VideoCapture(video_source)
  59. #cap.set(cv2.CAP_PROP_BUFFERSIZE, 100) # 设置缓冲区大小为 10 帧
  60. while cap.isOpened():
  61. if stop_event.is_set():#控制停止推理
  62. break
  63. success, frame = cap.read()
  64. if success:
  65. # Run YOLOv8 inference on the frame
  66. if cap.get(cv2.CAP_PROP_POS_FRAMES) % 25 != 0:
  67. continue
  68. results = model.predict(frame,conf=0.6,verbose=False)
  69. global equipment_cleaning_flag
  70. for r in results:
  71. if model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[0]:#D3 detect
  72. boxes = r.boxes.xyxy
  73. confidences = r.boxes.conf
  74. classes = r.boxes.cls
  75. # basket_warning_zone_flag=False#当检测不到则为False
  76. # basket_cleaning_up_flag=False
  77. equipment_cleaning_flag[0]=False
  78. for i in range(len(boxes)):
  79. x1, y1, x2, y2 = boxes[i].tolist()
  80. confidence = confidences[i].item()
  81. cls = int(classes[i].item())
  82. label = model.names[cls]
  83. if label=='warning_zone':
  84. equipment_cleaning_flag[0]=True
  85. print("警戒区")
  86. elif label=='person':
  87. centerx=(x1+x2)/2
  88. centery=(y1+y2)/2
  89. point_in_region_flag=point_in_region([centerx,centery],EQUIPMENT_ANCHOR_DEVICE_REGION)#挂点装置是否检测到人
  90. if point_in_region_flag:
  91. equipment_cleaning_flag[1]=True
  92. elif label=='seating_plate':
  93. equipment_cleaning_flag[2]=True
  94. elif label=='self_locking':
  95. equipment_cleaning_flag[5]=True
  96. equipment_cleaning_flag[6]=True
  97. elif label=='brush':
  98. equipment_cleaning_flag[10]=True
  99. elif not equipment_cleaning_flag[0]:#当检测不到警戒区时,判定未拆除警戒区域
  100. equipment_cleaning_flag[11]=True
  101. elif model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[1]:#D8,pose
  102. boxes=r.boxes.xyxy#人体的检测框
  103. keypoints = r.keypoints.xy
  104. confidences = r.keypoints.conf
  105. basket_person_flag=False#当检测不到则为False
  106. for i in range(len(boxes)):
  107. #当有检测框,则说明有人
  108. #basket_person_flag=True
  109. left_wrist, right_wrist = keypoints[i][9:11].tolist()#获取左右手腕和左右肘的坐标
  110. points = [left_wrist, right_wrist]
  111. if not equipment_cleaning_flag[3]:
  112. is_inside1 = any(point_in_region(point, EQUIPMENT_WORK_ROPE_REGION[0]) for point in points)
  113. if is_inside1:
  114. equipment_cleaning_flag[3]=True#工作绳
  115. print("工作绳")
  116. if not equipment_cleaning_flag[4]:
  117. is_inside = any(point_in_region(point, EQUIPMENT_SAFETY_ROPE_REGION) for point in points)
  118. if is_inside:
  119. equipment_cleaning_flag[4]=True#安全绳
  120. print("安全绳")
  121. elif model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[2]:#d8 目标检测
  122. boxes = r.boxes.xyxy
  123. confidences = r.boxes.conf
  124. classes = r.boxes.cls
  125. #basket_safety_lock_flag=False#当检测不到则为False
  126. for i in range(len(boxes)):
  127. x1, y1, x2, y2 = boxes[i].tolist()
  128. confidence = confidences[i].item()
  129. cls = int(classes[i].item())
  130. label = model.names[cls]
  131. if label=='safety_belt':
  132. equipment_cleaning_flag[8]=True
  133. elif label=='brush':
  134. is_inside = any(point_in_region(point,EQUIPMENT_CLEANING_OPERATION_REGION) for point in points)#刷子是否在指定区域
  135. if is_inside:
  136. equipment_cleaning_flag[9]=True
  137. if model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[0]:
  138. if equipment_cleaning_flag[0] and not redis_client.exists("equipment_step_1"):
  139. save_image_and_redis(redis_client, results, "equipment_step_1", SAVE_IMG_PATH, POST_IMG_PATH6)
  140. if equipment_cleaning_flag[1] and not redis_client.exists("equipment_step_2"):
  141. save_image_and_redis(redis_client, results, "equipment_step_2", SAVE_IMG_PATH, POST_IMG_PATH6)
  142. if equipment_cleaning_flag[2] and not redis_client.exists("equipment_step_3"):
  143. save_image_and_redis(redis_client, results, "equipment_step_3", SAVE_IMG_PATH, POST_IMG_PATH6)
  144. if equipment_cleaning_flag[5] and not redis_client.exists("equipment_step_6"):
  145. save_image_and_redis(redis_client, results, "equipment_step_6", SAVE_IMG_PATH, POST_IMG_PATH6)
  146. if equipment_cleaning_flag[10] and not redis_client.exists("equipment_step_11"):
  147. save_image_and_redis(redis_client, results, "equipment_step_11", SAVE_IMG_PATH, POST_IMG_PATH6)
  148. if equipment_cleaning_flag[11] and not redis_client.exists("equipment_step_12"):
  149. save_image_and_redis(redis_client, results, "equipment_step_12", SAVE_IMG_PATH, POST_IMG_PATH6)
  150. elif model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[1]:
  151. if equipment_cleaning_flag[3] and not redis_client.exists("equipment_step_4"):
  152. save_image_and_redis(redis_client, results, "equipment_step_4", SAVE_IMG_PATH, POST_IMG_PATH6)
  153. if equipment_cleaning_flag[4] and not redis_client.exists("equipment_step_5"):
  154. save_image_and_redis(redis_client, results, "equipment_step_5", SAVE_IMG_PATH, POST_IMG_PATH6)
  155. elif model_path==EQUIPMENT_CLEANING_MODEL_SOURCES[2]:#d6目标检测
  156. if equipment_cleaning_flag[8] and not redis_client.exists("equipment_step_9"):
  157. save_image_and_redis(redis_client, results, "equipment_step_9", SAVE_IMG_PATH, POST_IMG_PATH6)
  158. if equipment_cleaning_flag[9] and not redis_client.exists("equipment_step_10"):
  159. save_image_and_redis(redis_client, results, "equipment_step_10", SAVE_IMG_PATH, POST_IMG_PATH6)
  160. start_event.set()
  161. else:
  162. # Break the loop if the end of the video is reached
  163. break
  164. # Release the video capture object and close the display window
  165. cap.release()
  166. if torch.cuda.is_available():
  167. torch.cuda.empty_cache()
  168. del model