Ask Your Question
0

Subscribe to two image_raws with one function

asked 2013-10-30 23:46:13 -0600

Bison gravatar image

updated 2014-04-20 14:06:44 -0600

ngrennan gravatar image

Hello community, I want to capture pictures from two webcams simultaneously and process them with opencv. I tried to get this work with two image_subscribers, that have the same callback-function. I tried that by editing the code from the cvbridge-tutorial. The result of my editing was, that i got two windows that show both the same picture, switching between the two image raws. So here is my question now:

How do I have to define my subscribers or my callback function to get the two raws seperately in one function to process them both simultaneously?

Solution: http://wiki.ros.org/message_filters. There you can find an example cpp-code for a policy-based synchronizer function. I've used this example to get my Node working.

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
0

answered 2013-10-31 06:11:02 -0600

image_transport has a special type of subscriber specifically for stereo cameras that does what you want, but I think it requires that the timestamps in the image headers be exactly synchronized which is hard to do with webcams.

Your best choice is probably an ApproximateTime synchronizer, which lets you subscribe to two topics with a callback that receives a message from each topic.

edit flag offensive delete link more

Comments

There was a very good example on the message_filters entry of the ROS WIKI. Using this example I was able to get the task accomplished. Thank you all for your help. It's good to know that there is a great community that helps everytime it is needed.

Bison gravatar imageBison ( 2013-11-04 02:13:04 -0600 )edit
0

answered 2013-10-31 06:21:21 -0600

timster gravatar image

I think I originally took part of the code from stereo_image_proc. I guess your two webcams are not synchronized, so the following code uses approximate sync. If they are synchronized you can use exact sync in the same way.

These are your includes:

#include <sensor_msgs/Image.h>
#include <image_transport/subscriber_filter.h>
#include <message_filters/sync_policies/approximate_time.h>

And don't forget to add the corresponding dependencies in your manifest.xml/package.xml!

Subscribe to the right topics and register what callback function to call, this could go into your main function:

ros::NodeHandle nh;
image_transport::SubscriberFilter left_sub, right_sub;
image_transport::ImageTransport it(nh);
left_sub.subscribe(it, "left_topic", 1, "raw");
right_sub.subscribe(it, "right_topic", 1, "raw");

typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image> ApproximatePolicy;
typedef message_filters::Synchronizer<ApproximatePolicy> ApproximateSync;

boost::shared_ptr<ApproximateSync> approximate_sync;

approximate_sync.reset(new ApproximateSync(ApproximatePolicy(queue_size),left_sub,right_sub));
approximate_sync->registerCallback(boost::bind(callback, _1, _2));

ros::spin();

Define your callback function:

void callback(const sensor_msgs::ImageConstPtr& l_image_msg, 
              const sensor_msgs::ImageConstPtr& r_image_msg){
    ROS_INFO("Callback reached! :-)");
}

Probably I forgot some stuff so I will try to update my answer!

Good luck!

edit flag offensive delete link more
-1

answered 2013-10-31 00:06:12 -0600

BennyRe gravatar image

updated 2013-10-31 03:18:06 -0600

I would suggest you create two callbacks. Each callback calls your original callback, but with an argument, which stream to process.

For example:

void callback1(image_raw foo)
{
    originalCallback(foo, 1);
}

void callback2(image_raw foo)
{
    originalCallback(foo, 2);
}

void originalCallback(image_raw bar, int callerId)
{
    if(callerId == 1)
    {}
    else
    {}
}

Another possible solution could be looking at the connection header of the image_raw message.

edit flag offensive delete link more

Comments

Actually your suggestion works, but it doesn't fit my problem. With your solution I don't get both image_raws in my function at the same time. But this is exactly what i need. I want to save a pair of stereo images where a chessboard is recognized for an offline calibration of my stereocamera system

Bison gravatar imageBison ( 2013-10-31 03:04:50 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2013-10-30 23:46:13 -0600

Seen: 864 times

Last updated: Nov 04 '13