在ROS中基于颜色做简单的物体识别

本文介绍如何在ROS环境下,利用opencv进行图像处理,实现基于颜色的物体识别。通过cv_bridge将ROS图像数据转换为opencv可用格式,识别桌面和物体,找到目标中心位置。识别过程包括桌面识别、物体识别和目标位置转换,最终将结果发布到相应话题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ROS无法直接进行图像处理,需要借助于opencv,要使用cv_bridge把ROS 的图像数据格式转为Opencv可以使用的数据格式。即是一个提供ROS和OpenCV库提供之间的接口的开发包。然后可以将opencv处理好的图像再转换回ros中的数据格式。

包含的头文件如下:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"

#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <image_transport/image_transport.h>

从主函数开始:

int main(int argc, char** argv ) 
{
    //初始化节点
  	ros::init(argc, argv, "simple_grasping_vision_detection");
    //创建节点句柄
  	ros::NodeHandle n_;

    //输出等待2s..
  	ROS_INFO_STREAM("Waiting for two seconds..");
  	ros::WallDuration(2.0).sleep();

	float length = 0.3;
	float breadth = 0.3;

    //创建一个VisionManager类的对象
	VisionManager vm(n_, length, breadth);

	while (ros::ok())
	{
		// Process image callback
		ros::spinOnce();

		ros::WallDuration(2.0).sleep();
	}
	return 0;
}

首先初始化节点,节点名为simple_grasping_vision_detection,创建一个VisionManager类的对象vm,然后再循环中不断的进行处理。

看一下类的构造函数:

VisionManager::VisionManager(ros::NodeHandle n_, float length, float breadth) : it_(n_)
{
	this->table_length = length;
	this->table_breadth = breadth;

  	// Subscribe to input video feed and publish object location
  	image_sub_  = it_.subscribe("/probot_anno/camera/image_raw", 1, &VisionManager::imageCb, this);
	image1_pub_ = it_.advertise("/table_detect", 1);
	image2_pub_ = it_.advertise("/object_detect", 1);
}

构造函数输入有三个形参,VisionManager::VisionManager(ros::NodeHandle n_, float length, float breadth):

  • ros::NodeHandle n_  是节点句柄;
  • float length    是
  • float breadth  是

然后订阅了摄像头发布信息的话题,image_sub_  = it_.subscribe("/probot_anno/camera/image_raw", 1, &VisionManager::imageCb, this);

发布两个话题,一个是检测到的桌面,image1_pub_ = it_.advertise("/table_detect", 1);另外一个是检测到的物体,image2_pub_ = it_.advertise("/object_detect", 1);

当订阅者接收到图像之后就会进入到回调函数当中:

