通過ROS控制真實機械臂(16) --- 視覺抓取之find_object實現物體識別

視覺抓取中非常重要的一個部分就是對抓取物體的識別,無論是二維圖像還是三維點雲,在ROS中都可以找到對應的功能包,本次測試的是能對物體進行快速識別,甚至定位的find_object包,該功能包是基於模板匹配算法(包括彩色圖像或點雲匹配)。ubuntu14.04+indigo+usb攝像頭/kinect相機/Zed mini相機。

本文參考: https://github.com/introlab/find-object

一、下載安裝(兩種方式):

1. Install安裝:

# 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. 源碼安裝:

# Install ROS Groovy/Hydro/Indigo/Jade/Kinetic (catkin build):
 $ cd ~/catkin_ws
 $ git clone https://github.com/introlab/find-object.git src/find_object_2d
 $ catkin_make

# Install ROS Fuerte (in a directory of your "ROS_PACKAGE_PATH"):
 $ svn checkout -r176 http://find-object.googlecode.com/svn/trunk/ros-pkg/find_object_2d
 $ rosmake find_object_2d

二、簡單啓動測試:

1. USB攝像頭

 # &表示後臺運行
 $ roscore &

 # 啓動攝像機節點
 $ rosrun uvc_camera uvc_camera_node &
 # 或者啓動攝像機launch文件,我更傾向這種
 $ roslaunch usb_cam usb_cam-test.launch

 $ rosrun find_object_2d find_object_2d image:=image_raw
 # 通過launch啓動話題需要修改
 $ rosrun find_object_2d find_object_2d image:=/usb_cam/image_raw 

2. KInect攝像頭

 # 啓動Kinect攝像機節點
 $ rosrun freenect_launch freenect.launch

 # 查看話題類型
 $ rostopic list
 
 # 雙目相機同理,訂閱對應的二維圖像話題即可
 $ rosrun find_object_2d find_object_2d image:=/camera/rgb/image_color
 
 # 如果使用選擇成/camera/rgb/image_raw會報錯
  find_object_ros: Encoding "bayer_grbg8" detected. Supported image encodings are bgr8 and rgb8...

三、基於二維圖像識別和檢測物體

在出現的界面左側空白欄中鼠標右擊選擇Add obejct from scene 從場景中選取待檢測物體,講想要識別的物體置於場景當中,點擊take picture,然後左上角可以選擇拍照的具體的區域或者角點,next之後確認無誤end即可。

此時左側空白處已經添加了一個待識別物體,當我們講該物體放到攝像頭的視角當中的時候,待識別物體就會背框選出來。

find_object包中還有一個節點print_objects_detected可以用來確定物體的位置,當沒有檢測處待測物體的時候,顯示的是No object detected,當待識別物體出現在視野當中的時候,就可以看到終端輸出的物體位置信息。

源碼:
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());

從源碼可以看出,數據還不是特別容易觀察,但該信息也通過話題/objects發佈,編程的是訂閱話題即可獲取數據。通過topic查看:

$ rostopic echo /objects

輸出結果說明:
Objects detected formatted as [objectId1, objectWidth, objectHeight, h11, h12, h13, h21, h22, h23, h31, h32, h33, objectId2...] where h## is a 3x3 homography matrix (h31 = dx and h32 = dy, see QTransform).

輸出結果:
layout: 
  dim: []
  data_offset: 0
data: [4.0, 289.0, 271.0, 1.8393758535385132, 0.0202195942401886, 0.00017601421859581023, 0.4901503920555115, 2.0912954807281494, 0.00150511774700135, 125.54476928710938, 102.35379791259766, 1.0]


# 對應的結果來看 此處物體的寬和高都是爲289.0和271.0,大致是真實物體的寬和高的一半,我覺得可能描述的是識別物體的中心座標,也可能是配置和標定不準確,有待後期測試

四、基於三維深度識別和檢測物體

和usb單目攝像頭不同的是,find_object還專門提供了一個find_object_3d節點,專爲kinect或者zed雙目之類的深度相機準備的,可以通過在匹配目標後識別目標中心的深度信息輸出目標的三維座標。

