Week3: Image Subscriber - lasithaya/Robotics-lasi GitHub Wiki
Create Image subscriber and Image-Processing Node
The next node will subscribe to the image topic and display it in a window using OpenCV library functions
-
As before, create a basic ROS python node (
example2_image_subcriber.py) and set its executable permissions:#!/usr/bin/env python import rospy def start_node(): rospy.init_node('image_subcriber') rospy.loginfo('image_subcriber node started') if __name__ == '__main__': try: start_node() except rospy.ROSInterruptException: passchmod u+x nodes/example2_image_subcriber.py- Note that we don't have to edit
CMakeListsto create new build rules for each script, since python does not need to be compiled.
- Note that we don't have to edit
-
Add a ROS subscriber to the
imagetopic, to provide the source for images to process.-
Import the
Imagemessage headerfrom sensor_msgs.msg import Image -
Above the
start_nodefunction, create an empty callback (process_image) that will be called when a new Image message is received:def process_image(msg): try: pass except Exception as err: print err- The try/except error handling will allow our code to continue running, even if there are errors during the processing pipeline.
-
In the
start_nodefunction, create a ROS Subscriber object:- subscribe to the
imagetopic, monitoring messages of typeImage - register the callback function we defined above
rospy.Subscriber("image", Image, process_image) rospy.spin()- reference: rospy.Subscriber
- reference: rospy.spin
- subscribe to the
-
Run the new node and verify that it is subscribing to the topic as expected:
rosrun my_cv_tutorial example2_image_subcriber.py rosnode info /image_subcriber rqt_graph
-
-
Convert the incoming
Imagemessage to an OpenCVImageobject and display it As before, we'll use theCvBridgemodule to do the conversion.-
Import the
CvBridgemodules and createCvBridgeobjectfrom cv_bridge import CvBridge bridge = CvBridge() -
In the
process_imagecallback, add a call to the CvBridge imgmsg_to_cv2 method:# convert sensor_msgs/Image to OpenCV Image orig = bridge.imgmsg_to_cv2(msg, "bgr8")- This code (and all other image-processing code) should go inside the
tryblock, to ensure that processing errors don't crash the node. - This should replace the placeholder
passcommand placed in thetryblock earlier
- This code (and all other image-processing code) should go inside the
-
Use the OpenCV
imshowmethod to display the images received. We'll create a pattern that can be re-used to show the result of each image-processing step.-
Import the OpenCV
cv2module:import cv2 -
Add a display helper function above the
process_imagecallback:def show_image(img): cv2.imshow('image', img) cv2.waitKey(1) -
Below the
exceptblock (outside its scope; atprocess_imagescope, display thedrawImgvariable:# show results show_image(orig)
-
-
Run the node and see the received image displayed. Make sure image publisher is still running from the previous example
-
Complete code
#!/usr/bin/env python
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
bridge = CvBridge()
def start_node():
rospy.init_node('image_subcriber')
rospy.loginfo('image_subcriber node started')
rospy.Subscriber("image", Image, process_image)
rospy.spin()
def process_image(msg):
try:
# convert sensor_msgs/Image to OpenCV Image
orig = bridge.imgmsg_to_cv2(msg, "bgr8")
except Exception as err:
print err
# show results
show_image(orig)
def show_image(img):
cv2.imshow('image', img)
cv2.waitKey(1)
if __name__ == '__main__':
try:
start_node()
except rospy.ROSInterruptException:
pass