imagesurf.cpp
Go to the documentation of this file.
00001 // Copyright (C) 2008 Rosen Diankov (rdiankov@cs.cmu.edu)
00002 //
00003 // This program is free software: you can redistribute it and/or modify
00004 // it under the terms of the GNU Lesser General Public License as published by
00005 // the Free Software Foundation, either version 3 of the License, or
00006 // at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public License
00014 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
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         // compute SURF
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         // write the keys to the output
00113         int numkeys = kp_vec.size();
00114 
00115         // publish
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; // probably copying pointers so don't use af
00162 
00163         {
00164             boost::mutex::scoped_lock lock(_mutex); // needed for camerainfo
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


imagesift
Author(s): Rosen Diankov (rdiankov@cs.cmu.edu), Kei Okada
autogenerated on Sat Mar 23 2013 13:15:06