0
$\begingroup$

Rosanswers logo

ROS Indigo, Python, OpenCV (cv_bridge)

I wrote a node that does differential imaging on the webcam feed from a Kinect, but when I publish the final images and try to view them in image_view, the frame rate is really slow. If I instead use cv2.imshow() at the same place I'm publishing, the frame rate is fine. What is causing the the frame rate to be so slow when publishing and viewing with image_view, rather than just viewing through OpenCV?

Here's my publisher setup:

...other code...

image_pub = rospy.Publisher("/motion_image", Image, queue_size=10)

...other code...

try:
        img = bridge.cv2_to_imgmsg(motion_img, "bgr8")
        image_pub.publish(img)
except CvBridgeError, e:
        print e

And my subscriber if helpful:

image_sub = rospy.Subscriber("/camera/rgb/image_color", Image, callback, queue_size=10)

I just want to be able to grab one image at a time so I unregister at each call, when I want another image I resubscribe

def callback(data):
    global camera_img, image_sub

    try:
        bridge = CvBridge()
        camera_img = bridge.imgmsg_to_cv2(data, "bgr8")
        image_sub.unregister()
    except CvBridgeError, e:
        print e

Update: Here's the rest of my code, feel free to comment on other things as well. I'm new to Python and ROS and I want to get better. Sorry it's not posted direct, I was having trouble getting it to format correctly.

http://pastebin.com/RveN6esS


Originally posted by troman on ROS Answers with karma: 30 on 2015-06-27

Post score: 0

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

Keep your connection alive.

Unregistering and registering takes time. At least some milliseconds, it is done by XMLRPC and this means as the name says, parsing an XML message on each side, then opening a port and creating the connection.

(Update:)

more detailed what happens:

First you subscribe:
Node -XMLRPC -> Master (I subscribe topic xyz)
Master -XMLRPC -> Node (There is a publisher X)
Node -XMLRPC-> NodeX (I want topic xyz)
NodeX -XMLRPC-> Node (I opened port Y for you)
Node <-ROSMSG Header-> NodeX:PortY(ROSMSG Header)
NodeX -ROSMSG Binary-> constantly sending when published

Then you unsubscribe:
Node -XMLRPC-> NodeX (I do not want topic xyz anymore)
NodeX -XMLRPC> Node (OK) 
Close connection on PortY (both)
Node -XMLRPC-> Master (I am not interested in xyz anymore)
Master -XMLRPC-> OK

So why don't you just disable the processing in the callback itself instead of resubscribing when you do not want to have images?

Like

void callback(...)
{
  if(image_processing_enable) 
  {
   .... Save your image, processing ... what ever ...
   image_processing_enable=false; // for getting only one image. 
  }
}

Regards,

Christian


Originally posted by cyborg-x1 with karma: 1376 on 2015-06-27

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by troman on 2015-06-27:
Hi Christian, thanks for the reply. The reason I subscribe like this is so that I can grab a new image at a specific time. I have a loop going were I need to grab two sequential images, and as far as I could tell, that was the only way I could accomplish this.

Comment by troman on 2015-06-27:
I don't think this is the root of my performance issue though. When I display the image mid loop using opencv, and still subscribing in this way it works fine. The performance issue seems to be coming from publishing lt and viewing it from another node

Comment by cyborg-x1 on 2015-06-28:
Even if you want this image at a specific time there is no need to resubscribe. You as soon as you want the next image in my approach you do image_processing_enable = true. Then you get your image even closer to the time you want.

Comment by cyborg-x1 on 2015-06-28:
Is this

image_pub = rospy.Publisher("/motion_image", Image, queue_size=10

in the same loop like

try:
        img = bridge.cv2_to_imgmsg(motion_img, "bgr8")
        image_pub.publish(img)
except CvBridgeError, e:
        print e

?

Comment by cyborg-x1 on 2015-06-28:
If yes you would also always recreate your publisher before you publish it which would do almost the same like above with the subscriber master communication, that would lead to a very low frequency

Comment by troman on 2015-06-28:
The publisher is created outside of the loop, and is told to publish inside the loop. The subscriber is created outside the loop, subscribed outside to initialize the first image, and then resubscribed in the loop to get the next image.

Comment by troman on 2015-06-28:
I haven't been able to try your suggestion yet but as soon as I can I will. Then I'll update here. Thanks for the help!

Comment by cyborg-x1 on 2015-06-28:
You could also consider my answer to this, http://answers.ros.org/question/212357/subscribe-to-image-at-regular-time-intervals/ if the bandwith is critical for you

Comment by troman on 2015-06-29:
Alright so I tried what you suggested. Now my motion tracking doesn't work because it's not loading in the next frame, it's constantly comparing the next frame to itself, which is my original problem and why I switched to the resubscribe. I'm going to post the full code so you can see more.

Comment by troman on 2015-06-29:
For the record this is my code before trying your changes. Maybe you had something different in mind than I imagined?

Comment by cyborg-x1 on 2015-06-29:
I expected you to have a secondary process (like the main loop) where you determine when to start to get the next images. And when doing so, set the variable true. Then gather the images in an array maybe till you counted as many you want and then set it to false and analyze and reenable gathering

Comment by troman on 2015-07-06:
I'm going to go ahead and give you the check for this one. I never ended up being able to improve the frame rate with or without your approach but I see it's worked for other people. Thanks for the help.

Comment by scandrew on 2016-12-15:
Hi Thomas, Were you able to figure out the framerate issue? I am having the same problem. cv_bridge converts my image and posts it, but the frame rate is abysmal.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.