Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <ros/node_handle.h>
00017 #include <sensor_msgs/Image.h>
00018 #include <sensor_msgs/CameraInfo.h>
00019 #include <posedetection_msgs/ImageFeature0D.h>
00020 #include <posedetection_msgs/Feature0DDetect.h>
00021 #include <image_transport/image_transport.h>
00022
00023 #include <opencv/highgui.h>
00024 #include <opencv/cv.h>
00025 #if (CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >= 4)
00026 #include <opencv2/nonfree/nonfree.hpp>
00027 #endif
00028
00029 #include <boost/shared_ptr.hpp>
00030 #include <boost/thread/mutex.hpp>
00031
00032 #include <map>
00033 #include <string>
00034 #include <cstdio>
00035 #include <vector>
00036
00037 #include <cv_bridge/cv_bridge.h>
00038
00039 using namespace std;
00040 using namespace ros;
00041
00042 class SurfNode
00043 {
00044 boost::mutex _mutex;
00045 ros::NodeHandle _node;
00046 image_transport::ImageTransport _it;
00047 image_transport::Subscriber _subImage;
00048 ros::ServiceServer _srvDetect;
00049 Subscriber _subInfo;
00050 Publisher _pubSurf;
00051 posedetection_msgs::ImageFeature0D surf_msg;
00052 bool _bInfoInitialized;
00053
00054 cv::SURF calc_surf;
00055
00056 public:
00057 ros::Time lasttime;
00058
00059 SurfNode() : _it(_node)
00060 {
00061 _pubSurf = _node.advertise<posedetection_msgs::ImageFeature0D>("ImageFeature0D",1);
00062 usleep(100000);
00063 _subImage = _it.subscribe("image",1,&SurfNode::image_cb,this);
00064 usleep(100000);
00065 _subInfo = _node.subscribe("camera_info",1,&SurfNode::info_cb,this);
00066 usleep(100000);
00067 _srvDetect = _node.advertiseService("Feature0DDetect",&SurfNode::detect_cb,this);
00068 calc_surf = cv::SURF(500,4,2,true);
00069 lasttime = ros::Time::now();
00070 _bInfoInitialized = false;
00071 }
00072 virtual ~SurfNode() {
00073 _srvDetect.shutdown();
00074 _subInfo.shutdown();
00075 _subImage.shutdown();
00076 _pubSurf.shutdown();
00077 }
00078
00079 void info_cb(const sensor_msgs::CameraInfoConstPtr& msg_ptr)
00080 {
00081 boost::mutex::scoped_lock lock(_mutex);
00082 surf_msg.info = *msg_ptr;
00083 _bInfoInitialized = true;
00084 }
00085
00086 bool detect_cb(posedetection_msgs::Feature0DDetect::Request& req, posedetection_msgs::Feature0DDetect::Response& res)
00087 {
00088 return Detect(res.features,req.image);
00089 }
00090
00091 bool Detect(posedetection_msgs::Feature0D& features, const sensor_msgs::Image& imagemsg)
00092 {
00093 boost::mutex::scoped_lock lock(_mutex);
00094 cv::Mat grayImage;
00095 try {
00096 cv_bridge::CvImagePtr frame;
00097 if (!(frame = cv_bridge::toCvCopy(imagemsg, "mono8")) )
00098 return false;
00099 grayImage = frame->image;
00100 }
00101 catch (cv_bridge::Exception error) {
00102 ROS_WARN("bad frame");
00103 return false;
00104 }
00105
00106
00107 ros::Time surfbasetime = ros::Time::now();
00108 vector<cv::KeyPoint> kp_vec;
00109 vector<float> desc_vec;
00110 calc_surf(grayImage,cv::Mat(),kp_vec,desc_vec);
00111
00112
00113 int numkeys = kp_vec.size();
00114
00115
00116 features.header = imagemsg.header;
00117 features.positions.resize(numkeys*2);
00118 features.scales.resize(numkeys);
00119 features.orientations.resize(numkeys);
00120 features.confidences.resize(numkeys);
00121 features.descriptors.resize(numkeys*128);
00122 features.descriptor_dim = 128;
00123 features.type = "opencv_surf";
00124
00125 int index = 0;
00126 vector<cv::KeyPoint>::iterator key = kp_vec.begin(), key_end = kp_vec.end();
00127 for(; key != key_end; ++key) {
00128
00129 for(int j = 0; j < 128; ++j)
00130 features.descriptors[128*index+j] = desc_vec[128*index+j];
00131
00132 features.positions[2*index+0] = key->pt.x;
00133 features.positions[2*index+1] = key->pt.y;
00134 features.scales[index] = key->size;
00135 features.orientations[index] = key->angle;
00136 features.confidences[index] = key->response;
00137
00138 ++index;
00139 }
00140
00141 ROS_INFO("imagesurf: image: %d(size=%d), num: %d, surf time: %.3fs, total: %.3fs", (int)imagemsg.header.seq,
00142 (int)imagemsg.data.size(), (int)numkeys,
00143 (float)(ros::Time::now()-surfbasetime).toSec(), (float)(ros::Time::now()-lasttime).toSec());
00144
00145 lasttime = ros::Time::now();
00146 return true;
00147 }
00148
00149 void image_cb(const sensor_msgs::ImageConstPtr& msg_ptr)
00150 {
00151 if( _pubSurf.getNumSubscribers()==0 ){
00152 ROS_DEBUG("number of subscribers is 0, ignoring image");
00153 return;
00154 }
00155 if( !_bInfoInitialized ) {
00156 ROS_DEBUG("camera info not initialized, ignoring image");
00157 return;
00158 }
00159
00160 Detect(surf_msg.features,*msg_ptr);
00161 surf_msg.image = *msg_ptr;
00162
00163 {
00164 boost::mutex::scoped_lock lock(_mutex);
00165 _pubSurf.publish(surf_msg);
00166 }
00167 }
00168 };
00169
00170 int main(int argc, char **argv)
00171 {
00172 ros::init(argc,argv,"imagesurf");
00173 if( !ros::master::check() )
00174 return 1;
00175
00176 boost::shared_ptr<SurfNode> surfnode(new SurfNode());
00177
00178 ros::spin();
00179 surfnode.reset();
00180 return 0;
00181 }