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 SparseImageEncoder: public nodelet::Nodelet
00017 {
00018 ros::Publisher _spr_img_pub;
00019 image_transport::Subscriber _img_sub;
00020
00021 jsk_perception::SparseImagePtr _spr_img_ptr;
00022
00023 boost::shared_ptr<image_transport::ImageTransport> _it;
00024 ros::NodeHandle _nh;
00025 ros::NodeHandle _ln;
00026 int _subscriber_count;
00027 double _rate;
00028
00029 void imageCallback(const sensor_msgs::ImageConstPtr& msg){
00030 do_work(msg, msg->header.frame_id);
00031 }
00032
00033 void do_work(const sensor_msgs::ImageConstPtr& msg, const std::string input_frame_from_msg){
00034 try {
00035 int channel = enc::numChannels(msg->encoding);
00036
00037
00038 bool useData32 = false;
00039 if (std::max(msg->width, msg->height) > 256){
00040 useData32 = true;
00041 NODELET_DEBUG("use data32 array");
00042 }
00043
00044 _spr_img_ptr->header.stamp = msg->header.stamp;
00045 _spr_img_ptr->header.frame_id = input_frame_from_msg;
00046 _spr_img_ptr->width = msg->width;
00047 _spr_img_ptr->height = msg->height;
00048 if (!_spr_img_ptr->data16.empty()) _spr_img_ptr->data16.clear();
00049 if (!_spr_img_ptr->data32.empty()) _spr_img_ptr->data32.clear();
00050
00051
00052 for (uint32_t y = 0; y < msg->height; ++y){
00053 for (uint32_t x = 0; x < msg->width; ++x){
00054 if(msg->data[x*channel+y*msg->step] > 125){
00055 if (useData32) _spr_img_ptr->data32.push_back( (x << 16) | y );
00056 else _spr_img_ptr->data16.push_back( (x << 8) | y );
00057 }
00058 }
00059 }
00060
00061
00062 _spr_img_pub.publish(*_spr_img_ptr);
00063 }
00064 catch (...) {
00065 NODELET_ERROR("making sparse image error");
00066 }
00067
00068 ros::Rate pubRate(_rate);
00069 pubRate.sleep();
00070 }
00071
00072 void subscribe() {
00073 NODELET_DEBUG("Subscribing to image topic.");
00074 _img_sub = _it->subscribe("image", 3, &SparseImageEncoder::imageCallback, this);
00075 }
00076
00077 void unsubscribe() {
00078 NODELET_DEBUG("Unsubscribing from image topic.");
00079 _img_sub.shutdown();
00080 }
00081
00082 void connectCb(const ros::SingleSubscriberPublisher& ssp) {
00083 if (_subscriber_count++ == 0) {
00084 subscribe();
00085 }
00086 }
00087
00088 void disconnectCb(const ros::SingleSubscriberPublisher&) {
00089 _subscriber_count--;
00090 if (_subscriber_count == 0) {
00091 unsubscribe();
00092 }
00093 }
00094
00095 public:
00096 void onInit() {
00097 _nh = getNodeHandle();
00098 _ln = ros::NodeHandle("~");
00099 _it.reset(new image_transport::ImageTransport(_nh));
00100 _subscriber_count = 0;
00101 ros::SubscriberStatusCallback connect_cb = boost::bind(&SparseImageEncoder::connectCb, this, _1);
00102 ros::SubscriberStatusCallback disconnect_cb = boost::bind(&SparseImageEncoder::disconnectCb, this, _1);
00103 _spr_img_pub = _nh.advertise<jsk_perception::SparseImage>("sparse_image", 10, connect_cb, disconnect_cb);
00104 _spr_img_ptr = boost::make_shared<jsk_perception::SparseImage>();
00105 _ln.param("rate", _rate, 3.0);
00106 }
00107 };
00108 }
00109
00110 typedef jsk_perception::SparseImageEncoder SparseImageEncoder;
00111 PLUGINLIB_DECLARE_CLASS (jsk_perception, SparseImageEncoder, SparseImageEncoder, nodelet::Nodelet);