basket_cleaning_detect.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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_PATH5,BASKET_CLEANING_VIDEO_SOURCES,BASKET_CLEANING_MODEL_SOURCES
  11. from config import BASKET_SUSPENSION_REGION,BASKET_STEEL_WIRE_REGION,BASKET_PLATFORM_REGION,BASKET_LIFTING_REGION,BASKET_ELECTRICAL_SYSTEM_REGION,BASKET_SAFETY_LOCK_REGION,BASKET_EMPTY_LOAD_REGION,BASKET_CLEANING_OPERATION_REGION
  12. from globals import basket_suspension_flag,basket_warning_zone_flag,basket_steel_wire_flag,basket_platform_flag,basket_person_flag
  13. from globals import basket_electrical_system_flag,basket_lifting_flag,basket_safety_lock_flag,basket_safety_belt_flag,basket_empty_load_flag,basket_cleaning_operation_flag,basket_cleaning_up_flag
  14. def init_basket_cleaning_detection():
  15. global basket_suspension_flag,basket_warning_zone_flag,basket_steel_wire_flag,basket_platform_flag,basket_electrical_system_flag,basket_lifting_flag,basket_safety_lock_flag,basket_safety_belt_flag,basket_cleaning_up_flag,basket_cleaning_operation_flag,basket_empty_load_flag,basket_person_flag
  16. basket_suspension_flag=False
  17. basket_warning_zone_flag=False
  18. basket_steel_wire_flag=False
  19. basket_platform_flag=False
  20. basket_electrical_system_flag=False
  21. basket_lifting_flag=False
  22. basket_safety_lock_flag=False
  23. basket_safety_belt_flag=False
  24. basket_cleaning_up_flag=False
  25. basket_cleaning_operation_flag=False
  26. basket_empty_load_flag=False
  27. basket_person_flag=False
  28. for i in range(1, 12):
  29. redis_client.delete(f"basket_step_{i}")
  30. redis_client.delete("basket_cleaning_order")
  31. pass
  32. def start_basket_cleaning_detection(start_events):
  33. threads = []
  34. for model_path, video_source in zip(BASKET_CLEANING_MODEL_SOURCES,BASKET_CLEANING_VIDEO_SOURCES):
  35. event = threading.Event()
  36. start_events.append(event)
  37. thread = threading.Thread(target=process_video, args=(model_path, video_source,event))
  38. threads.append(thread)
  39. thread.daemon=True
  40. thread.start()
  41. print("吊篮清洗子线程运行中")
  42. # Wait for any threads to complete
  43. for thread in threads:
  44. thread.join()
  45. print("吊篮清洗子线程运行结束")
  46. def point_in_region(point, region):#判断点是否在多边形内
  47. is_inside = cv2.pointPolygonTest(region.reshape((-1, 1, 2)), point, False)
  48. return is_inside >= 0
  49. def save_image_and_redis(redis_client, results, step_name, save_path, post_path):
  50. save_time = datetime.now().strftime('%Y%m%d_%H%M')
  51. imgpath = f"{save_path}/{step_name}_{save_time}.jpg"
  52. annotated_frame = results[0].plot()
  53. if step_name == "basket_step_2":
  54. 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)
  55. elif step_name == "basket_step_3":
  56. 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)
  57. elif step_name == "basket_step_4":
  58. annotated_frame = cv2.polylines(annotated_frame, BASKET_PLATFORM_REGION.reshape(-1, 1, 2), isClosed=True, color=(0, 255, 0), thickness=4)
  59. elif step_name == "basket_step_6":
  60. 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)
  61. cv2.imwrite(imgpath, annotated_frame)
  62. redis_client.set(step_name, post_path)
  63. redis_client.rpush("basket_cleaning_order", step_name)
  64. def get_region_mean_color(regions_security_lock_and_work_area, img):
  65. for region in regions_security_lock_and_work_area:
  66. points = np.array(region, dtype=np.int32)
  67. mask = np.zeros(img.shape[:2], dtype=np.uint8)
  68. cv2.fillPoly(mask, [points], 255)
  69. roi = cv2.bitwise_and(img, img, mask=mask)
  70. mean_color = cv2.mean(roi)
  71. # 将BGR颜色均值再平均
  72. average_color_value = sum(mean_color[:3]) / 3
  73. # 判断平均值是否大于0.30
  74. if average_color_value < 0.30:
  75. return True
  76. else:
  77. return False
  78. def process_video(model_path, video_source,start_event):
  79. model = YOLO(model_path)
  80. cap = cv2.VideoCapture(video_source)
  81. #cap.set(cv2.CAP_PROP_BUFFERSIZE, 100) # 设置缓冲区大小为 10 帧
  82. while cap.isOpened():
  83. if stop_event.is_set():#控制停止推理
  84. break
  85. success, frame = cap.read()
  86. if success:
  87. # Run YOLOv8 inference on the frame
  88. if cap.get(cv2.CAP_PROP_POS_FRAMES) % 25 != 0:
  89. continue
  90. results = model.predict(frame,conf=0.6,verbose=False)
  91. global basket_suspension_flag,basket_warning_zone_flag,basket_steel_wire_flag,basket_platform_flag,basket_electrical_system_flag,basket_lifting_flag,basket_safety_lock_flag,basket_safety_belt_flag,basket_cleaning_up_flag,basket_cleaning_operation_flag,basket_empty_load_flag,basket_person_flag
  92. for r in results:
  93. if model_path==BASKET_CLEANING_MODEL_SOURCES[0] and not basket_suspension_flag:#D4悬挂机构
  94. boxes=r.boxes.xyxy#人体的检测框
  95. keypoints = r.keypoints.xy
  96. confidences = r.keypoints.conf
  97. for i in range(len(boxes)):
  98. left_wrist, right_wrist = keypoints[i][9:11].tolist()#获取左右手腕和左右肘的坐标
  99. points = [left_wrist, right_wrist]
  100. is_inside1 = any(point_in_region(point, BASKET_SUSPENSION_REGION[0]) for point in points)
  101. is_inside2 = any(point_in_region(point, BASKET_SUSPENSION_REGION[1]) for point in points)
  102. is_inside3 = any(point_in_region(point, BASKET_SUSPENSION_REGION[2]) for point in points)
  103. is_inside4 = any(point_in_region(point, BASKET_SUSPENSION_REGION[3]) for point in points)
  104. if is_inside1 or is_inside2 or is_inside3 or is_inside4:
  105. basket_suspension_flag=True#悬挂机构
  106. print("悬挂机构")
  107. elif model_path==BASKET_CLEANING_MODEL_SOURCES[1]:#D5吊篮悬挂
  108. boxes = r.boxes.xyxy
  109. confidences = r.boxes.conf
  110. classes = r.boxes.cls
  111. basket_warning_zone_flag=False#当检测不到则为False
  112. basket_cleaning_up_flag=False
  113. for i in range(len(boxes)):
  114. x1, y1, x2, y2 = boxes[i].tolist()
  115. confidence = confidences[i].item()
  116. cls = int(classes[i].item())
  117. label = model.names[cls]
  118. if label=='warning_zone':
  119. basket_warning_zone_flag=True
  120. elif label=='brush':
  121. basket_cleaning_up_flag=True
  122. # elif label=='person':
  123. elif model_path==BASKET_CLEANING_MODEL_SOURCES[2]:#D6,pose
  124. boxes=r.boxes.xyxy#人体的检测框
  125. keypoints = r.keypoints.xy
  126. confidences = r.keypoints.conf
  127. basket_person_flag=False#当检测不到则为False
  128. for i in range(len(boxes)):
  129. #当有检测框,则说明有人
  130. basket_person_flag=True
  131. left_wrist, right_wrist = keypoints[i][9:11].tolist()#获取左右手腕和左右肘的坐标
  132. points = [left_wrist, right_wrist]
  133. if not basket_steel_wire_flag:
  134. is_inside1 = any(point_in_region(point, BASKET_STEEL_WIRE_REGION[0]) for point in points)
  135. is_inside2 = any(point_in_region(point, BASKET_STEEL_WIRE_REGION[1]) for point in points)
  136. #is_inside3 = any(point_in_region(point, BASKET_STEEL_WIRE_REGION[2]) for point in points)
  137. #is_inside4 = any(point_in_region(point, BASKET_STEEL_WIRE_REGION[3]) for point in points)
  138. if is_inside1 or is_inside2:
  139. basket_steel_wire_flag=True#钢丝绳
  140. print("钢丝绳")
  141. if not basket_platform_flag:
  142. is_inside = any(point_in_region(point, BASKET_PLATFORM_REGION) for point in points)
  143. if is_inside:
  144. basket_platform_flag=True
  145. print("平台")
  146. if not basket_lifting_flag:
  147. is_inside = any(point_in_region(point, BASKET_LIFTING_REGION) for point in points)
  148. if is_inside:
  149. basket_lifting_flag=True
  150. print("提升机")
  151. if not basket_electrical_system_flag:
  152. is_inside = any(point_in_region(point, BASKET_ELECTRICAL_SYSTEM_REGION) for point in points)
  153. if is_inside:
  154. basket_electrical_system_flag=True
  155. print("电气系统")
  156. if not basket_safety_lock_flag:
  157. is_inside1 = any(point_in_region(point, BASKET_SAFETY_LOCK_REGION[0]) for point in points)
  158. is_inside2 = any(point_in_region(point, BASKET_SAFETY_LOCK_REGION[1]) for point in points)
  159. if is_inside1 or is_inside2:
  160. basket_safety_lock_flag=True
  161. print("安全锁")
  162. if not basket_person_flag and get_region_mean_color([BASKET_EMPTY_LOAD_REGION], frame):
  163. basket_empty_load_flag=True
  164. else:#d6目标检测
  165. boxes = r.boxes.xyxy
  166. confidences = r.boxes.conf
  167. classes = r.boxes.cls
  168. #basket_safety_lock_flag=False#当检测不到则为False
  169. for i in range(len(boxes)):
  170. x1, y1, x2, y2 = boxes[i].tolist()
  171. confidence = confidences[i].item()
  172. cls = int(classes[i].item())
  173. label = model.names[cls]
  174. if label=='safety_belt':
  175. basket_safety_belt_flag=True
  176. elif label=='brush':
  177. is_inside = any(point_in_region(point,BASKET_CLEANING_OPERATION_REGION) for point in points)
  178. if is_inside:
  179. basket_cleaning_operation_flag=True
  180. if model_path==BASKET_CLEANING_MODEL_SOURCES[0] and not redis_client.exists("basket_step_2") and basket_suspension_flag:#D4悬挂机构
  181. save_image_and_redis(redis_client, results, "basket_step_2", SAVE_IMG_PATH, POST_IMG_PATH5)
  182. elif model_path==BASKET_CLEANING_MODEL_SOURCES[1]:#D5吊篮悬挂
  183. if basket_warning_zone_flag and not redis_client.exists("basket_step_1"):#警戒区
  184. save_image_and_redis(redis_client, results, "basket_step_1", SAVE_IMG_PATH, POST_IMG_PATH5)
  185. elif basket_cleaning_up_flag and not redis_client.exists("basket_step_11"):
  186. save_image_and_redis(redis_client, results, "basket_step_11", SAVE_IMG_PATH, POST_IMG_PATH5)
  187. elif not basket_warning_zone_flag and redis_client.exists("basket_step_1") and not redis_client.exists("basket_step_12"):
  188. save_image_and_redis(redis_client, results, "basket_step_12", SAVE_IMG_PATH, POST_IMG_PATH5)
  189. elif model_path==BASKET_CLEANING_MODEL_SOURCES[2]:#D6,pose
  190. if basket_steel_wire_flag and not redis_client.exists("basket_step_3"):
  191. save_image_and_redis(redis_client, results, "basket_step_3", SAVE_IMG_PATH, POST_IMG_PATH5)
  192. elif basket_platform_flag and not redis_client.exists("basket_step_4"):
  193. save_image_and_redis(redis_client, results, "basket_step_4", SAVE_IMG_PATH, POST_IMG_PATH5)
  194. elif basket_lifting_flag and not redis_client.exists("basket_step_5"):
  195. save_image_and_redis(redis_client, results, "basket_step_5", SAVE_IMG_PATH, POST_IMG_PATH5)
  196. elif basket_electrical_system_flag and not redis_client.exists("basket_step_7"):
  197. save_image_and_redis(redis_client, results, "basket_step_7", SAVE_IMG_PATH, POST_IMG_PATH5)
  198. elif basket_safety_lock_flag and not redis_client.exists("basket_step_6"):
  199. save_image_and_redis(redis_client, results, "basket_step_6", SAVE_IMG_PATH, POST_IMG_PATH5)
  200. elif basket_empty_load_flag and not redis_client.exists("basket_step_8"):
  201. save_image_and_redis(redis_client, results, "basket_step_8", SAVE_IMG_PATH, POST_IMG_PATH5)
  202. else:#d6目标检测
  203. if basket_safety_belt_flag and not redis_client.exists("basket_step_9"):
  204. save_image_and_redis(redis_client, results, "basket_step_9", SAVE_IMG_PATH, POST_IMG_PATH5)
  205. elif basket_cleaning_operation_flag and not redis_client.exists("basket_step_10"):
  206. save_image_and_redis(redis_client, results, "basket_step_10", SAVE_IMG_PATH, POST_IMG_PATH5)
  207. start_event.set()
  208. else:
  209. # Break the loop if the end of the video is reached
  210. break
  211. # Release the video capture object and close the display window
  212. cap.release()
  213. if torch.cuda.is_available():
  214. torch.cuda.empty_cache()
  215. del model