一起做ROS-DEMO系列 (2):基于find_object_2d的目标模板匹配识别

本文详细介绍ROS中的find_object_2d功能包,包括安装、配置与使用方法。通过模板匹配和机器学习技术,实现目标物体的识别与定位。特别介绍了基于彩色图像的模板匹配过程,以及如何通过调整参数选择最佳算法。

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

  • 接上文,我们希望机器人能够更加智能一点,抓住我们想要的任何东西,而不是通过贴标签(ar_makrer)或者简单的颜色过滤分割(比如固定识别某纯色物体)来进行目标物体的识别。所以我们打算采用其他的方法来进行目标的识别识别。
  • 目前我知道的比较好上手的方法有两种,一是使用模板匹配(包括彩色图像或点云匹配),二是使用最近大热的机器学习来做(比如yolo等,以后会具体介绍)。那么这次我会讲一讲基于彩色图像的模板匹配,因为目前ROS上现有的find_object_2d功能包能够让我们在不需要了解具体实现原理的情况下,快速上手此功能,比较适合任务的迅速部署。
  • 参考资料:
    http://wiki.ros.org/find_object_2d
    https://github.com/introlab/find-object/tree/kinetic-devel
    http://introlab.github.io/find-object/
    fetch


1、find_object_2d 功能包安装

直接悬着对应的ros版本进行安装即可,其他版本安装参见官方说明:https://github.com/introlab/find-object/tree/kinetic-devel

# ROS Kinetic:
 $ sudo apt-get install ros-kinetic-find-object-2d
# ROS Jade:
 $ sudo apt-get install ros-jade-find-object-2d
# ROS Indigo:
 $ sudo apt-get install ros-indigo-find-object-2d
# ROS Hydro:
 $ sudo apt-get install ros-hydro-find-object-2d

2、功能包的可视化使用

该功能包有两个节点find_object_2dfind_object_3d,其中find_object_3d是为kinect之类的深度相机准备的,可以通过在匹配目标后识别目标中心的深度信息输出目标的三维坐标。

2.1 、find_object_2d

find_object_2d
启动过程:

 $ roscore 
 $ 启动你的相机节点,输出图像话题
 $ rosrun find_object_2d find_object_2d image:=image_raw

注意 image:=image_raw,这是个话题重映射,这里的image_raw要修改为你的相机输出的图像话题。

  • launch文件写法:
<launch>
	<!-- Nodes -->
	<node name="find_object_2d" pkg="find_object_2d" type="find_object_2d" output="screen">
		<remap from="image" to="image"/>
		<param name="gui" value="false" type="bool"/>
		<param name="objects_path" value="~/objects" type="str"/>
		<param name="settings_path" value="~/.ros/find_object_2d.ini" type="str"/>
	</node>
</launch
2.2 、find_object_3d

在这里插入图片描述

  • 启动过程:(由于需要调用多个参数,所以这里采用launch文件配置参数,启动节点)

  • 1、启动深度相机,如:

# kinect2
roslaunch kinect2_bridge kinect2_bridge,launch

# realsesnse D414/435
roslaunch realsense2_camera rs_camera.launch
  • 2、启动find_object_3d识别:
<launch>
	<!-- Example finding 3D poses of the objects detected -->
	<!-- $ roslaunch kinect2_bridge kinect2_bridge.launch publish_tf:=true -->

	<!-- Which image resolution: sd, qhd, hd -->
	<arg name="resolution" default="qhd" />
	
	<node name="find_object_3d" pkg="find_object_2d" type="find_object_2d" output="screen">
		<param name="gui" value="true" type="bool"/>
		<param name="settings_path" value="~/.ros/find_object_2d.ini" type="str"/>
		<param name="subscribe_depth" value="true" type="bool"/>
		<param name="objects_path" value="" type="str"/>
		<param name="object_prefix" value="object" type="str"/>
		
		<remap from="rgb/image_rect_color" to="/kinect2/$(arg resolution)/image_color_rect"/>
		<remap from="depth_registered/image_raw" to="/kinect2/$(arg resolution)/image_depth_rect"/>
		<remap from="depth_registered/camera_info" to="/kinect2/$(arg resolution)/camera_info"/>
	</node>
</launch>

3、具体使用

不管是启动2d、3d哪个节点,都会有一个QT的可视化界面。

3.1 调整参数,选择特征算子及算法

可以选择SURF、SIFT、ORB、FAST等一系列算法,观察目标物体上的特征点数量及效果,以及处理的流畅程度,衡量选择合适的算法。通过菜单View - Parameters调出参数栏选项卡进行调整。
如图:
在这里插入图片描述

3.2 选择匹配的对象,进行匹配

在左侧栏右键选择添加新的目标,通过框选方式选择目标。
在这里插入图片描述
之后就可以看到目标物体被成功框选了。

