【ROS2】使用摄像头功能包 usb_cam

1、准备工作

因为本人使用VirtualBox虚拟机运行的ROS2,所以首先要让摄像头可以在虚拟机中运行

1.1 安装VirtualBox扩展包

1)下载地址:https://www.virtualbox.org/wiki/Downloads,注意扩展包的版本要和虚拟机的版本匹配

在这里插入图片描述
2)安装
打开虚拟机 ——》工具 ——》扩展 ——》安装

在这里插入图片描述
3)安装成功

在这里插入图片描述

1.2 在虚拟机中添加摄像头

在这里插入图片描述

1.3 测试摄像头

1)查看摄像头节点

~$ ls /dev/video* 
/dev/video0  /dev/video1

2)使用ffplay测试

ffplay /dev/video0

在这里插入图片描述

2、安装usb_cam

安装命令如下,注意本人的Ubuntu版本是22.04,对应ROS2版本为humble

sudo apt install ros-humble-usb-cam

在这里插入图片描述

3、命令测试

1)启动摄像头及显示

~$ ros2 launch usb_cam demo_launch.py
[INFO] [launch]: All log files can be found below /home/laoer/.ros/log/2023-06-09-10-03-47-100527-laoer-VirtualBox-8264
[INFO] [launch]: Default logging verbosity is set to INFO
/opt/ros/humble/share/usb_cam/config/params.yaml
……

从打印信息可以看出,摄像头相关参数的配置文件路径:/opt/ros/humble/share/usb_cam/config/params.yaml

2)只启动摄像头节点

ros2 run usb_cam usb_cam_node_exe --ros-args --params-file /opt/ros/humble/share/usb_cam/config/params.yaml

3)使用rqt_image_view显示图像
下载,注意版本,本人的ROS2版本为humble

sudo apt install ros-humble-rqt-image-view

在这里插入图片描述

4、编程测试

4.1 python编程测试

1)进入功能包源码目录(根据自己的环境创建)

cd ~/ros/eg/src/py

2)创建功能包

ros2 pkg create --build-type ament_python camera

3)编辑源码

cd camera
vi topic_camera_sub.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import rclpy                            # ROS2 Python接口库
from rclpy.node import Node             # ROS2 节点类
from sensor_msgs.msg import Image       # 图像消息类型
from cv_bridge import CvBridge          # ROS与OpenCV图像转换类
import cv2                              # Opencv图像处理库

class ImageSubscriber(Node):
    def __init__(self, name):
        super().__init__(name)                                  # ROS2节点父类初始化
        self.sub = self.create_subscription(
            Image, 'image_raw', self.listener_callback, 10)     # 创建订阅者对象(消息类型、话题名、订阅者回调函数、队列长度)
    self.cv_bridge = CvBridge()                             # 创建一个图像转换对象,用于OpenCV图像与ROS的图像消息的互相转换

def show(self, image):
    cv2.imshow("camera", image)                             # 使用OpenCV显示图像效果
    cv2.waitKey(10)

def listener_callback(self, data):
    self.get_logger().info('Receiving video frame')         # 输出日志信息,提示已进入回调函数
    image = self.cv_bridge.imgmsg_to_cv2(data, 'bgr8')      # 将ROS的图像消息转化成OpenCV图像
    self.show(image)                               

def main(args=None):                                        # ROS2节点主入口main函数
    rclpy.init(args=args)                                   # ROS2 Python接口初始化
    node = ImageSubscriber("topic_webcam_sub")              # 创建ROS2节点对象并进行初始化
    rclpy.spin(node)                                        # 循环等待ROS2退出
    node.destroy_node()                                     # 销毁节点对象
    rclpy.shutdown()                                        # 关闭ROS2 Python接口

4)修改配置
修改setup.py,添加入口
在entry_points中添加

'topic_camera_sub= camera.topic_camera_sub:main',

完整的setup.py如下

~/ros/eg/src/py/camera$ cat setup.py 
from setuptools import setup
package_name = 'camera'
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']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='laoer',
    maintainer_email='laoer@todo.todo',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
		'topic_camera_sub= camera.topic_camera_sub:main',
        ],
    },
)

5)编译
注意:在项目根目录中编译

cd ~/ros/eg
colcon build

6)运行
在终端1中启动摄像头

ros2 run usb_cam usb_cam_node_exe --ros-args --params-file /opt/ros/humble/share/usb_cam/config/params.yaml

