35 #include <boost/endian/arithmetic.hpp> 39 #include <opencv2/highgui/highgui.hpp> 40 #include <opencv2/imgproc/imgproc.hpp> 41 #include <turbojpeg.h> 55 CompressedSubscriber::CompressedSubscriber()
70 Base::subscribeImpl(nh, base_topic, queue_size, callback, tracked_object, transport_hints);
82 if (
config_.mode == compressed_image_transport::CompressedSubscriber_gray) {
84 }
else if (
config_.mode == compressed_image_transport::CompressedSubscriber_color) {
100 tj_ = tjInitDecompress();
102 int width, height, jpegSub, jpegColor;
105 uint8_t* src =
const_cast<uint8_t*
>(data.data());
107 if (tjDecompressHeader3(
tj_, src, data.size(), &width, &height, &jpegSub, &jpegColor) != 0)
108 return sensor_msgs::ImagePtr();
110 sensor_msgs::ImagePtr ret(
new sensor_msgs::Image);
111 ret->header = header;
113 ret->height = height;
114 ret->encoding = source_encoding;
116 ret->is_bigendian = (boost::endian::order::native == boost::endian::order::big);
120 if (source_encoding == enc::MONO8)
122 ret->data.resize(height*width);
123 ret->step = ret->width;
124 pixelFormat = TJPF_GRAY;
126 else if (source_encoding == enc::RGB8)
128 ret->data.resize(height*width*3);
130 pixelFormat = TJPF_RGB;
132 else if (source_encoding == enc::BGR8)
134 ret->data.resize(height*width*3);
136 pixelFormat = TJPF_BGR;
138 else if (source_encoding == enc::RGBA8)
140 ret->data.resize(height*width*4);
142 pixelFormat = TJPF_RGBA;
144 else if (source_encoding == enc::BGRA8)
146 ret->data.resize(height*width*4);
148 pixelFormat = TJPF_BGRA;
150 else if (source_encoding.empty())
153 if(jpegColor == TJCS_GRAY)
155 ret->data.resize(height*width);
157 ret->encoding = enc::MONO8;
158 pixelFormat = TJPF_GRAY;
162 ret->data.resize(height*width*3);
164 ret->encoding = enc::RGB8;
165 pixelFormat = TJPF_RGB;
170 ROS_WARN_THROTTLE(10.0,
"Encountered a source encoding that is not supported by TurboJPEG: '%s'", source_encoding.c_str());
171 return sensor_msgs::ImagePtr();
174 if (tjDecompress2(
tj_, src, data.size(), ret->data.data(), width, 0, height, pixelFormat, 0) != 0)
176 ROS_WARN_THROTTLE(10.0,
"Could not decompress data using TurboJPEG, falling back to OpenCV");
177 return sensor_msgs::ImagePtr();
188 std::string image_encoding;
189 std::string compressed_encoding;
191 const size_t split_pos = message->format.find(
';');
192 if (split_pos != std::string::npos)
194 image_encoding = message->format.substr(0, split_pos);
195 compressed_encoding = message->format.substr(split_pos);
200 if(message->data.size() > 4 && message->data[0] == 0xFF && message->data[1] == 0xD8)
202 sensor_msgs::ImagePtr decoded =
decompressJPEG(message->data, image_encoding, message->header);
214 cv_ptr->header = message->header;
219 cv_ptr->image = cv::imdecode(cv::Mat(message->data),
imdecode_flag_);
222 if (image_encoding.empty())
225 switch (cv_ptr->image.channels())
228 cv_ptr->encoding = enc::MONO8;
231 cv_ptr->encoding = enc::BGR8;
234 ROS_ERROR(
"Unsupported number of channels: %i", cv_ptr->image.channels());
239 cv_ptr->encoding = image_encoding;
241 if ( enc::isColor(image_encoding))
243 bool compressed_bgr_image = (compressed_encoding.find(
"compressed bgr") != std::string::npos);
246 if (compressed_bgr_image)
249 if ((image_encoding == enc::RGB8) || (image_encoding == enc::RGB16))
250 cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_BGR2RGB);
252 if ((image_encoding == enc::RGBA8) || (image_encoding == enc::RGBA16))
253 cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_BGR2RGBA);
255 if ((image_encoding == enc::BGRA8) || (image_encoding == enc::BGRA16))
256 cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_BGR2BGRA);
260 if ((image_encoding == enc::BGR8) || (image_encoding == enc::BGR16))
261 cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_RGB2BGR);
263 if ((image_encoding == enc::BGRA8) || (image_encoding == enc::BGRA16))
264 cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_RGB2BGRA);
266 if ((image_encoding == enc::RGBA8) || (image_encoding == enc::RGBA16))
267 cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_RGB2RGBA);
272 catch (cv::Exception& e)
277 size_t rows = cv_ptr->image.rows;
278 size_t cols = cv_ptr->image.cols;
280 if ((rows > 0) && (cols > 0))
282 user_cb(cv_ptr->toImageMsg());
sensor_msgs::ImagePtr decompressJPEG(const std::vector< uint8_t > &data, const std::string &source_encoding, const std_msgs::Header &header)
compressed_image_transport::CompressedSubscriberConfig Config
boost::function< void(const sensor_msgs::ImageConstPtr &)> Callback
const ros::NodeHandle & nh() const
virtual void subscribeImpl(ros::NodeHandle &nh, const std::string &base_topic, uint32_t queue_size, const Callback &callback, const ros::VoidPtr &tracked_object, const image_transport::TransportHints &transport_hints)
#define ROS_WARN_THROTTLE(period,...)
virtual void internalCallback(const sensor_msgs::CompressedImageConstPtr &message, const Callback &user_cb)
virtual ~CompressedSubscriber()
void configCb(Config &config, uint32_t level)
boost::shared_ptr< ReconfigureServer > reconfigure_server_