3.3 查阅相关的话题
3.3.1 节点接收的话题
//find_object_2d节点使用
topic:image (message_type: sensor_msgs/Image) 
//find_object_3d节点使用
topic:rgb/image_rect_color (message_type: sensor_msgs/Image) //对齐后的彩色图像

topic:rgb/camera_info (message_type: sensor_msgs/CameraInfo) //相机标定信息

topic:registered_depth/image_raw (message_type: sensor_msgs/Image)//深度图像
3.3.2 节点发布的话题
topic:objects (message_type: std_msgs/Float32MultiArray)
//话题内容按照以下方式排列 [objectId1, objectWidth, objectHeight, h11, h12, h13, h21, h22, h23, h31, h32, h33, objectId2...] 
 //hxx 是 3x3 矩阵 (h31 = dx and h32 = dy, see QTransform)

topic:objectsStamped (message_type: find_object_2d/ObjectsStamped)
//带标签的对象物体
  • 注意:此外如果我们是使用find_object_3d,可以打开rviz可视化工具,看到目标的TF坐标已经被发出来了(这里需要正确的配置相机的TF坐标系)。
  • 话题 /objects 的h矩阵并不利于理解,这里官方还提供了另外一个节点供我们借鉴:
    rosrun find_object_2d print_objects_detected image:=/camera/color/image_raw
  • 观察该节点代码可以看到此节点会处理h矩阵,输出目标id及边框的坐标。源码看这里
此节点的输出:
Object 3 detected, Qt corners at (786.949707,-11.180605) (1497.147252,-69.618191) (813.221906,428.768064) (1425.264906,463.355441)
printf("Object %d detected, Qt corners at (%f,%f) (%f,%f) (%f,%f) (%f,%f)\n",
					id,
					qtTopLeft.x(), qtTopLeft.y(),
					qtTopRight.x(), qtTopRight.y(),
					qtBottomLeft.x(), qtBottomLeft.y(),
					qtBottomRight.x(), qtBottomRight.y());

此外此节点还发布了目标中心坐标的图像,可以通过rqt_image_view查看 /image_with_objects
在这里插入图片描述

3.3 保存匹配的模板及配置文件

点击左上角的File,保存匹配模板及配置,并放置到自己对应的目录下,如我都存到config文件夹下,使用launch文件正确的读取他们。

<launch>
	<!-- My finding 3D poses of the objects detected -->
	<node name="find_object_3d" pkg="find_object_2d" type="find_object_2d" output="screen">
		<param name="gui" value="true" type="bool"/>

		<param name="settings_path" value="~/dhrobot_ws/src/dhrobot_demo/config/find_object_2d.ini" type="str"/>
		<param name="subscribe_depth" value="true" type="bool"/>
		<param name="objects_path" value="~/dhrobot_ws/src/dhrobot_demo/config" type="str"/>
		<param name="object_prefix" value="object" type="str"/>

		<remap from="rgb/image_rect_color" to="/camera/color/image_raw"/>
		<remap from="depth_registered/image_raw" to="/camera/depth/image_rect_raw"/>
		<remap from="depth_registered/camera_info" to="/camera/depth/camera_info"/>
	</node>
</launch>

4、将识别的坐标点发送给机械臂

在使用find_object_3d时,我们可以直接获得目标物体的tf坐标,因此可以使用ros自带的tf转换直接查询机械臂基座标到物体的tf关系,并发送给机械臂:
参考这里:http://docs.ros.org/lunar/api/tf/html/c++/classtf_1_1TransformListener.html
http://wiki.ros.org/tf/Tutorials/Writing%20a%20tf%20listener%20%28C%2B%2B%29

tf::StampedTransform transform;
  25     try{
  26       listener.lookupTransform("/arm_base_link", "/object_1",  
  27                                ros::Time(0), transform);
  28     }
  29     catch (tf::TransformException ex){
  30       ROS_ERROR("%s",ex.what());
  31       ros::Duration(1.0).sleep();
  32     }
  33 

5、功能包效果评价

  • 整体来说这个功能包安装是相当方便的,不过因为是模板匹配,所以局限性比较大,在目标物体未正对摄像头的情况下识别成功率不高,而且想要得到良好的匹配效果需要认真的调节参数,旋转合适的算法,另外输出的tf中心点坐标大致准确,但是姿态就不是很靠谱了。
