imagestar.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_MAJOR_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 StarNode
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 _pubStar;
00051     posedetection_msgs::ImageFeature0D star_msg;
00052     bool _bInfoInitialized;
00053 
00054     cv::StarDetector calc_star;
00055 
00056 public:
00057     ros::Time lasttime;
00058 
00059     StarNode() : _it(_node)
00060     { 
00061         _pubStar = _node.advertise<posedetection_msgs::ImageFeature0D>("ImageFeature0D",1);
00062         usleep(100000);
00063         _subImage = _it.subscribe("image",1,&StarNode::image_cb,this);
00064         usleep(100000);
00065         _subInfo = _node.subscribe("camera_info",1,&StarNode::info_cb,this);
00066         usleep(100000);
00067         _srvDetect = _node.advertiseService("Feature0DDetect",&StarNode::detect_cb,this);
00068         calc_star = cv::StarDetector();
00069         lasttime = ros::Time::now();
00070         _bInfoInitialized = false;
00071     }
00072     virtual ~StarNode() {
00073         _srvDetect.shutdown();
00074         _subInfo.shutdown();
00075         _subImage.shutdown();
00076         _pubStar.shutdown();
00077     }
00078 
00079     void info_cb(const sensor_msgs::CameraInfoConstPtr& msg_ptr)
00080     {
00081         boost::mutex::scoped_lock lock(_mutex);
00082         star_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 STAR
00107         ros::Time starbasetime = ros::Time::now();
00108         vector<cv::KeyPoint> kp_vec;
00109         cv::Mat desc_mat;
00110         calc_star(grayImage,kp_vec);
00111 
00112         // compute SURF description
00113         cv::DescriptorExtractor *de;
00114         //de = new cv::SurfDescriptorExtractor/*( int nOctaves=4, int nOctaveLayers=2, bool extended=false )*/;
00115         de->compute(grayImage,kp_vec,desc_mat);
00116 
00117         // write the keys to the output
00118         int numkeys = kp_vec.size();
00119 
00120         // publish
00121         features.header = imagemsg.header;
00122         features.positions.resize(numkeys*2);
00123         features.scales.resize(numkeys);
00124         features.orientations.resize(numkeys);
00125         features.confidences.resize(numkeys);
00126         features.descriptors.resize(numkeys*64);
00127         features.descriptor_dim = 64;
00128         features.type = "opencv_star";
00129 
00130         int index = 0;
00131         vector<cv::KeyPoint>::iterator key = kp_vec.begin(), key_end = kp_vec.end();
00132         for(; key != key_end; ++key) {
00133 
00134             for(int j = 0; j < 64; ++j)
00135                 features.descriptors[64*index+j] = desc_mat.at<float>(index,j);
00136 
00137             features.positions[2*index+0] = key->pt.x;
00138             features.positions[2*index+1] = key->pt.y;
00139             features.scales[index] = key->size;
00140             features.orientations[index] = key->angle;
00141             features.confidences[index] = key->response;
00142 
00143             ++index;
00144         }
00145 
00146         ROS_INFO("imagestar: image: %d(size=%d), num: %d, star time: %.3fs, total: %.3fs", (int)imagemsg.header.seq,
00147                  (int)imagemsg.data.size(),  (int)numkeys,
00148                  (float)(ros::Time::now()-starbasetime).toSec(), (float)(ros::Time::now()-lasttime).toSec());
00149 
00150         lasttime = ros::Time::now();
00151         return true;
00152     }
00153 
00154     void image_cb(const sensor_msgs::ImageConstPtr& msg_ptr)
00155     {
00156         if( _pubStar.getNumSubscribers()==0 ){ 
00157             ROS_DEBUG("number of subscribers is 0, ignoring image");
00158             return;
00159         }
00160         if( !_bInfoInitialized ) {
00161             ROS_DEBUG("camera info not initialized, ignoring image");
00162             return;
00163         }
00164 
00165         Detect(star_msg.features,*msg_ptr);
00166         star_msg.image = *msg_ptr; // probably copying pointers so don't use af
00167 
00168         {
00169             boost::mutex::scoped_lock lock(_mutex); // needed for camerainfo
00170             _pubStar.publish(star_msg);
00171         }
00172     }
00173 };
00174 
00175 int main(int argc, char **argv)
00176 {
00177     ros::init(argc,argv,"imagestar");
00178     if( !ros::master::check() )
00179         return 1;
00180     
00181     boost::shared_ptr<StarNode> starnode(new StarNode());
00182     
00183     ros::spin();
00184     starnode.reset();
00185     return 0;
00186 }
 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