Go to the documentation of this file.00001 #include <stdint.h>
00002 #include <boost/shared_ptr.hpp>
00003 #include <vector>
00004 #include <iostream>
00005
00006 #include <nodelet/nodelet.h>
00007 #include <image_transport/image_transport.h>
00008 #include <pluginlib/class_list_macros.h>
00009 #include <sensor_msgs/image_encodings.h>
00010 #include <jsk_perception/SparseImage.h>
00011
00012
00013 namespace enc = sensor_msgs::image_encodings;
00014
00015 namespace jsk_perception {
00016 class SparseImageDecoder: public nodelet::Nodelet
00017 {
00018 image_transport::Publisher _img_pub;
00019 ros::Subscriber _spr_img_sub;
00020
00021 sensor_msgs::ImagePtr _img_ptr;
00022
00023 boost::shared_ptr<image_transport::ImageTransport> _it;
00024 ros::NodeHandle _nh;
00025 int _subscriber_count;
00026
00027 void imageCallback(const jsk_perception::SparseImageConstPtr& msg){
00028 do_work(msg, msg->header.frame_id);
00029 }
00030
00031 void do_work(const jsk_perception::SparseImageConstPtr& msg, const std::string input_frame_from_msg){
00032 try {
00033
00034 _img_ptr->header.stamp = msg->header.stamp;
00035 _img_ptr->header.frame_id = input_frame_from_msg;
00036 _img_ptr->width = msg->width;
00037 _img_ptr->height = msg->height;
00038 _img_ptr->step = msg->width;
00039 _img_ptr->encoding = enc::MONO8;
00040 if (!_img_ptr->data.empty()) _img_ptr->data.clear();
00041
00042
00043 bool useData32 = false;
00044 int length = msg->data16.size();
00045 if (length <= 0) {
00046 useData32 = true;
00047 length = msg->data32.size();
00048 NODELET_DEBUG("use data32 array");
00049 }
00050 _img_ptr->data.resize(_img_ptr->width * _img_ptr->height);
00051
00052 for (int i = 0; i < length; ++i){
00053 uint16_t x, y;
00054 if (useData32) {
00055 uint32_t pos = msg->data32[i];
00056 x = (uint16_t)(pos >> 16);
00057 y = (uint16_t)pos;
00058 } else {
00059 uint16_t pos = msg->data16[i];
00060 x = (uint16_t)(pos >> 8);
00061 y = (uint16_t)(pos & (uint8_t)-1);
00062 }
00063 _img_ptr->data[y * _img_ptr->width + x] = 255;
00064 }
00065
00066
00067 _img_pub.publish(*_img_ptr);
00068 }
00069 catch (...) {
00070 NODELET_ERROR("making sparse image error");
00071 }
00072 }
00073
00074 void subscribe() {
00075 NODELET_DEBUG("Subscribing to image topic.");
00076 _spr_img_sub = _nh.subscribe("sparse_image", 3, &SparseImageDecoder::imageCallback, this);
00077 }
00078
00079 void unsubscribe() {
00080 NODELET_DEBUG("Unsubscribing from image topic.");
00081 _spr_img_sub.shutdown();
00082 }
00083
00084 void connectCb(const image_transport::SingleSubscriberPublisher& ssp) {
00085 if (_subscriber_count++ == 0) {
00086 subscribe();
00087 }
00088 }
00089
00090 void disconnectCb(const image_transport::SingleSubscriberPublisher&) {
00091 _subscriber_count--;
00092 if (_subscriber_count == 0) {
00093 unsubscribe();
00094 }
00095 }
00096
00097 public:
00098 void onInit() {
00099 _nh = getNodeHandle();
00100 _img_ptr.reset(new sensor_msgs::Image());
00101 _it.reset(new image_transport::ImageTransport(_nh));
00102 _subscriber_count = 0;
00103 image_transport::SubscriberStatusCallback connect_cb = boost::bind(&SparseImageDecoder::connectCb, this, _1);
00104 image_transport::SubscriberStatusCallback disconnect_cb = boost::bind(&SparseImageDecoder::disconnectCb, this, _1);
00105 _img_pub = image_transport::ImageTransport(ros::NodeHandle(_nh, "sparse")).advertise("image_decoded", 1, connect_cb, disconnect_cb);
00106 }
00107 };
00108 }
00109
00110 typedef jsk_perception::SparseImageDecoder SparseImageDecoder;
00111 PLUGINLIB_DECLARE_CLASS (jsk_perception, SparseImageDecoder, SparseImageDecoder, nodelet::Nodelet);