Go to the documentation of this file.00001 #include "web_video_server/image_streamer.h"
00002 #include <cv_bridge/cv_bridge.h>
00003 #include <iostream>
00004
00005 namespace web_video_server
00006 {
00007
00008 ImageStreamer::ImageStreamer(const async_web_server_cpp::HttpRequest &request,
00009 async_web_server_cpp::HttpConnectionPtr connection, ros::NodeHandle& nh) :
00010 request_(request), connection_(connection), nh_(nh), inactive_(false)
00011 {
00012 topic_ = request.get_query_param_value_or_default("topic", "");
00013 }
00014
00015 ImageStreamer::~ImageStreamer()
00016 {
00017 }
00018
00019 ImageTransportImageStreamer::ImageTransportImageStreamer(const async_web_server_cpp::HttpRequest &request,
00020 async_web_server_cpp::HttpConnectionPtr connection, ros::NodeHandle& nh) :
00021 ImageStreamer(request, connection, nh), it_(nh), initialized_(false)
00022 {
00023 output_width_ = request.get_query_param_value_or_default<int>("width", -1);
00024 output_height_ = request.get_query_param_value_or_default<int>("height", -1);
00025 invert_ = request.has_query_param("invert");
00026 default_transport_ = request.get_query_param_value_or_default("default_transport", "raw");
00027 }
00028
00029 ImageTransportImageStreamer::~ImageTransportImageStreamer()
00030 {
00031 }
00032
00033 void ImageTransportImageStreamer::start()
00034 {
00035 image_transport::TransportHints hints(default_transport_);
00036 ros::master::V_TopicInfo available_topics;
00037 ros::master::getTopics(available_topics);
00038 inactive_ = true;
00039 for (size_t it = 0; it<available_topics.size(); it++){
00040 std::string available_topic_name = available_topics[it].name;
00041 if(available_topic_name == topic_ || (available_topic_name.find("/") == 0 &&
00042 available_topic_name.substr(1) == topic_)) {
00043 inactive_ = false;
00044 }
00045 }
00046 image_sub_ = it_.subscribe(topic_, 1, &ImageTransportImageStreamer::imageCallback, this, hints);
00047 }
00048
00049 void ImageTransportImageStreamer::initialize(const cv::Mat &)
00050 {
00051 }
00052
00053 void ImageTransportImageStreamer::restreamFrame(double max_age)
00054 {
00055 if (inactive_ || !initialized_ )
00056 return;
00057 try {
00058 if ( last_frame + ros::Duration(max_age) < ros::Time::now() ) {
00059 boost::mutex::scoped_lock lock(send_mutex_);
00060 sendImage(output_size_image, ros::Time::now() );
00061 }
00062 }
00063 catch (boost::system::system_error &e)
00064 {
00065
00066 ROS_DEBUG("system_error exception: %s", e.what());
00067 inactive_ = true;
00068 return;
00069 }
00070 catch (std::exception &e)
00071 {
00072 ROS_ERROR_THROTTLE(30, "exception: %s", e.what());
00073 inactive_ = true;
00074 return;
00075 }
00076 catch (...)
00077 {
00078 ROS_ERROR_THROTTLE(30, "exception");
00079 inactive_ = true;
00080 return;
00081 }
00082 }
00083
00084 void ImageTransportImageStreamer::imageCallback(const sensor_msgs::ImageConstPtr &msg)
00085 {
00086 if (inactive_)
00087 return;
00088
00089 cv::Mat img;
00090 try
00091 {
00092 if (msg->encoding.find("F") != std::string::npos)
00093 {
00094
00095 cv::Mat float_image_bridge = cv_bridge::toCvCopy(msg, msg->encoding)->image;
00096 cv::Mat_<float> float_image = float_image_bridge;
00097 double max_val;
00098 cv::minMaxIdx(float_image, 0, &max_val);
00099
00100 if (max_val > 0)
00101 {
00102 float_image *= (255 / max_val);
00103 }
00104 img = float_image;
00105 }
00106 else
00107 {
00108
00109 img = cv_bridge::toCvCopy(msg, "bgr8")->image;
00110 }
00111
00112 int input_width = img.cols;
00113 int input_height = img.rows;
00114
00115 if (output_width_ == -1)
00116 output_width_ = input_width;
00117 if (output_height_ == -1)
00118 output_height_ = input_height;
00119
00120 if (invert_)
00121 {
00122
00123 cv::flip(img, img, false);
00124 cv::flip(img, img, true);
00125 }
00126
00127 boost::mutex::scoped_lock lock(send_mutex_);
00128 if (output_width_ != input_width || output_height_ != input_height)
00129 {
00130 cv::Mat img_resized;
00131 cv::Size new_size(output_width_, output_height_);
00132 cv::resize(img, img_resized, new_size);
00133 output_size_image = img_resized;
00134 }
00135 else
00136 {
00137 output_size_image = img;
00138 }
00139
00140 if (!initialized_)
00141 {
00142 initialize(output_size_image);
00143 initialized_ = true;
00144 }
00145
00146 last_frame = ros::Time::now();
00147 sendImage(output_size_image, last_frame );
00148
00149 }
00150 catch (cv_bridge::Exception &e)
00151 {
00152 ROS_ERROR_THROTTLE(30, "cv_bridge exception: %s", e.what());
00153 inactive_ = true;
00154 return;
00155 }
00156 catch (cv::Exception &e)
00157 {
00158 ROS_ERROR_THROTTLE(30, "cv_bridge exception: %s", e.what());
00159 inactive_ = true;
00160 return;
00161 }
00162 catch (boost::system::system_error &e)
00163 {
00164
00165 ROS_DEBUG("system_error exception: %s", e.what());
00166 inactive_ = true;
00167 return;
00168 }
00169 catch (std::exception &e)
00170 {
00171 ROS_ERROR_THROTTLE(30, "exception: %s", e.what());
00172 inactive_ = true;
00173 return;
00174 }
00175 catch (...)
00176 {
00177 ROS_ERROR_THROTTLE(30, "exception");
00178 inactive_ = true;
00179 return;
00180 }
00181 }
00182
00183 }