compressed_publisher.cpp
Go to the documentation of this file.
00001 #include "compressed_image_transport/compressed_publisher.h"
00002 #include <cv_bridge/cv_bridge.h>
00003 #include <sensor_msgs/image_encodings.h>
00004 #include <cv.h>
00005 #include <highgui.h>
00006 #include <boost/make_shared.hpp>
00007 
00008 #include "compressed_image_transport/compression_common.h"
00009 
00010 #include <vector>
00011 #include <sstream>
00012 
00013 using namespace cv;
00014 using namespace std;
00015 
00016 namespace enc = sensor_msgs::image_encodings;
00017 
00018 namespace compressed_image_transport
00019 {
00020 
00021 void CompressedPublisher::advertiseImpl(ros::NodeHandle &nh, const std::string &base_topic, uint32_t queue_size,
00022                                         const image_transport::SubscriberStatusCallback &user_connect_cb,
00023                                         const image_transport::SubscriberStatusCallback &user_disconnect_cb,
00024                                         const ros::VoidPtr &tracked_object, bool latch)
00025 {
00026   typedef image_transport::SimplePublisherPlugin<sensor_msgs::CompressedImage> Base;
00027   Base::advertiseImpl(nh, base_topic, queue_size, user_connect_cb, user_disconnect_cb, tracked_object, latch);
00028 
00029   // Set up reconfigure server for this topic
00030   reconfigure_server_ = boost::make_shared<ReconfigureServer>(this->nh());
00031   ReconfigureServer::CallbackType f = boost::bind(&CompressedPublisher::configCb, this, _1, _2);
00032   reconfigure_server_->setCallback(f);
00033 }
00034 
00035 void CompressedPublisher::configCb(Config& config, uint32_t level)
00036 {
00037   config_ = config;
00038 }
00039 
00040 void CompressedPublisher::publish(const sensor_msgs::Image& message, const PublishFn& publish_fn) const
00041 {
00042   // Compressed image message
00043   sensor_msgs::CompressedImage compressed;
00044   compressed.header = message.header;
00045   compressed.format = message.encoding;
00046 
00047   // Compression settings
00048   std::vector<int> params;
00049   params.resize(3, 0);
00050 
00051   // Get codec configuration
00052   compressionFormat encodingFormat = UNDEFINED;
00053   if (config_.format == "jpeg")
00054     encodingFormat = JPEG;
00055   if (config_.format == "png")
00056     encodingFormat = PNG;
00057 
00058   // Bit depth of image encoding
00059   int bitDepth = enc::bitDepth(message.encoding);
00060   int numChannels = enc::numChannels(message.encoding);
00061 
00062   switch (encodingFormat)
00063   {
00064     // JPEG Compression
00065     case JPEG:
00066     {
00067       params[0] = CV_IMWRITE_JPEG_QUALITY;
00068       params[1] = config_.jpeg_quality;
00069 
00070       // Update ros message format header
00071       compressed.format += "; jpeg compressed ";
00072 
00073       // Check input format
00074       if ((bitDepth == 8) || (bitDepth == 16))
00075       {
00076         // Target image format
00077         std::string targetFormat;
00078         if (enc::isColor(message.encoding))
00079         {
00080           // convert color images to BGR8 format
00081           targetFormat = "bgr8";
00082           compressed.format += targetFormat;
00083         }
00084 
00085         // OpenCV-ros bridge
00086         cv_bridge::CvImagePtr cv_ptr;
00087         try
00088         {
00089           cv_ptr = cv_bridge::toCvCopy(message, targetFormat);
00090 
00091           // Compress image
00092           if (cv::imencode(".jpg", cv_ptr->image, compressed.data, params))
00093           {
00094 
00095             float cRatio = (float)(cv_ptr->image.rows * cv_ptr->image.cols * cv_ptr->image.elemSize())
00096                 / (float)compressed.data.size();
00097             ROS_DEBUG("Compressed Image Transport - Codec: jpg, Compression Ratio: 1:%.2f (%lu bytes)", cRatio, compressed.data.size());
00098           }
00099           else
00100           {
00101             ROS_ERROR("cv::imencode (jpeg) failed on input image");
00102           }
00103         }
00104         catch (cv_bridge::Exception& e)
00105         {
00106           ROS_ERROR("%s", e.what());
00107         }
00108         catch (cv::Exception& e)
00109         {
00110           ROS_ERROR("%s", e.what());
00111         }
00112 
00113         // Publish message
00114         publish_fn(compressed);
00115       }
00116       else
00117         ROS_ERROR("Compressed Image Transport - JPEG compression requires 8/16-bit color format (input format is: %s)", message.encoding.c_str());
00118 
00119       break;
00120     }
00121       // PNG Compression
00122     case PNG:
00123     {
00124       params[0] = CV_IMWRITE_PNG_COMPRESSION;
00125       params[1] = config_.png_level;
00126 
00127       // Update ros message format header
00128       compressed.format += "; png compressed ";
00129 
00130       // Check input format
00131       if ((bitDepth == 8) || (bitDepth == 16))
00132       {
00133 
00134         // Target image format
00135         stringstream targetFormat;
00136         if (enc::isColor(message.encoding))
00137         {
00138           // convert color images to RGB domain
00139           targetFormat << "bgr" << bitDepth;
00140           compressed.format += targetFormat.str();
00141         }
00142 
00143         // OpenCV-ros bridge
00144         cv_bridge::CvImagePtr cv_ptr;
00145         try
00146         {
00147           cv_ptr = cv_bridge::toCvCopy(message, targetFormat.str());
00148 
00149           // Compress image
00150           if (cv::imencode(".png", cv_ptr->image, compressed.data, params))
00151           {
00152 
00153             float cRatio = (float)(cv_ptr->image.rows * cv_ptr->image.cols * cv_ptr->image.elemSize())
00154                 / (float)compressed.data.size();
00155             ROS_DEBUG("Compressed Image Transport - Codec: png, Compression Ratio: 1:%.2f (%lu bytes)", cRatio, compressed.data.size());
00156           }
00157           else
00158           {
00159             ROS_ERROR("cv::imencode (png) failed on input image");
00160           }
00161         }
00162         catch (cv_bridge::Exception& e)
00163         {
00164           ROS_ERROR("%s", e.what());
00165           return;
00166         }
00167         catch (cv::Exception& e)
00168         {
00169           ROS_ERROR("%s", e.what());
00170           return;
00171         }
00172 
00173         // Publish message
00174         publish_fn(compressed);
00175       }
00176       else
00177         ROS_ERROR("Compressed Image Transport - PNG compression requires 8/16-bit encoded color format (input format is: %s)", message.encoding.c_str());
00178       break;
00179     }
00180 
00181     default:
00182       ROS_ERROR("Unknown compression type '%s', valid options are 'jpeg' and 'png'", config_.format.c_str());
00183       break;
00184   }
00185 
00186 }
00187 
00188 } //namespace compressed_image_transport


compressed_image_transport
Author(s): Patrick Mihelich, Julius Kammerl
autogenerated on Sat Dec 28 2013 17:06:09