Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <ros/node_handle.h>
00016 #include <sensor_msgs/Image.h>
00017 #include <sensor_msgs/CameraInfo.h>
00018 #include <posedetection_msgs/ImageFeature0D.h>
00019 #include <posedetection_msgs/Feature0DDetect.h>
00020 #include <image_transport/image_transport.h>
00021
00022 #include <opencv/highgui.h>
00023 #include <opencv/cv.h>
00024
00025 #include <boost/shared_ptr.hpp>
00026 #include <boost/thread/mutex.hpp>
00027
00028 #include <map>
00029 #include <string>
00030 #include <cstdio>
00031 #include <vector>
00032
00033 #include <cv_bridge/cv_bridge.h>
00034 #include <siftfast/siftfast.h>
00035
00036 using namespace std;
00037 using namespace ros;
00038
00039 class SiftNode
00040 {
00041 boost::mutex _mutex;
00042 ros::NodeHandle _node;
00043 image_transport::ImageTransport _it;
00044 image_transport::Subscriber _subImage;
00045 ros::ServiceServer _srvDetect;
00046 Subscriber _subInfo;
00047 Publisher _pubSift;
00048 posedetection_msgs::ImageFeature0D sift_msg;
00049 bool _bInfoInitialized;
00050 public:
00051 ros::Time lasttime;
00052
00053 SiftNode() : _it(_node)
00054 {
00055 _pubSift = _node.advertise<posedetection_msgs::ImageFeature0D>("ImageFeature0D",1);
00056 usleep(100000);
00057 _subImage = _it.subscribe("image",1,&SiftNode::image_cb,this);
00058 usleep(100000);
00059 _subInfo = _node.subscribe("camera_info",1,&SiftNode::info_cb,this);
00060 usleep(100000);
00061 _srvDetect = _node.advertiseService("Feature0DDetect",&SiftNode::detect_cb,this);
00062 lasttime = ros::Time::now();
00063 _bInfoInitialized = false;
00064 }
00065 virtual ~SiftNode() {
00066 _srvDetect.shutdown();
00067 _subInfo.shutdown();
00068 _subImage.shutdown();
00069 _pubSift.shutdown();
00070 }
00071
00072 void info_cb(const sensor_msgs::CameraInfoConstPtr& msg_ptr)
00073 {
00074 boost::mutex::scoped_lock lock(_mutex);
00075 sift_msg.info = *msg_ptr;
00076 _bInfoInitialized = true;
00077 }
00078
00079 bool detect_cb(posedetection_msgs::Feature0DDetect::Request& req, posedetection_msgs::Feature0DDetect::Response& res)
00080 {
00081 return Detect(res.features,req.image);
00082 }
00083
00084 bool Detect(posedetection_msgs::Feature0D& features, const sensor_msgs::Image& imagemsg)
00085 {
00086 boost::mutex::scoped_lock lock(_mutex);
00087 Image imagesift = NULL;
00088 try {
00089 cv_bridge::CvImagePtr frame, framefloat;
00090 if (!(frame = cv_bridge::toCvCopy(imagemsg, "bgr8")) )
00091 return false;
00092
00093
00094
00095 if (!(framefloat = cv_bridge::toCvCopy(imagemsg, "mono8")) )
00096 return false;
00097
00098
00099 if( imagesift != NULL && (imagesift->cols!=imagemsg.width || imagesift->rows!=imagemsg.height) ) {
00100 ROS_INFO("clear sift resources");
00101 DestroyAllImages();
00102 imagesift = NULL;
00103 }
00104
00105 if( imagesift == NULL )
00106 imagesift = CreateImage(imagemsg.height,imagemsg.width);
00107
00108 for(int i = 0; i < imagemsg.height; ++i) {
00109 uint8_t* psrc = (uint8_t*)framefloat->image.data+framefloat->image.step*i;
00110 float* pdst = imagesift->pixels+i*imagesift->stride;
00111 for(int j = 0; j < imagemsg.width; ++j)
00112 pdst[j] = (float)psrc[j]*(1.0f/255.0f);
00113
00114 }
00115 }
00116 catch (cv_bridge::Exception error) {
00117 ROS_WARN("bad frame");
00118 return false;
00119 }
00120
00121
00122 ros::Time siftbasetime = ros::Time::now();
00123 Keypoint keypts = GetKeypoints(imagesift);
00124
00125 int numkeys = 0;
00126 Keypoint key = keypts;
00127 while(key) {
00128 numkeys++;
00129 key = key->next;
00130 }
00131
00132
00133 features.header = imagemsg.header;
00134 features.positions.resize(numkeys*2);
00135 features.scales.resize(numkeys);
00136 features.orientations.resize(numkeys);
00137 features.confidences.resize(numkeys);
00138 features.descriptors.resize(numkeys*128);
00139 features.descriptor_dim = 128;
00140 features.type = "libsiftfast";
00141
00142 int index = 0;
00143 key = keypts;
00144 while(key) {
00145
00146 for(int j = 0; j < 128; ++j)
00147 features.descriptors[128*index+j] = key->descrip[j];
00148
00149 features.positions[2*index+0] = key->col;
00150 features.positions[2*index+1] = key->row;
00151 features.scales[index] = key->scale;
00152 features.orientations[index] = key->ori;
00153 features.confidences[index] = 1.0;
00154
00155 key = key->next;
00156 ++index;
00157 }
00158
00159 FreeKeypoints(keypts);
00160 DestroyAllImages();
00161
00162 ROS_INFO("imagesift: image: %d(size=%d), num: %d, sift time: %.3fs, total: %.3fs", imagemsg.header.seq,
00163 imagemsg.data.size(), numkeys,
00164 (float)(ros::Time::now()-siftbasetime).toSec(), (float)(ros::Time::now()-lasttime).toSec());
00165 lasttime = ros::Time::now();
00166 return true;
00167 }
00168
00169 void image_cb(const sensor_msgs::ImageConstPtr& msg_ptr)
00170 {
00171 if( _pubSift.getNumSubscribers()==0 ){
00172 ROS_DEBUG("number of subscribers is 0, ignoring image");
00173 return;
00174 }
00175 if( !_bInfoInitialized ) {
00176 ROS_DEBUG("camera info not initialized, ignoring image");
00177 return;
00178 }
00179
00180 Detect(sift_msg.features,*msg_ptr);
00181 sift_msg.image = *msg_ptr;
00182
00183 {
00184 boost::mutex::scoped_lock lock(_mutex);
00185 _pubSift.publish(sift_msg);
00186 }
00187 }
00188 };
00189
00190 int main(int argc, char **argv)
00191 {
00192 ros::init(argc,argv,"imagesift");
00193 if( !ros::master::check() )
00194 return 1;
00195
00196 boost::shared_ptr<SiftNode> siftnode(new SiftNode());
00197
00198 ros::spin();
00199 siftnode.reset();
00200 return 0;
00201 }