在终端2中启动测试程序

cd ~/ros/eg
source install/setup.sh
ros2 run camera topic_camera_sub

4.2 c++编程测试

1)进入功能包源码目录(根据自己的环境创建)

cd ~/ros/eg/src/cpp

2)创建功能包

ros2 pkg create --build-type ament_cmake cpp_camera  --dependencies rclcpp OpenCV sensor_msgs cv_bridge

3)编辑源码

cd cpp_camera/src
vi camera_sub.cpp
#include <memory>
#include <opencv2/opencv.hpp>

#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"
#include "cv_bridge/cv_bridge.h"

// std::bind占位符引用
using std::placeholders::_1;

class CameraSub : public rclcpp::Node
{
  public:
    CameraSub()
    : Node("cpp_camera_subscriber")
    {
      # a) 初始化订阅者,使用消息类型Image、主题名称image_raw */
      subscription_ = this->create_subscription<sensor_msgs::msg::Image>(
      "image_raw", 10, std::bind(&CameraSub::topic_callback, this, _1));
    }

  private:
    void topic_callback(const sensor_msgs::msg::Image & img) const
    {
      RCLCPP_INFO(this->get_logger(), "Receiving video frame");
      # b)cv_bridge::toCvCopy:Image 话题消息转 opencv 的 cv::Mat
      cv::imshow("camera", cv_bridge::toCvCopy(img, sensor_msgs::image_encodings::BGR8).get()->image);
      cv::waitKey(10);
    }

    rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr subscription_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);

  // 创建并运行
  rclcpp::spin(std::make_shared<CameraSub>());

  rclcpp::shutdown();
  return 0;
}

4)配置
修改CMakeLists.txt
添加引用

find_package(rclcpp REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(OpenCV REQUIRED)
find_package(cv_bridge REQUIRED)

生成可执行文件(使用对应的源码文件和依赖)

add_executable(camera_sub src/camera_sub.cpp)
ament_target_dependencies(camera_sub rclcpp sensor_msgs OpenCV cv_bridge)

添加安装规则

install(TARGETS
  camera_sub  
  DESTINATION lib/${PROJECT_NAME})

完整CM艾克List.txt如下

cmake_minimum_required(VERSION 3.8)
project(cpp_camera)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

find_package(ament_cmake REQUIRED)

find_package(rclcpp REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(OpenCV REQUIRED)
find_package(cv_bridge REQUIRED)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  set(ament_cmake_copyright_FOUND TRUE)
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

add_executable(camera_sub src/camera_sub.cpp)
ament_target_dependencies(camera_sub rclcpp sensor_msgs OpenCV cv_bridge)

install(TARGETS
  camera_sub  
  DESTINATION lib/${PROJECT_NAME})

ament_package()

修改package.xml,添加依赖

  <depend>rclcpp</depend>
  <depend>OpenCV</depend>
  <depend>sensor_msgs</depend>
  <depend>cv_bridge</depend>

5)编译
注意:在项目根目录中编译

cd ~/ros/eg
colcon build

6)运行
在终端1中启动摄像头

ros2 run usb_cam usb_cam_node_exe --ros-args --params-file /opt/ros/humble/share/usb_cam/config/params.yaml

在终端2中启动测试程序

cd ~/ros/eg
source install/setup.sh
ros2 run cpp_camera camera_sub

5、话题消息

5.1 原始未压缩图像 ImageRaw

1)python数据描述
class Image_

    _fields_and_field_types = {
        'header': 	'std_msgs/Header',	// 话题消息队列头
        'height': 	'uint32',			// 图像高(单位像素)
        'width': 	'uint32',			// 图像宽(单位像素)
        'encoding':	'string',			// 像素格式,如“bgr8”
        'is_bigendian': 'uint8',		// 数据大小端字节序
        'step': 	'uint32',			// 步长(图像宽,单位字节)
        'data': 	'sequence<uint8>',	// 图像数据
    }

2)C++中的描述
C++中encoding(像素格式)定义在名字空间 sensor_msgs::image_encodings 中,如:

