One of the advantages of ROS is that it has tons of packages that can be reused in our applications. In our case, what we want is to implement an object recognition and detection system. The find_object_2d
package (http://wiki.ros.org/find_object_2d) implements SURF, SIFT, FAST, and BRIEF feature detectors (https://goo.gl/B8H9Zm) and descriptors for object detection. Using the GUI provided by this package, we can mark the objects we want to detect and save them for future detection. The detector node will detect the objects in camera images and publish the details of the object through a topic. Using a 3D sensor, it can estimate the depth and orientation of the object.
Installing this package is pretty easy. Here is the command to install it on Ubuntu 16.04 and ROS Kinetic:
$ sudo apt-get install ros-kinetic-find-object-2d
Here is the procedure to run the detector nodes for a webcam. If we want to detect an object using a webcam, we first need to install the usb_cam
package,which was discussed in Chapter 2, Face Detection and Tracking Using ROS, OpenCV, and Dynamixel Servos.
roscore
:$ roscore
usb_cam
driver:$ roslaunch usb_cam usb_cam-test.launch
This will launch the ROS driver for USB web cameras, and you can list the topics in this driver using the rostopic list
command. The list of topics in the driver is shown here:
Figure 3: Topics being published from the camera driver
/usb_cam/image_raw
topic. If you are getting this topic, then the next step is to run the object detector node. The following command will start the object detector node:$ rosrun find_object_2d find_object_2d image:=/usb_cam/image_raw
This command will open the object detector window, shown in the previous screenshot, in which we can see the camera feed and the feature points on the objects.
Figure 4: The Find-Object detector window
Figure 5: The Add object wizard for taking a snap of the object
Figure 6: The Add object wizard for marking the object
Figure 7: The last step of the Add object wizard
Figure 8: The Find-Object wizard starting the detection
$ rosrun find_object_2d print_objects_detected
Figure 9: The object details
/object
topic. The topic publishes a multi-array that consist of the width and height of the object and the homography matrix to compute the position and orientation of the object and its scale and shear values. You can echo the /objects
topic to get output like this:
Figure 10: The /object topic values
Figure 11: The equation to compute object position
Here, H is the homography 3x3 matrix, (x1, y1) is the object's position in the stored image, and (x2, y2) is the computed object position in the current frame.
You can check out the source code of the print_objected_src
node to get the conversion using a homography matrix.
Here is the source code of this node: https://github.com/introlab/find-object/blob/master/src/ros/print_objects_detected_node.cpp.
Using a webcam, we can only find the 2D position and orientation of an object, but what should we use if we need the 3D coordinates of the object? We could simply use a depth sensor like the Kinect and run these same nodes. For interfacing the Kinect with ROS, we need to install some driver packages. The Kinect can deliver both RGB and depth data. Using RGB data, the object detector detects the object, and using the depth value, it computes the distance from the sensor too.
Here are the dependent packages for working with the Kinect sensor:
$ sudo apt-get install ros-kinetic-openni-launch
If you are using the Asus Xtion Pro or other PrimeSense device, you may need to install the following driver to work with this detector:
$ sudo apt-get install ros-kinetic-openni2-launch
In this book, we will be working with the Xbox Kinect, which is the first version of Kinect.
Before starting the Kinect driver, you have to plug the USB to your PC and make sure that the Kinect is powered using its adapter. Once everything is done, you can launch the drivers using the following command:
$ roslaunch openni_launch openni.launch depth_registration:=true
Figure 12: List of topics from the Kinect openNI driver
Figure 13: Object detection using Kinect
find_object_3d.launch
.You can directly view this file from the following link: https://github.com/introlab/find-object/blob/master/launch/find_object_3d.launch.
This launch file is written for an autonomous robot that detects objects while navigating the surrounding.
camera_rgb_frame
, which is shown in the previous diagram. Here is the launch file definition we want for the demo:<launch> <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_registered/image_raw"/> <remap from="depth_registered/camera_info" to="camera/depth_registered/camera_info"/> </node> </launch>
In this code, we just removed the static transform required for the mobile robot. You can also change the object_prefix
parameter to name the detected object.
Using the following commands, you can modify this launch file, which is already installed on your system:
$ roscd find_object_2d/launch $ sudo gedit find_object_3d.launch
Now, you can remove the unwanted lines of code and save your changes. After saving this launch file, launch it to start detection:
$ roslaunch find_object_2d find_object_3d.launch
You can mark the object and it will start detecting the marked object.
/camera_link
or /camera_rgb_frame
, and add a TF display from the left panel of Rviz.$ rosrun rviz rviz
Other than publishing TF, we can also see the 3D position of the object in the detector Terminal. The detected position values are shown in the following screenshot:
Figure 14: Printing the 3D object's position
18.216.190.167