<think>好的,我现在需要解决用户关于ROSfind_object_2d包实现物体识别的原理和方程式的问题。首先,我需要回忆一下这个包的基本信息。find_object_2d是基于OpenCV的,主要用于二维物体识别,适用于机器人应用。 用户提到需要了解具体方法或方程式,所以我要深入其核心算法。可能涉及特征提取,比如SIFT、SURF或ORB。这些算法都有数学基础,比如SIFT使用高斯差分金字塔进行关键点检测,SURF使用积分图像加速Hessian矩阵计算,ORB则结合FAST关键点和BRIEF描述子。 接下来是特征匹配,常用的有FLANN或暴力匹配。需要解释匹配过程的数学方法,比如最近邻距离比(NNDR)来筛选匹配点。公式可能是$d_{ratio} = \frac{d_1}{d_2}$,其中$d_1$和$d_2分别是最接近和次接近的特征距离。 然后是几何验证,比如使用RANSAC估计单应性矩阵。单应性矩阵H满足$\mathbf{x'} = H \mathbf{x}$,通过最小化重投影误差来优化。这部分需要详细说明RANSAC的步骤和数学原理。 另外,用户之前的引用提到了欧几里得距离和线性模型,虽然这些可能不直接相关,但或许在物体定位或运动控制中有应用。比如在计算物体位置时可能用到欧氏距离,但需要确认是否属于find_object_2d的功能。 还要注意代码示例,用户可能希望看到相关的代码片段,比如特征提取或匹配的部分。虽然不确定具体的实现代码,但可以引用OpenCV的函数,如detectAndCompute()。 最后,生成相关问题需要考虑用户可能感兴趣的扩展方向,如性能优化、不同特征方法的比较、实际应用案例,以及与ROS其他组件的集成,如如何结合点云数据进行3D定位。 需要确保回答结构清晰,分步骤解释原理,并正确使用LaTeX公式,行内公式用$...$,独立公式用$$...$$。同时,引用用户提供的引用内容,但要注意相关性。例如,欧氏距离可能在物体定位中使用,但find_object_2d主要处理2D识别,可能涉及平面变换而非3D距离计算。 总结回答结构:先概述find_object_2d的功能,然后分特征提取、匹配、几何验证三个部分,每部分解释方法并给出相关公式,最后可能提到与ROS其他模块的结合,如tf坐标变换。确保引用正确,比如特征匹配中的NNDR和RANSAC部分可以引用用户提供的引用[1]中的欧氏距离,但需要恰当关联。</think>[系统级响应] ### ROS find_object_2d 包的物体识别原理与数学方法 #### 1. **核心原理概述** `find_object_2d` 是基于特征匹配的物体识别工具,其核心流程包括 **特征提取 → 特征匹配 → 几何验证**。它依赖 OpenCV 实现以下关键步骤: - **特征提取**:使用 SIFT、SURF 或 ORB 等算法提取关键点和描述子。 - **特征匹配**:通过相似性度量(如欧氏距离)匹配当前帧与模板的特征。 - **几何验证**:通过单应性矩阵(Homography)验证匹配的几何一致性。 #### 2. **关键数学方法与公式** **2.1 特征描述子生成(以 SIFT 为例)** SIFT 通过高斯差分(DoG)检测关键点,并生成 128 维描述子: $$ D(x,y,\sigma) = (G(x,y,k\sigma) - G(x,y,\sigma)) * I(x,y) $$ 其中 $G$ 为高斯核,$I$ 为图像,$\sigma$ 为尺度参数[^1]。 **2.2 特征匹配与相似性度量** 使用欧氏距离(引用[1]中提到的公式)衡量描述子相似性: $$ d(\mathbf{v}_1, \mathbf{v}_2) = \sqrt{\sum_{i=1}^{n}(v_{1i} - v_{2i})^2} $$ 匹配时通过 **最近邻距离比(NNDR)** 筛选: $$ \text{NNDR} = \frac{d_{\text{最近}}}{d_{\text{次近}}} \quad (\text{阈值通常设为 } 0.6-0.8) $$ **2.3 单应性矩阵估计(RANSAC)** 通过 RANSAC 算法估计单应性矩阵 $H$,满足: $$ \mathbf{x'} = H \mathbf{x} \quad \text{即} \quad \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} h_{11} & h_{12} & h_{13} \\ h_{21} & h_{22} & h_{23} \\ h_{31} & h_{32} & h_{33} \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} $$ RANSAC 通过迭代优化最小化重投影误差: $$ \epsilon = \sum_i \left\| \mathbf{x'}_i - H \mathbf{x}_i \right\|^2 $$ #### 3. **ROS 中的实现流程** ```python # 伪代码示例(基于 OpenCV) sift = cv2.SIFT_create() kp1, des1 = sift.detectAndCompute(template_img, None) # 模板特征 kp2, des2 = sift.detectAndCompute(query_img, None) # 当前帧特征 # 特征匹配(暴力匹配) bf = cv2.BFMatcher() matches = bf.knnMatch(des1, des2, k=2) # 应用 NNDR 筛选 good_matches = [] for m,n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) # 计算单应性矩阵 src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1,1,2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1,1,2) H, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) ``` #### 4. **与 ROS 的集成** - **坐标变换**:通过 `tf` 发布物体在机器人坐标系中的位置(需结合相机标定参数)。 - **性能优化**:引用[2]中的线性模型思想可用于预测运动物体的位置变化,但需扩展为非线性模型。
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值