<think>我们正在处理一个关于ROS2 Foxy中实现颜色锥桶识别的问题。用户希望了解如何在ROS2 Foxy中使用图像处理技术来识别颜色锥桶。 步骤: 1. 理解问题:用户需要在ROS2 Foxy环境下,通过摄像头获取图像,然后通过图像处理识别颜色锥桶(比如橙色或红色的锥桶)。 2. 解决方案概述: - 使用ROS2的图像处理工具,主要是通过OpenCV来处理图像。 - 步骤包括:图像获取、颜色空间转换、颜色阈值分割、形态学操作、轮廓检测和过滤、标记锥桶位置等。 3. 具体步骤: a. 创建一个ROS2节点,订阅摄像头图像话题(例如:/camera/image_raw)。 b. 将ROS2的图像消息(sensor_msgs/msg/Image)转换为OpenCV的图像格式(使用cv_bridge)。 c. 在OpenCV中,将图像从BGR颜色空间转换到HSV颜色空间,因为HSV空间更容易进行颜色分割。 d. 根据锥桶的颜色(例如橙色)设定HSV的阈值范围,通过阈值分割得到二值图像。 e. 对二值图像进行形态学操作(如膨胀和腐蚀)以去除噪声并连接相邻区域。 f. 使用轮廓检测函数找到二值图像中的轮廓。 g. 根据轮廓的面积、宽高比等特征过滤掉非锥桶的轮廓。 h. 在原始图像上绘制锥桶的边界框,并可以计算锥桶在图像中的位置(例如中心坐标)。 i. 将处理后的图像发布到一个新的ROS话题上(可选),或者发布锥桶的位置信息(例如通过自定义消息发布中心坐标)。 4. 代码示例:我们将提供一个简单的节点代码框架。 注意:由于用户使用的是ROS2 Foxy,我们需要确保代码符合Foxy的API。 5. 相关问题:在最后,我们将生成几个相关问题以帮助用户深入理解。 现在,我们开始编写回答。</think>### ROS2 Foxy 颜色锥桶识别实现指南 #### 核心实现步骤 1. **环境配置** - 安装依赖:`sudo apt install ros-foxy-vision-opencv ros-foxy-cv-bridge ros-foxy-image-transport` - 创建功能包:`ros2 pkg create cone_detection --build-type ament_cmake --dependencies rclcpp cv_bridge sensor_msgs image_transport OpenCV` 2. **图像采集节点** ```python # camera_node.py import rclpy from sensor_msgs.msg import Image from cv_bridge import CvBridge import cv2 class CameraNode(Node): def __init__(self): super().__init__('camera_node') self.publisher = self.create_publisher(Image, 'camera/image_raw', 10) self.cap = cv2.VideoCapture(0) # 摄像头设备号 self.bridge = CvBridge() self.timer = self.create_timer(0.1, self.capture_frame) def capture_frame(self): ret, frame = self.cap.read() if ret: msg = self.bridge.cv2_to_imgmsg(frame, "bgr8") self.publisher.publish(msg) ``` 3. **锥桶识别核心算法** ```python # cone_detector.py import cv2 import numpy as np class ConeDetector: def __init__(self): # 橙色锥桶的HSV阈值范围 (需根据实际环境调整) self.lower_orange = np.array([5, 100, 100]) self.upper_orange = np.array([15, 255, 255]) def detect(self, frame): # 颜色空间转换 hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 颜色阈值分割 mask = cv2.inRange(hsv, self.lower_orange, self.upper_orange) # 形态学操作 kernel = np.ones((5,5), np.uint8) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) # 轮廓检测 contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cones = [] for cnt in contours: # 面积过滤 if cv2.contourArea(cnt) < 500: continue # 边界框和中心点 x,y,w,h = cv2.boundingRect(cnt) center_x = x + w//2 center_y = y + h//2 # 宽高比过滤 (锥桶通常高度大于宽度) if h/w < 1.5: continue cones.append((center_x, center_y, w, h)) return mask, cones ``` 4. **ROS2处理节点** ```python # detection_node.py import rclpy from rclpy.node import Node from sensor_msgs.msg import Image from cv_bridge import CvBridge from .cone_detector import ConeDetector class DetectionNode(Node): def __init__(self): super().__init__('detection_node') self.subscription = self.create_subscription( Image, 'camera/image_raw', self.image_callback, 10) self.publisher = self.create_publisher(Image, 'processed_image', 10) self.bridge = CvBridge() self.detector = ConeDetector() def image_callback(self, msg): cv_image = self.bridge.imgmsg_to_cv2(msg, "bgr8") # 锥桶检测 mask, cones = self.detector.detect(cv_image) # 标注检测结果 for (x, y, w, h) in cones: cv2.rectangle(cv_image, (x,y), (x+w,y+h), (0,255,0), 2) cv2.putText(cv_image, "Cone", (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2) # 发布处理后的图像 processed_msg = self.bridge.cv2_to_imgmsg(cv_image, "bgr8") self.publisher.publish(processed_msg) ``` #### 部署与优化 1. **启动系统** ```bash # 终端1:启动摄像头节点 ros2 run cone_detection camera_node # 终端2:启动处理节点 ros2 run cone_detection detection_node # 终端3:查看结果 ros2 run image_view image_view --ros-args -r image:=/processed_image ``` 2. **优化方向** - **动态阈值调整**:使用HSV直方图分析自动调整阈值范围 - **深度学习增强**:集成YOLO等模型提高识别精度[^1] - **多传感器融合**:结合深度相机(LiDAR)获取三维位置 - **光照补偿**:应用CLAHE算法处理光照不均问题 3. **性能提升技巧** - 使用GPU加速:通过CUDA加速OpenCV运算 - 图像降采样:处理前减小图像尺寸 - ROI区域限定:只在感兴趣区域进行处理 - 异步处理:使用`rclcpp::AsyncParametersClient` #### 常见问题解决 1. **颜色识别不稳定** - 解决方案:建立HSV颜色直方图数据库,实现自适应阈值选择 $$ \text{自适应阈值} = f(\mu_H \pm 2\sigma_H, \mu_S \pm 2\sigma_S, \mu_V \pm 2\sigma_V) $$ 2. **误检率过高** - 改进方法: - 增加形状匹配:使用Hu矩特征验证锥桶形状 $$ I_1 = \eta_{20} + \eta_{02} $$ $$ I_2 = (\eta_{20} - \eta_{02})^2 + 4\eta_{11}^2 $$ - 实现多帧验证:仅持续现3帧以上的目标才被确认 3. **实时性不足** - 优化策略: - 启用硬件加速:VPI/Vulkan - 算法复杂度优化:将$O(n^2)$操作降为$O(n\log n)$ - 线程池处理:使用`rclcpp::executors::MultiThreadedExecutor` [^1]: 基于深度学习的物体检测方法在复杂场景中表现
评论 68
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程芝士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值