ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

publishing a cv2 image with cv_bridge

asked 2019-07-04 04:29:40 -0500

rosberrypi gravatar image

I wrote a basic node that reads an image from a local folder and publishes it. However, the topic is empty, i can not display the image when i use the image viewer. The cv2 image is being loaded correctly because i can display it with cv2.imshow function so the problem is the way i convert it to imgmsg.

I am not sure if this line works as it should:

image_message = self.bridge.cv2_to_imgmsg(cv_image, "passthrough")

The whole node is as simple as this:

class image_publisher:
 def __init__(self):
  self.image_pub = rospy.Publisher("image_topic",Image)
  cv_image = cv2.imread('/Pictures/image.png',0)
  self.bridge = CvBridge()
  image_message = self.bridge.cv2_to_imgmsg(cv_image, "passthrough")
  self.image_pub.publish(image_message)
edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
1

answered 2019-07-08 03:05:15 -0500

pavel92 gravatar image

updated 2019-07-09 09:56:50 -0500

As PeteBlackerThe3rd suggested you're publishing the image in your __init__ method right after the publisher is created. Here is an example class that works for your case:

import rospy
from sensor_msgs.msg import Image
import cv2
from cv_bridge import CvBridge, CvBridgeError
import time


class ImagePublisher(object):

  def __init__(self):
    self.node_rate = 1

    self.image_pub = rospy.Publisher("image_topic", Image)
    cv_image = cv2.imread('/Pictures/image.png',0)
    self.bridge = CvBridge()

    try:
      self.image_message = self.bridge.cv2_to_imgmsg(cv_image, "passthrough")
    except CvBridgeError as e:
      print(e)

    time.sleep(5)
    self.image_pub.publish(self.image_message)

  def doSmth(self):
    rospy.loginfo('its working!')
    # self.image_pub.publish(self.image_message)

  def run(self):
    loop = rospy.Rate(self.node_rate)
    while not rospy.is_shutdown():
      self.doSmth()
      loop.sleep()

If you want to publish the image only once then use the time.sleep() in your __init__ . Otherwise if you want to publish on some rate then uncomment the publish line in doSmth().

EDIT: WIth image_view I am encountering conversion errors due to encoding/color formats. In my case it is trying to convert image from '8UC3' to 'bgr8' so I had to change this line:

self.image_message = self.bridge.cv2_to_imgmsg(cv_image, encoding="bgr8")

Now I can see the image using:

rosrun image_view image_view image:=/image_topic

Anyway the initial problem you had was still related to publishing the image in your __init__ method right after the publisher is create.
Also note that if you are publishing it only once as in your example, make sure to run image_view before you run your node.

edit flag offensive delete link more
0

answered 2019-07-09 03:51:54 -0500

rosberrypi gravatar image

updated 2019-07-09 03:52:36 -0500

Thanks for the answers. Altough I took your advice and changed the way I structure the node and do the actual stuff outside the __init__ function, the image viewer does not display my images. However, I wrote a subscriber node and subscribed to the image topic and can receive images just fine. So I guess the problem is actually displaying it not about the node itself. I can see the images on rviz right now so everything works fine.

edit flag offensive delete link more

Comments

In that case did you check if you successfully loaded the image with cv_image = cv2.imread()? Maybe the path was wrong and it could not found it (for debug you can just print the image to see if there is any data in it for example). With the code that I posted bellow it works, meaning you can visualize the loaded image in rviz using the image display.

In addition, in the future please do not write your feedback as an answer. Write it as a comment to your question, edit the question with the fix or write a comment to some of the answers. At the moment your answer is not the fix for the stated problem asked in the question but a fix for your specific usecase. :)
Also accept an answer if it was correct by clicking the tick mark.

pavel92 gravatar image pavel92  ( 2019-07-09 07:52:25 -0500 )edit

I am able to visualize the image with imshow function but not with the following command "rosrun image_view image_view image:=/image_topic". So my issue still exists, i can subscribe to image and use it which means there is nothing wrong with the way it is being published however the above image_viewer fails to display it.

rosberrypi gravatar image rosberrypi  ( 2019-07-09 08:26:17 -0500 )edit

I will give it a look with image_view. However you dont need to use the imshow from opencv, Open rviz, click add and find the "Image" plugin. Then select the right topic. If you are publishing it only in your initialization just re-run your node with rviz open and you should be able to see the image.

pavel92 gravatar image pavel92  ( 2019-07-09 08:59:37 -0500 )edit

I updated my answer regarding image_view

pavel92 gravatar image pavel92  ( 2019-07-09 09:51:31 -0500 )edit
0

answered 2019-07-04 08:13:13 -0500

I notice you're publishing the image in your __init__ method right after the publisher is created. This is probably the cause of this issue.

Publishers take a while to setup and for subscribers to attach to them, so in this case the image is probably being published before any subscribers are registered, which is why you're not seeing anything on the topic.

Try changing your code so it uses a loop with a 1 second rate or a timer callback to publish the same image once per second. This should give time for subscribers to attach and the image to be viewed.

Hope this helps.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2019-07-04 04:29:40 -0500

Seen: 3,286 times

Last updated: Jul 09 '19