namespace sensor_msgs
{
namespace image_encodings
{
	const char RGB8[] = "rgb8";
	const char RGBA8[] = "rgba8";
	const char RGB16[] = "rgb16";
	……

sensor_msgs::msg::Image_

this->header 	= const std_msgs::msg::Header_……
this->height 	= 0ul;
this->width 	= 0ul;
this->encoding 	= "";
this->is_bigendian = 0;
this->step 		= 0ul;
this->data 		= std::vector<uint8_t……

5.2 压缩图像 CompressedImage

压缩格式支持:jpeg、png、tiff
1)python

_fields_and_field_types = {
    'header': 'std_msgs/Header',
    'format': 'string',
    'data': 'sequence<uint8>',
}

2)C++

this->header	= const std_msgs::msg::Header_……
this->format	= ""; // 可选值:jpeg、png、tiff
this->data		= std::vector<uint8_t……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/27138.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于STM32F103C8T6的超声波测距——串口输出

文章目录 前言一、超声波模块介绍1、产品特点2、超声波模块的时序图 二、STM32CubeMx创建工程1、配置项目2、keil代码设置3、效果 三、总结四、参考资料 前言 环境&#xff1a; 1、硬件&#xff1a;stm32f103c8t6 核心板 2、软件&#xff1a;STM32CubeMX 6.4.0 3、软件&#xf…

世界研发管理组织在美国成立,中国籍研发管理专家江新安当选总干事

World R&D Management Organization世界研发管理组织&#xff08;WRDMO&#xff09;由来自世界各地的研发管理研究组织&#xff0c;创新技术研究机构&#xff0c;院校以及研发管理咨询机构联合发起。是一个具有开放性&#xff0c;无党派性&#xff0c;非营利性的国际先进研…

第七章 Electron Vue3实现音乐播放器

一、介绍 &#x1f351; &#x1f351; &#x1f351; 一个音乐播放器应该具备播放、暂停、上一首、下一首、播放模式&#xff08;单曲循环、列表循环、顺序播放……&#xff09;。除了这些比如还可以扩展进度条的展示、拖拽、音量大小的调节&#xff0c;如果资源允许的话可以…

企业工程项目管理系统源码-全面的工程项目管理

​ ​工程项目管理系统是指从事工程项目管理的企业&#xff08;以下简称工程项目管理企业&#xff09;受业主委托&#xff0c;按照合同约定&#xff0c;代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 如今建筑行业竞争激烈&#xff0c;内卷严重&#xff0c…

chatgpt赋能python:Python循环间隔-了解如何在循环中增加延时

Python循环间隔 - 了解如何在循环中增加延时 在Python编程中&#xff0c;循环是非常常见且重要的控制语句。 它使我们可以多次执行代码块。 但是&#xff0c;在有些情况下&#xff0c;您可能需要在循环之间增加一定的延时时间。 这就是Python循环间隔的概念。 在本文中&#x…

Linux系统下SQLite创建数据库, 建表, 插入数据保姆级教程

