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.