You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

plot.py 3.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import os
  4. import cv2
  5. import numpy as np
  6. import pyarrow as pa
  7. from dora import DoraStatus
  8. from utils import LABELS
  9. pa.array([])
  10. CI = os.environ.get("CI")
  11. CAMERA_WIDTH = 640
  12. CAMERA_HEIGHT = 480
  13. font = cv2.FONT_HERSHEY_SIMPLEX
  14. class Operator:
  15. """
  16. Plot image and bounding box
  17. """
  18. def __init__(self):
  19. self.image = []
  20. self.bboxs = []
  21. self.bounding_box_messages = 0
  22. self.image_messages = 0
  23. self.object_detection_stdout = []
  24. def on_event(
  25. self,
  26. dora_event,
  27. send_output,
  28. ) -> DoraStatus:
  29. if dora_event["type"] == "INPUT":
  30. return self.on_input(dora_event, send_output)
  31. return DoraStatus.CONTINUE
  32. def on_input(
  33. self,
  34. dora_input,
  35. send_output,
  36. ) -> DoraStatus:
  37. """
  38. Put image and bounding box on cv2 window.
  39. Args:
  40. dora_input["id"] (str): Id of the dora_input declared in the yaml configuration
  41. dora_input["value"] (arrow array): message of the dora_input
  42. send_output Callable[[str, bytes | pa.Array, Optional[dict]], None]:
  43. Function for sending output to the dataflow:
  44. - First argument is the `output_id`
  45. - Second argument is the data as either bytes or `pa.Array`
  46. - Third argument is dora metadata dict
  47. e.g.: `send_output("bbox", pa.array([100], type=pa.uint8()), dora_event["metadata"])`
  48. """
  49. if dora_input["id"] == "image":
  50. frame = (
  51. dora_input["value"]
  52. .to_numpy()
  53. .reshape((CAMERA_HEIGHT, CAMERA_WIDTH, 3))
  54. .copy() # copy the image because we want to modify it below
  55. )
  56. self.image = frame
  57. self.image_messages += 1
  58. print("received " + str(self.image_messages) + " images")
  59. elif dora_input["id"] == "object_detection_stdout":
  60. stdout = dora_input["value"][0].as_py()
  61. self.object_detection_stdout += [stdout]
  62. ## Only keep last 10 stdout
  63. self.object_detection_stdout = self.object_detection_stdout[-10:]
  64. return DoraStatus.CONTINUE
  65. elif dora_input["id"] == "bbox" and len(self.image) != 0:
  66. bboxs = dora_input["value"].to_numpy()
  67. self.bboxs = np.reshape(bboxs, (-1, 6))
  68. self.bounding_box_messages += 1
  69. print("received " + str(self.bounding_box_messages) + " bounding boxes")
  70. return DoraStatus.CONTINUE
  71. else:
  72. return DoraStatus.CONTINUE
  73. for bbox in self.bboxs:
  74. [
  75. min_x,
  76. min_y,
  77. max_x,
  78. max_y,
  79. confidence,
  80. label,
  81. ] = bbox
  82. cv2.rectangle(
  83. self.image,
  84. (int(min_x), int(min_y)),
  85. (int(max_x), int(max_y)),
  86. (0, 255, 0),
  87. 2,
  88. )
  89. cv2.putText(
  90. self.image,
  91. LABELS[int(label)] + f", {confidence:0.2f}",
  92. (int(max_x), int(max_y)),
  93. font,
  94. 0.75,
  95. (0, 255, 0),
  96. 2,
  97. 1,
  98. )
  99. for i, log in enumerate(self.object_detection_stdout):
  100. cv2.putText(
  101. self.image,
  102. log,
  103. (10, 10 + 20 * i),
  104. font,
  105. 0.5,
  106. (0, 255, 0),
  107. 2,
  108. 1,
  109. )
  110. if CI != "true":
  111. cv2.imshow("frame", self.image)
  112. if cv2.waitKey(1) & 0xFF == ord("q"):
  113. return DoraStatus.STOP
  114. return DoraStatus.CONTINUE
  115. def __del__(self):
  116. cv2.destroyAllWindows()