anaglyph.cpp
Go to the documentation of this file.
00001 #include <ros/ros.h>
00002 #include <sensor_msgs/Image.h>
00003 #include <sensor_msgs/image_encodings.h>
00004 #include "sensor_msgs/fill_image.h"
00005 
00006 #include <message_filters/subscriber.h>
00007 #include <message_filters/time_synchronizer.h>
00008 #include <image_transport/subscriber_filter.h>
00009 
00010 #include <boost/thread.hpp>
00011 
00012 namespace enc = sensor_msgs::image_encodings;
00013 
00014 void increment(int* value)
00015 {
00016   ++(*value);
00017 }
00018 
00019 class Anaglyph3D
00020 {
00021 private:
00022   image_transport::ImageTransport it_;
00023   image_transport::SubscriberFilter left_sub_, right_sub_;
00024   message_filters::TimeSynchronizer<sensor_msgs::Image, sensor_msgs::Image> sync_;
00025   image_transport::Publisher pub_anaglyph_;
00026   
00027   sensor_msgs::ImageConstPtr last_left_, last_right_;
00028   boost::mutex image_mutex_;
00029   sensor_msgs::Image img_ana_;
00030   
00031   ros::WallTimer check_synced_timer_;
00032   int left_received_, right_received_, all_received_;
00033 
00034 public:
00035   Anaglyph3D(ros::NodeHandle& nh)
00036     : it_(nh), sync_(2), left_received_(0),
00037       right_received_(0), all_received_(0)
00038   {
00039     ros::NodeHandle local_nh("~");
00040     
00041     std::string stereo_ns = nh.resolveName("stereo");
00042     std::string left_topic = ros::names::clean(stereo_ns + "/left/" + nh.resolveName("image"));
00043     std::string right_topic = ros::names::clean(stereo_ns + "/right/" + nh.resolveName("image"));
00044     ROS_INFO("Subscribing to:\n\t* %s\n\t* %s\n\t* %s", left_topic.c_str(), right_topic.c_str());
00045 
00046     left_sub_.subscribe(it_, left_topic, 3);
00047     right_sub_.subscribe(it_, right_topic, 3);
00048     sync_.connectInput(left_sub_, right_sub_);
00049     sync_.registerCallback(boost::bind(&Anaglyph3D::imageCB, this, _1, _2));
00050 
00051     pub_anaglyph_ = it_.advertise(stereo_ns + "anaglyph3D", 1);
00052 
00053     // Complain every 30s if the topics appear unsynchronized
00054     left_sub_.registerCallback(boost::bind(increment, &left_received_));
00055     right_sub_.registerCallback(boost::bind(increment, &right_received_));
00056     sync_.registerCallback(boost::bind(increment, &all_received_));
00057     check_synced_timer_ = nh.createWallTimer(ros::WallDuration(30.0),
00058                                              boost::bind(&Anaglyph3D::checkInputsSynchronized, this));
00059   }
00060 
00061   void imageCB(const sensor_msgs::ImageConstPtr& left, const sensor_msgs::ImageConstPtr& right)
00062   {
00063     {
00064       boost::lock_guard<boost::mutex> guard(image_mutex_);
00065     
00066       // Hang on to message pointers for sake of mouse_cb
00067       last_left_ = left;
00068       last_right_ = right;
00069     }
00070 
00071     if (last_left_->encoding == enc::BGR8) {
00072       uint8_t* data_anaglyph = (uint8_t*) calloc(3*last_left_->height*last_left_->width, sizeof(uint8_t));
00073       for(int row = 0; row < last_left_->height; row++)
00074         for(int col = 0; col < last_left_->width; col++) {
00075           data_anaglyph[row*last_right_->step + 3*col + 0] = last_right_->data[row*last_right_->step + 3*col + 0];
00076           data_anaglyph[row*last_right_->step + 3*col + 1] = last_right_->data[row*last_right_->step + 3*col + 1];
00077           data_anaglyph[row*last_left_->step + 3*col + 2] = last_left_->data[row*last_left_->step + 3*col + 2];
00078         }
00079 
00080       fillImage(img_ana_, "bgr8", last_left_->height, last_left_->width, last_left_->step, const_cast<uint8_t*>(data_anaglyph));
00081       pub_anaglyph_.publish(img_ana_);
00082       free(data_anaglyph);
00083     }
00084 
00085 
00086   }
00087 
00088   void checkInputsSynchronized()
00089   {
00090     int threshold = 2 * all_received_;
00091     if (left_received_ > threshold || right_received_ > threshold) {
00092       ROS_WARN("[anaglyph] Low number of synchronized left/right/disparity triplets received.\n"
00093                "Left images received: %d\n"
00094                "Right images received: %d\n"
00095                "Synchronized doublets: %d\n"
00096                "Possible issues:\n"
00097                "\t* stereo_image_proc is not running.\n"
00098                "\t* The cameras are not synchronized.\n"
00099                "\t* The network is too slow. One or more images are dropped from each triplet.",
00100                left_received_, right_received_, all_received_);
00101     }
00102   }
00103 };
00104 
00105 int main(int argc, char **argv)
00106 {
00107   ros::init(argc, argv, "anaglyph", ros::init_options::AnonymousName);
00108   ros::NodeHandle nh;
00109   if (ros::names::remap("stereo") == "stereo") {
00110     ROS_WARN("[stereo_view] stereo has not been remapped! Example command-line usage:\n"
00111              "\t$ rosrun image_view stereo_view stereo:=narrow_stereo image:=image_color");
00112   }
00113   if (ros::names::remap("image") == "/image_raw") {
00114     ROS_WARN("[stereo_view] There is a delay between when the camera drivers publish the raw "
00115              "images and when stereo_image_proc publishes the computed point cloud. stereo_view "
00116              "may fail to synchronize these topics.");
00117   }
00118   
00119   Anaglyph3D ana(nh);
00120   
00121   ros::spin();
00122   return 0;
00123 }


anaglyph
Author(s): Srećko Jurić-Kavelj
autogenerated on Tue Jan 7 2014 11:02:15