一起做ROS-DEMO系列 (2):基於find_object_2d的目標匹配識別

  • 接上文,我們希望機器人能夠更加智能一點,抓住我們想要的任何東西,而不是通過貼標籤(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中心點座標大致準確,但是姿態就不是很靠譜了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章