1,创建数据库: sqlite test.db 我这边是sqlite2版本, 直接使用命令sqlite test.db创建一个名称为test的数据库; test是你自定义是数据库名, 创建好数据库后, 接下来开始创建表格 2.创建表格, 就是常规的sql建表语句 CREATE TABLE ids_logs ( english_details TEXT, chines…

嵌入式软件工程师培训:提升技能、实现卓越

如果您对嵌入式培训感兴趣&#xff0c;以下是一些建议和关键点&#xff0c;可以帮助您进行嵌入式培训&#xff1a; 培训目标&#xff1a;明确确定您的嵌入式培训目标。是为了提升员工的技能水平&#xff0c;使他们能够承担更高级别的嵌入式开发工作&#xff0c;还是为了向非嵌入…

iOS App的打包和上架流程

转载&#xff1a;iOS App的打包和上架流程 - 掘金 1. 创建账号 苹果开发者账号几种开发者账号类型 个人开发者账号 费用&#xff1a;99 美元/年&#xff08;688.00元&#xff09;协作人数&#xff1a;仅限开发者自己不需要填写公司的邓百氏编码&#xff08; D-U-N-S Number…

网络安全:信息收集专总结【社会工程学】

前言 俗话说“渗透的本质也就是信息收集”&#xff0c;信息收集的深度&#xff0c;直接关系到渗透测试的成败&#xff0c;打好信息收集这一基础可以让测试者选择合适和准确的渗透测试攻击方式&#xff0c;缩短渗透测试的时间。 一、思维导图 二、GoogleHacking 1、介绍 利用…

大数据需要学习哪些内容?

大数据技术的体系庞大且复杂&#xff0c;每年都会涌现出大量新的技术&#xff0c;目前大数据行业所涉及到的核心技术主要就是&#xff1a;数据采集、数据存储、数据清洗、数据查询分析和数据可视化。 Python 已成利器 在大数据领域中大放异彩 Python&#xff0c;成为职场人追求…

甘孜州文化旅游产品市场营销策略研究_kaic

甘孜州文化旅游产品市场营销策略研究 摘要&#xff1a; 近年来&#xff0c;随着文化旅游的兴起&#xff0c;越来越多的旅游者渴望精神层面的满足&#xff0c;获得新奇的文化体验&#xff0c;而我国文化旅游仍处于单层次的观赏旅游。本文研究背景包括对旅游行业的背景介绍&#…

【第三章:链路层】

目录 知识框架No.0 引言No.1 功能零、基本功能概念一、封装成帧1、字符计数法2、字符填充法3、零比特填充法4、违规编码法 二、透明传输三、差错控制1、位错1.1、奇偶校验码1.2、循环冗余码CRC2、帧错2.1、海明码 四、流量控制1、停止-等待协议2、滑动窗口协议2.1、后退N帧协议…

【新星计划回顾】第五篇学习计划-数据库开启定时任务知识点

&#x1f3c6;&#x1f3c6;时间过的真快&#xff0c;这是导师回顾新星计划学习的第五篇文章&#xff01;本篇文章主要是承接上一篇学习计划&#xff0c;通过开启定时任务进行模拟生成数据&#xff0c;实际开发项目中&#xff0c;可能会用到其他方式&#xff01; 最近这段时间非…

Dockerfile应用的容器化

文章目录 Dockerfile应用的容器化应用的容器化——简介应用的容器化——详解单体应用容器化获取应用代码分析Dockerfile容器化当前应用/构建具体的镜像推送镜像到仓库运行应用程序测试总结 最佳实践利用构建缓存合并镜像 命令总结 Dockerfile应用的容器化 Docker 的核心思想是…

软件测试之路已不再是坦途

去年下半年才跳了槽&#xff0c;过程非常顺利&#xff0c;没有经历大家所说的工作荒的境地&#xff0c;所以一直没有直观地感受到软件测试就业形势到底有多严峻。 近来看到一些机构频频发出某某测试员在糟糕的就业形势下逆袭拿下XXW的某厂offer&#xff0c;然后推荐测试进阶课…

【PCIE体系结构十三】LTSSM

&#x1f449;个人主页&#xff1a;highman110 &#x1f449;作者简介&#xff1a;一名硬件工程师&#xff0c;持续学习&#xff0c;不断记录&#xff0c;保持思考&#xff0c;输出干货内容 参考书籍&#xff1a;《PCI.EXPRESS系统体系结构标准教材 Mindshare》 目录 概览…

【数据恢复、安全和备份解决方案】上海道宁与LSoft为企业提供先进的技术来处理现代数据安全和保存问题

需要备份和恢复磁盘、 恢复已删除的文档和照片、 安全擦除磁盘、 监控硬盘健康状况、 甚至在Windows 无法正常启动时修复 PC&#xff1f; Active Data Studio是 一组桌面应用程序 和可引导CD/DVD或USB磁盘 用于将任何系统引导至 Windows恢复环境 开发商介绍 LSoft Te…

Anaconda教程,Python版本控制

Anaconda教程,Python版本控制 文章目录 Anaconda教程,Python版本控制1&#xff1a;Anaconda安装1.1&#xff1a;Windows1.2&#xff1a;Linux1.3&#xff1a;MacOS 2&#xff1a;Anaconda使用2.1&#xff1a;创建一个新的环境2.2&#xff1a;安装 Python 包2.3&#xff1a;激活…

HNU-操作系统OS-作业2(15-22章)

OS_homework_2 这份文件是OS_homework_2 by计科210X wolf 202108010XXX 文档设置了目录,可以通过目录快速跳转至答案部分。 第15章 运行程序OS-homework/vm-mechanism/relocation.py 15.1 用种子 1、2 和 3 运行,并计算进程生成的每个虚拟地址是处于界限内还是界限外? 如…

信创办公–基于WPS的EXCEL最佳实践系列 (创建表格)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;创建表格&#xff09; 目录 应用背景操作步骤1、新建空白工作簿并命名为“奖牌榜”2、使用模板新建工作簿3、新增一张工作表&#xff0c;并将工作簿的标签更改为红色4、复制与隐藏工作表5、添加工作簿属性值6、更改工作簿主题…