object_detection.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import datetime
  2. import cv2
  3. import numpy as np
  4. from edgetpu.detection.engine import DetectionEngine
  5. from . util import tonumpyarray
  6. # Path to frozen detection graph. This is the actual model that is used for the object detection.
  7. PATH_TO_CKPT = '/frozen_inference_graph.pb'
  8. # List of the strings that is used to add correct label for each box.
  9. PATH_TO_LABELS = '/label_map.pbtext'
  10. # Function to read labels from text files.
  11. def ReadLabelFile(file_path):
  12. with open(file_path, 'r') as f:
  13. lines = f.readlines()
  14. ret = {}
  15. for line in lines:
  16. pair = line.strip().split(maxsplit=1)
  17. ret[int(pair[0])] = pair[1].strip()
  18. return ret
  19. def detect_objects(prepped_frame_array, prepped_frame_time, prepped_frame_lock,
  20. prepped_frame_ready, prepped_frame_box, object_queue, debug):
  21. # Load the edgetpu engine and labels
  22. engine = DetectionEngine(PATH_TO_CKPT)
  23. labels = ReadLabelFile(PATH_TO_LABELS)
  24. prepped_frame_time = 0.0
  25. while True:
  26. with prepped_frame_ready:
  27. prepped_frame_ready.wait()
  28. # make a copy of the cropped frame
  29. with prepped_frame_lock:
  30. prepped_frame_copy = prepped_frame_array.copy()
  31. prepped_frame_time = prepped_frame_time.value
  32. region_box = prepped_frame_box.value
  33. # Actual detection.
  34. ans = engine.DetectWithInputTensor(prepped_frame_copy, threshold=0.5, top_k=3)
  35. # put detected objects in the queue
  36. if ans:
  37. # assumes square
  38. region_size = region_box[3]-region_box[0]
  39. for obj in ans:
  40. box = obj.bounding_box.flatten().tolist()
  41. object_queue.append({
  42. 'frame_time': prepped_frame_time,
  43. 'name': str(labels[obj.label_id]),
  44. 'score': float(obj.score),
  45. 'xmin': int((box[0] * region_size) + region_box[0]),
  46. 'ymin': int((box[1] * region_size) + region_box[1]),
  47. 'xmax': int((box[2] * region_size) + region_box[0]),
  48. 'ymax': int((box[3] * region_size) + region_box[1])
  49. })
  50. def prep_for_detection(shared_whole_frame_array, shared_frame_time, frame_lock, frame_ready,
  51. motion_detected, frame_shape, region_size, region_x_offset, region_y_offset,
  52. prepped_frame_array, prepped_frame_time, prepped_frame_ready, prepped_frame_lock,
  53. prepped_frame_box):
  54. # shape shared input array into frame for processing
  55. shared_whole_frame = tonumpyarray(shared_whole_frame_array).reshape(frame_shape)
  56. shared_prepped_frame = tonumpyarray(prepped_frame_array).reshape((1,300,300,3))
  57. frame_time = 0.0
  58. while True:
  59. now = datetime.datetime.now().timestamp()
  60. # wait until motion is detected
  61. motion_detected.wait()
  62. with frame_ready:
  63. # if there isnt a frame ready for processing or it is old, wait for a new frame
  64. if shared_frame_time.value == frame_time or (now - shared_frame_time.value) > 0.5:
  65. print("waiting...")
  66. frame_ready.wait()
  67. # make a copy of the cropped frame
  68. with frame_lock:
  69. cropped_frame = shared_whole_frame[region_y_offset:region_y_offset+region_size, region_x_offset:region_x_offset+region_size].copy()
  70. frame_time = shared_frame_time.value
  71. print("grabbed frame " + str(frame_time))
  72. # convert to RGB
  73. cropped_frame_rgb = cv2.cvtColor(cropped_frame, cv2.COLOR_BGR2RGB)
  74. # Resize to 300x300 if needed
  75. if cropped_frame_rgb.shape != (300, 300, 3):
  76. cropped_frame_rgb = cv2.resize(cropped_frame_rgb, dsize=(300, 300), interpolation=cv2.INTER_LINEAR)
  77. # Expand dimensions since the model expects images to have shape: [1, 300, 300, 3]
  78. frame_expanded = np.expand_dims(cropped_frame_rgb, axis=0)
  79. # copy the prepped frame to the shared output array
  80. with prepped_frame_lock:
  81. shared_prepped_frame[:] = frame_expanded
  82. prepped_frame_time = frame_time
  83. prepped_frame_box[:] = [region_x_offset, region_y_offset, region_x_offset+region_size, region_y_offset+region_size]
  84. # signal that a prepped frame is ready
  85. with prepped_frame_ready:
  86. prepped_frame_ready.notify_all()