Solution-Proposal for Camera/Image-Display (Backend)
This article describes a proposal for connecting an USB camera to the ros2. There are two ways to connect an USB camera to the ros2 topic and publish the footage.
1-Predefined ROS2 Package
The first way is to use a predefined ros2 package that automatically accesses the camera and creates a ros2 topic.
The most popular packages are usb_cam and v4l2_camera. If you act this way, you don't have to write any code because packages contain everything you need. You can control the size of the transmitted footage by only passing the corresponding parameters.
The usb_cam and v4l2_camera also provide image compression if one wants to have compressed images.
2- Custom Node
The second way is to create a package and write a custom node that connects to the camera and publishes the footage via the ros2 topic.
Here is an example of a custom node written in python:
import cv2
from cv_bridge import CvBridge
from sensor_msgs.msg import Image
import rclpy
from rclpy.node import Node
class CameraPublisher(Node):
def __init__(self):
super().__init__('camera_publisher')
self.publisher_ = self.create_publisher(Image, '/my_camera/image_raw', 10)
self.timer_ = self.create_timer(0.1, self.publish_image)
self.bridge_ = CvBridge()
self.cap_ = cv2.VideoCapture(0)
def publish_image(self):
ret, frame = self.cap_.read()
if ret:
img_msg = self.bridge_.cv2_to_imgmsg(frame, encoding="passthrough")
self.publisher_.publish(img_msg)
def main(args=None):
rclpy.init(args=args)
camera_publisher = CameraPublisher()
rclpy.spin(camera_publisher)
camera_publisher.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Â
Let's go through the python code:
1 - Import the necessary packages: cv2
for working with the camera, CvBridge
for converting images between OpenCV and ROS2 message formats, Image
for the image message, rclpy
for ROS2 Python programming, and Node
for creating a ROS2 node.
2 - Create a CameraPublisher class that inherits from the Node class. In the init()
constructor the node named camera_publisher
is initialized. A publisher object self.publisher_
publishes image messages on the /my_camera/image_raw topic. 10 is the queue size for the publisher.
The self.timer_
timer calls the self.publish_image
function every 0.1 seconds. The self.bridge_
object converts images between OpenCV and ROS2 message formats. Finally, the self.cap_
object is initialized to capture video from the default camera device.
3 - The publish_image
function is called by the timer. It reads a frame from the camera using self.cap_.read()
method. If the frame is successfully read (ret == True), the image is converted to a ROS2 message using self.bridge_.cv2_to_imgmsg(frame, encoding="passthrough")
. Then the message is published on the /my_camera/image_raw topic using the self.publisher_.publish(img_msg)
method.
4 - Finally, the main
function initializes the ROS2 node with rclpy.init()
, creates a CameraPublisher object, spins the node with rclpy.spin()
, and finally shuts down the node with camera_publisher.destroy_node()
and rclpy.shutdown()
.
This Python code continuously captures camera footage and publishes it on the /my_camera/image_raw topic in a ROS2-compatible format. It allows other ROS2 nodes to subscribe to this topic and receive the camera footage.