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_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
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
00113 cv::DescriptorExtractor *de;
00114
00115 de->compute(grayImage,kp_vec,desc_mat);
00116
00117
00118 int numkeys = kp_vec.size();
00119
00120
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;
00167
00168 {
00169 boost::mutex::scoped_lock lock(_mutex);
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 }