visualizer.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #!/usr/bin/python
  2. # Copyright (c) 2021 Intel Corporation
  3. #
  4. # This work is licensed under the terms of the MIT license.
  5. # For a copy, see <https://opensource.org/licenses/MIT>.
  6. """
  7. This module provides an OpenCV based visualizer for camera sensors
  8. attached to an actor.
  9. The modul can for example be used inside an OSC Actor controller,
  10. such as simple_vehicle_control.py
  11. It can also be used as blueprint to implement custom visualizers.
  12. """
  13. import cv2
  14. import numpy as np
  15. import carla
  16. from srunner.scenariomanager.carla_data_provider import CarlaDataProvider
  17. class Visualizer(object):
  18. """
  19. Visualizer class for actor controllers.
  20. The class provides a birdeye camera and a camera mounted in the front
  21. bumper of the actor. The resolution is 1000x400 for both RGB cameras.
  22. To use this class, it is only required to:
  23. 1. Add an instance inside the controller constructor
  24. visualizer = Visualizer(actor)
  25. 2. Call the render method on a regular basis
  26. visualizer.render()
  27. 3. Call the reset method during cleanup
  28. visualizer.reset()
  29. Args:
  30. actor (carla.Actor): Vehicle actor the cameras should be attached to.
  31. Attributes:
  32. _actor (carla.Actor): The reference actor
  33. _cv_image_bird (numpy array): OpenCV image for the birdeye camera
  34. _cv_image_actor (numpy array): OpenCV image for the bumper camera
  35. _camera_bird (carla.Camera): Birdeye camera
  36. _camera_actor (carla.Camera): Bumper camera
  37. _video_writer (boolean): Flag to disable/enable writing the image stream into a video
  38. """
  39. _video_writer = False
  40. def __init__(self, actor):
  41. self._actor = actor
  42. self._cv_image_bird = None
  43. self._cv_image_actor = None
  44. self._camera_bird = None
  45. self._camera_actor = None
  46. bp = CarlaDataProvider.get_world().get_blueprint_library().find('sensor.camera.rgb')
  47. bp.set_attribute('image_size_x', '1000')
  48. bp.set_attribute('image_size_y', '400')
  49. self._camera_bird = CarlaDataProvider.get_world().spawn_actor(bp, carla.Transform(
  50. carla.Location(x=20.0, z=50.0), carla.Rotation(pitch=-90, yaw=-90)), attach_to=self._actor)
  51. self._camera_bird.listen(lambda image: self._on_camera_update(
  52. image, birdseye=True)) # pylint: disable=unnecessary-lambda
  53. bp = CarlaDataProvider.get_world().get_blueprint_library().find('sensor.camera.rgb')
  54. bp.set_attribute('image_size_x', '1000')
  55. bp.set_attribute('image_size_y', '400')
  56. self._camera_actor = CarlaDataProvider.get_world().spawn_actor(bp, carla.Transform(
  57. carla.Location(x=2.3, z=1.0)), attach_to=self._actor)
  58. self._camera_actor.listen(lambda image: self._on_camera_update(
  59. image, birdseye=False)) # pylint: disable=unnecessary-lambda
  60. if self._video_writer:
  61. fourcc = cv2.VideoWriter_fourcc(*'mp4v')
  62. self._video = cv2.VideoWriter('recorded_video.avi', fourcc, 13, (1000, 800))
  63. def reset(self):
  64. """
  65. Reset cameras
  66. """
  67. if self._camera_bird:
  68. self._camera_bird.destroy()
  69. self._camera_bird = None
  70. if self._camera_actor:
  71. self._camera_actor.destroy()
  72. self._camera_actor = None
  73. def _on_camera_update(self, image, birdseye):
  74. """
  75. Callback for the camera sensor
  76. Sets the OpenCV image (_cv_image). Requires conversion from BGRA to RGB.
  77. """
  78. if not image:
  79. return
  80. image_data = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
  81. np_image = np.reshape(image_data, (image.height, image.width, 4))
  82. np_image = np_image[:, :, :3]
  83. np_image = np_image[:, :, ::-1]
  84. if not birdseye:
  85. self._cv_image_actor = cv2.cvtColor(np_image, cv2.COLOR_BGR2RGB)
  86. else:
  87. self._cv_image_bird = cv2.cvtColor(np_image, cv2.COLOR_BGR2RGB)
  88. def render(self):
  89. """
  90. Render images in an OpenCV window (has to be called on a regular basis)
  91. """
  92. if self._cv_image_actor is not None and self._cv_image_bird is not None:
  93. im_v = cv2.vconcat([self._cv_image_actor, self._cv_image_bird])
  94. cv2.circle(im_v, (900, 300), 80, (170, 170, 170), -1)
  95. text = str(int(round((self._actor.get_velocity().x * 3.6))))+" kph"
  96. speed = np.sqrt(self._actor.get_velocity().x**2 + self._actor.get_velocity().y**2)
  97. text = str(int(round((speed * 3.6))))+" kph"
  98. text = ' '*(7-len(text)) + text
  99. im_v = cv2.putText(im_v, text, (830, 310), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2, cv2.LINE_AA)
  100. cv2.imshow("", im_v)
  101. cv2.waitKey(1)
  102. if self._video_writer:
  103. self._video.write(im_v)