Anto
Anto

Reputation: 61

Access Image via OpenCV in python (ROS Kinetic)

I want to access my camera using OpenCV in ros kinetic, this is my code

#!/usr/bin/env python2.7
import rospy
from sensor_msgs.msg import Image
import cv2
from cv_bridge import CvBridge, CvBridgeError

rospy.init_node('opencv_example', anonymous=True)
bridge = CvBridge()

def show_image(img):
    cv2.imshow("Image Window", img)
    cv2.waitKey(3)


def image_callback(img_msg):
    try:
        cv_image = bridge.imgmsg_to_cv2(img_msg, "passthrough")
    except CvBridgeError, e:
        rospy.logerr("CvBridge Error: {0}".format(e))
    
    show_image(cv_image)
    
sub_image = rospy.Subscriber("/raspicam_node/image/compressed", Image, image_callback)
cv2.namedWindow("Image Window", 1)

while not rospy.is_shutdown():
      rospy.spin()

all I get after this code is a blank image window

before you ask the topic address, I can access the camera with this command rostrum image_view image_view image:=/raspicam_node/image/ _image_transport:=compressed

currently, I am working with

Upvotes: 2

Views: 2062

Answers (1)

BTables
BTables

Reputation: 4833

You've answered your own question, the image is coming in compressed. Because of this your subscriber is also wrong there is a specific sensor_msgs type for Compressed Images.

Using numpy you can decode the image directly in your subscriber like so:

def image_callback(img_msg):
    np_arr = np.fromstring(img_msg.data, np.uint8)
    image_np = cv2.imdecode(np_arr, cv2.CV_LOAD_IMAGE_COLOR)
    
    show_image(cv_image)

As stated earlier, your subscriber also needs to look like

sub_image = rospy.Subscriber("/raspicam_node/image/compressed", CompressedImage, image_callback)

And you need to include from sensor_msgs.msg import CompressedImage

Edit:

Based on your comment you can also republish the compressed image as an uncompressed image to use with your original code using image_transport.

If you want to use rosrun in the terminal: rosrun image_transport republish compressed in:=/raspicam_node/image/compressed raw out:=/raspicam_node/image/uncompressed

Or if you're using a launch file:

<node name="republish" type="republish" pkg="image_transport" output="screen" args="compressed in:=/raspicam_node/image/compressed raw out:=/raspicam_node/image/uncompressed" />

Then you need to change your original code to

#!/usr/bin/env python2.7
import rospy
from sensor_msgs.msg import Image
import cv2
from cv_bridge import CvBridge, CvBridgeError

rospy.init_node('opencv_example', anonymous=True)
bridge = CvBridge()

def show_image(img):
    cv2.imshow("Image Window", img)
    cv2.waitKey(3)


def image_callback(img_msg):
    try:
        cv_image = bridge.imgmsg_to_cv2(img_msg, "passthrough")
    except CvBridgeError, e:
        rospy.logerr("CvBridge Error: {0}".format(e))
    
    show_image(cv_image)
    
sub_image = rospy.Subscriber("/raspicam_node/image/uncompressed", Image, image_callback)
cv2.namedWindow("Image Window", 1)

while not rospy.is_shutdown():
      rospy.spin()

Upvotes: 1

Related Questions