ROS2 视频采集节点实现
一个完整的ROS2视频采集节点的实现,使用OpenCV进行视频捕获并通过ROS2发布图像消息。
1. 创建功能包
首先创建一个新的ROS2功能包(如果还没有):
bash
ros2 pkg create video_capture --build-type ament_python --dependencies rclpy sensor_msgs cv_bridge opencv-python
2. 实现视频采集节点
在video_capture/video_capture
目录下创建video_capture_node.py
文件:
python
#!/usr/bin/env python3import rclpy from rclpy.node import Node from sensor_msgs.msg import Image from cv_bridge import CvBridge import cv2class VideoCaptureNode(Node):def __init__(self):super().__init__('video_capture_node')# 声明参数self.declare_parameter('video_source', 0) # 默认使用摄像头0self.declare_parameter('frame_width', 640)self.declare_parameter('frame_height', 480)self.declare_parameter('fps', 30)self.declare_parameter('topic_name', 'video_frames')# 获取参数值video_source = self.get_parameter('video_source').valueframe_width = self.get_parameter('frame_width').valueframe_height = self.get_parameter('frame_height').valuefps = self.get_parameter('fps').valuetopic_name = self.get_parameter('topic_name').value# 初始化视频捕获self.cap = cv2.VideoCapture(video_source)if not self.cap.isOpened():self.get_logger().error(f"Cannot open video source {video_source}")raise RuntimeError(f"Cannot open video source {video_source}")# 设置摄像头参数self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)self.cap.set(cv2.CAP_PROP_FPS, fps)# 初始化CV桥self.bridge = CvBridge()# 创建发布者self.publisher = self.create_publisher(Image, topic_name, 10)# 创建定时器timer_period = 1.0 / fps # 秒self.timer = self.create_timer(timer_period, self.timer_callback)self.get_logger().info(f"Video capture node started. Publishing to '{topic_name}' at {fps} FPS")def timer_callback(self):ret, frame = self.cap.read()if ret:try:# 转换并发布图像消息msg = self.bridge.cv2_to_imgmsg(frame, "bgr8")self.publisher.publish(msg)except Exception as e:self.get_logger().error(f"Error converting frame: {e}")else:self.get_logger().warning("Failed to capture frame")def destroy_node(self):self.cap.release()self.get_logger().info("Video capture released")super().destroy_node()def main(args=None):rclpy.init(args=args)try:node = VideoCaptureNode()rclpy.spin(node)except Exception as e:node.get_logger().error(f"Error in video capture node: {e}")finally:if 'node' in locals():node.destroy_node()rclpy.shutdown()if __name__ == '__main__':main()
3. 添加启动文件
在功能包中创建launch
目录,并添加video_capture.launch.py
文件:
python
from launch import LaunchDescription from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='video_capture',executable='video_capture_node',name='video_capture_node',parameters=[{'video_source': 0},{'frame_width': 640},{'frame_height': 480},{'fps': 30},{'topic_name': 'video_frames'}])])
4. 修改setup.py
确保setup.py
包含正确的入口点:
python
from setuptools import setuppackage_name = 'video_capture'setup(name=package_name,version='0.0.0',packages=[package_name],data_files=[('share/ament_index/resource_index/packages',['resource/' + package_name]),('share/' + package_name, ['package.xml']),('share/' + package_name + '/launch', ['launch/video_capture.launch.py']),],install_requires=['setuptools'],zip_safe=True,maintainer='your_name',maintainer_email='your_email@example.com',description='ROS2 video capture node',license='Apache License 2.0',tests_require=['pytest'],entry_points={'console_scripts': ['video_capture_node = video_capture.video_capture_node:main',],}, )
5. 构建和运行
构建功能包:
bash
colcon build --packages-select video_capture source install/setup.bash
运行节点:
bash
ros2 launch video_capture video_capture.launch.py
或者直接运行:
bash
ros2 run video_capture video_capture_node
6. 参数说明
可以通过以下方式修改参数:
在启动文件中修改
通过命令行参数修改:
bash
ros2 run video_capture video_capture_node --ros-args -p video_source:=0 -p frame_width:=1280 -p frame_height:=720
7. 查看图像
可以使用image_view
节点查看发布的图像:
bash
ros2 run image_tools showimage --ros-args --remap image:=video_frames
注意事项
确保已安装OpenCV和cv_bridge
根据实际摄像头调整
video_source
参数(0通常为默认摄像头)对于视频文件,将
video_source
设置为文件路径节点会自动释放摄像头资源当被关闭时
这个实现提供了基本的视频采集功能,可以根据需要进一步扩展,例如添加图像处理、保存视频等功能。