1. 啓動深度相機

# kinect2
roslaunch kinect2_bridge kinect2_bridge,launch

# realsesnse D414/435
roslaunch realsense2_camera rs_camera.launch

# zed mini相機
roslaunch zed_wrapper zedm.launch

2. 啓動find_object_3d節點

 # 雙目相機
 $ roslaunch find_object_2d find_object_3d.launch
 # 或
 $ roslaunch find_object_2d find_object_3d_kinect2.launch
 # 或
 $ roslaunch find_object_2d find_object_3d_zed.launch

由於kinect一代和二代有點區別,如下是我用kinect和zed的launch文件

<launch>
	<!-- Example finding 3D poses of the objects detected -->
	<!-- $roslaunch freenect_launch freenect.launch depth_registration:=true -->
	
	<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="/camera/rgb/image_rect_color"/>
		<remap from="depth_registered/image_raw" to="/camera/depth/image"/>
		<remap from="depth_registered/camera_info" to="/camera/rgb/camera_info"/>
	</node>
	
	<!-- Example of tf synchronisation with the objectsStamped message -->
	<node name="tf_example" pkg="find_object_2d" type="tf_example" output="screen">
		<param name="map_frame_id" value="/map" type="string"/>
		<param name="object_prefix" value="object" type="str"/>
	</node>
</launch>


<launch>
	<!-- Example finding 3D poses of the objects detected -->
	<!-- $ roslaunch zed_wrapper zed.launch -->

	<arg name="object_prefix" default="object"/>
	<arg name="objects_path"  default=""/>
	<arg name="gui"           default="true"/>
	<arg name="settings_path" default="~/.ros/find_object_2d.ini"/>
		
	<node name="find_object_3d" pkg="find_object_2d" type="find_object_2d" output="screen">
		<param name="gui" value="$(arg gui)" type="bool"/>
		<param name="settings_path" value="$(arg settings_path)" type="str"/>
		<param name="subscribe_depth" value="true" type="bool"/>
		<param name="objects_path" value="$(arg objects_path)" type="str"/>
		<param name="object_prefix" value="$(arg object_prefix)" type="str"/>
		<param name="approx_sync" value="false" type="bool"/>
		
		<remap from="rgb/image_rect_color" to="/zed/rgb/image_rect_color"/>
		<remap from="depth_registered/image_raw" to="/zed/depth/depth_registered"/>
		<remap from="depth_registered/camera_info" to="/zed/rgb/camera_info"/>
	</node>
</launch>

3.話題確定(如果launch文件發佈的話題不同,還需要手動映射參數)

​# 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)//深度圖像​


# find_object_3d節點發布的話題
topic:objects (message_type: std_msgs/Float32MultiArray)    // 同二維
topic:objectsStamped (message_type: find_object_2d/ObjectsStamped)//帶標籤的對象物體

4 調整參數,選擇特徵算子及算法(參考知乎大神:https://zhuanlan.zhihu.com/p/71603204)

可以選擇SURF、SIFT、ORB、FAST等一系列算法,觀察目標物體上的特徵點數量及效果,以及處理的流暢程度,衡量選擇合適的算法。通過菜單View - Parameters調出參數欄選項卡進行調整。此外如果我們是使用find_object_3d,可以打開rviz可視化工具,看到目標的TF座標已經被發出來了(這裏需要正確的配置相機的TF座標系),此外此節點還發布了目標中心座標的圖像,可以通過rqt_image_view查看 /image_with_objects。整體來說這個功能包安裝是相當方便的,不過因爲是模板匹配,所以侷限性比較大,在目標物體未正對攝像頭的情況下識別成功率不高,而且想要得到良好的匹配效果需要認真的調節參數,旋轉合適的算法,另外輸出的tf中心點座標大致準確,但是姿態就不是很靠譜了。

$ rosrun rviz rviz  (for visualisation purpose: set "fixed_frame" to "/camera_link" and add TF display)

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章