tracking_eval_node.cpp
Go to the documentation of this file.
00001 
00060 //##################
00061 //#### includes ####
00062 
00063 #include <munkres/munkres.h>
00064 
00065 // standard includes
00066 //--
00067 
00068 // ROS includes
00069 #include <ros/ros.h>
00070 #include <ros/package.h>
00071 
00072 // ROS message includes
00073 #include <sensor_msgs/Image.h>
00074 //#include <sensor_msgs/PointCloud2.h>
00075 #include <cob_perception_msgs/DetectionArray.h>
00076 
00077 // services
00078 //#include <cob_people_detection/DetectPeople.h>
00079 
00080 // topics
00081 #include <message_filters/subscriber.h>
00082 #include <message_filters/synchronizer.h>
00083 #include <message_filters/sync_policies/approximate_time.h>
00084 #include <image_transport/image_transport.h>
00085 #include <image_transport/subscriber_filter.h>
00086 
00087 // opencv
00088 #include <opencv/cv.h>
00089 #include <opencv/highgui.h>
00090 #include <cv_bridge/cv_bridge.h>
00091 #include <sensor_msgs/image_encodings.h>
00092 
00093 // boost
00094 #include <boost/bind.hpp>
00095 #include <boost/thread/mutex.hpp>
00096 #include <boost/lexical_cast.hpp>
00097 
00098 // external includes
00099 #include "cob_vision_utils/GlobalDefines.h"
00100 
00101 #include <sstream>
00102 #include <string>
00103 #include <vector>
00104 
00105 class EvalObj
00106 {
00107 public:
00108         ros::Time timestamp;
00109         std::vector<geometry_msgs::Point> positions;
00110         std::vector<std::string> labels;
00111         EvalObj()
00112         {
00113         }
00114         void print()
00115         {
00116                 std::cout << "-----------------------------" << std::endl;
00117                 std::cout << "Timestamp:\n" << timestamp << std::endl;
00118                 std::cout << "Positions:" << std::endl;
00119                 for (int i = 0; i < positions.size(); i++)
00120                 {
00121                         std::cout << positions[i].x << " " << positions[i].y << std::endl;
00122                         ;
00123                 }
00124                 std::cout << "Labels:" << std::endl;
00125                 for (int i = 0; i < labels.size(); i++)
00126                 {
00127                         std::cout << labels[i] << std::endl;
00128                         ;
00129                 }
00130                 std::cout << "-----------------------------" << std::endl;
00131         }
00132 
00133         bool compare(EvalObj& cmp, std::string& gt, bool& this_corr, bool& cmp_corr)
00134         {
00135                 if (cmp.timestamp != this->timestamp)
00136                 {
00137                         std::cout << "time discrepancy - skipping comparison" << std::endl;
00138                         return false;
00139                 }
00140                 else
00141                 {
00142                         // find out matching detections by comparing position
00143                         float dist = 100000;
00144                         std::vector<int> index_arr;
00145                         index_arr.resize(this->labels.size());
00146                         if (this->labels.size() == 0)
00147                         {
00148                                 std::cout << "empty label array...." << std::endl;
00149                                 return false;
00150                         }
00151                         if (cmp.labels.size() == 0)
00152                         {
00153                                 std::cout << "empty label array...." << std::endl;
00154                                 return false;
00155                         }
00156                         for (int i = 0; i < this->labels.size(); i++)
00157                         {
00158                                 for (int j = 0; j < cmp.labels.size(); j++)
00159                                 {
00160                                         //calc distance
00161                                         float tmp_dist = (cmp.positions[i].x - this->positions[j].x) * (cmp.positions[i].x - this->positions[j].y) + (cmp.positions[i].y - this->positions[j].y)
00162                                                         * (cmp.positions[i].y - this->positions[j].y);
00163                                         if (tmp_dist < dist)
00164                                         {
00165                                                 dist = tmp_dist;
00166                                                 index_arr[i] = j;
00167                                         }
00168                                 }
00169                         }
00170                         //for(int p = 0;p<index_arr.size();++p)
00171                         //{
00172                         //std::cout<<index_arr[p]<<std::endl;
00173                         //}
00174                         //
00175                         //  compare labels of matches
00176                         this_corr = true;
00177                         cmp_corr = true;
00178                         for (int i; i < index_arr.size(); i++)
00179                         {
00180                                 std::string a = boost::lexical_cast<std::string>(this->labels[i]);
00181                                 std::string b = boost::lexical_cast<std::string>(cmp.labels[index_arr[i]]);
00182                                 std::cout << a << ": " << gt.compare(a) << " - " << b << ": " << gt.compare(b) << std::endl;
00183                                 if (a.compare("UnknownHead") == 0 || b.compare("UnknownHead") == 0)
00184                                 {
00185                                         std::cout << "discarding" << std::endl;
00186                                         return false;
00187                                 }
00188                                 //
00189                                 if (a.compare(gt) != 0)
00190                                         this_corr = false;
00191                                 if (b.compare(gt) != 0)
00192                                         cmp_corr = false;
00193 
00194                         }
00195 
00196                 }
00197                 return true;
00198         }
00199 };
00200 
00201 class TrackingEvalNode
00202 {
00203 public:
00204 
00205         EvalObj eval_rec_;
00206         EvalObj eval_track_;
00207         bool rec_track;
00208         bool rec_rec;
00209         std::string gt_name_;
00210 
00211         int correct_trackings_;
00212         int correct_recognitions_;
00213         int total_comparisons_;
00214         int tracking_improvement_;
00215         int tracking_decline_;
00216         int error_out_;
00217 
00218         ros::Subscriber recognition_subscriber_;
00219         ros::Subscriber tracking_subscriber_;
00220         ros::NodeHandle node_handle_;
00221 
00222         TrackingEvalNode(ros::NodeHandle nh) :
00223                 node_handle_(nh), correct_trackings_(0), correct_recognitions_(0), total_comparisons_(0), error_out_(0), tracking_improvement_(0), tracking_decline_(0), rec_track(false),
00224                                 rec_rec(false)
00225         {
00226 
00227                 // subscribers
00228                 recognition_subscriber_ = node_handle_.subscribe("/cob_people_detection/face_recognizer/face_recognitions", 1, &TrackingEvalNode::recognitionCallback, this);
00229                 tracking_subscriber_ = node_handle_.subscribe("/cob_people_detection/detection_tracker/face_position_array", 1, &TrackingEvalNode::trackingCallback, this);
00230 
00231                 // parameters
00232                 if (!node_handle_.getParam("/cob_people_detection/tracking_evaluator/person", gt_name_))
00233                         std::cout << "PARAM NOT AVAILABLE" << std::endl;
00234                 std::cout << "Groundtruth name: " << gt_name_ << "\n";
00235 
00236         }
00237 
00238         ~TrackingEvalNode()
00239         {
00240         }
00241 
00242         double computeFacePositionDistance(const cob_perception_msgs::Detection& previous_detection, const cob_perception_msgs::Detection& current_detection)
00243         {
00244                 const geometry_msgs::Point* point_1 = &(previous_detection.pose.pose.position);
00245                 const geometry_msgs::Point* point_2 = &(current_detection.pose.pose.position);
00246 
00247                 double dx = point_1->x - point_2->x;
00248                 double dy = point_1->y - point_2->y;
00249                 double dz = point_1->z - point_2->z;
00250 
00251                 return sqrt(dx * dx + dy * dy + dz * dz);
00252         }
00253 
00255         void trackingCallback(const cob_perception_msgs::DetectionArray::ConstPtr& face_position_msg_in)
00256         {
00257                 //std::cout<<"Callback TRACKING running..."<<std::endl;
00258 
00259                 EvalObj eval_obj;
00260                 eval_obj.timestamp = face_position_msg_in->header.stamp;
00261                 // put timestamp, position and label in vector
00262                 //std::cout<<"----> tracking: det_size="<<face_position_msg_in->detections.size()<<std::endl;
00263                 for (unsigned int i = 0; i < face_position_msg_in->detections.size(); i++)
00264                 {
00265                         if (face_position_msg_in->detections[i].label.compare("") != 0)
00266                         {
00267                                 //std::cout<<"      t label="<<face_position_msg_in->detections[i].label<<std::endl;
00268                                 eval_obj.positions.push_back(face_position_msg_in->detections[i].pose.pose.position);
00269                                 eval_obj.labels.push_back(face_position_msg_in->detections[i].label);
00270                         }
00271                 }
00272                 eval_track_ = eval_obj;
00273                 rec_track = true;
00274                 this->eval();
00275         }
00277         void recognitionCallback(const cob_perception_msgs::DetectionArray::ConstPtr& face_position_msg_in)
00278         {
00279                 //std::cout<<"Callback running..."<<std::endl;
00280 
00281                 EvalObj eval_obj;
00282                 eval_obj.timestamp = face_position_msg_in->header.stamp;
00283                 // put timestamp, position and label in vector
00284                 //std::cout<<"----> recognition: det_size="<<face_position_msg_in->detections.size()<<std::endl;
00285                 for (unsigned int i = 0; i < face_position_msg_in->detections.size(); i++)
00286                 {
00287                         if (face_position_msg_in->detections[i].label.compare("") != 0)
00288                         {
00289                                 //std::cout<<"      r label="<<face_position_msg_in->detections[i].label<<std::endl;
00290                                 eval_obj.positions.push_back(face_position_msg_in->detections[i].pose.pose.position);
00291                                 eval_obj.labels.push_back(face_position_msg_in->detections[i].label);
00292                         }
00293                 }
00294                 eval_rec_ = eval_obj;
00295                 rec_rec = true;
00296                 this->eval();
00297         }
00298 
00299         void eval()
00300         {
00301                 if (rec_track == true && rec_rec == true)
00302                 {
00303                         //std::cout<<"time rec= "<<eval_rec_.timestamp<<std::endl;
00304                         //std::cout<<"time track= "<<eval_track_.timestamp<<std::endl;
00305                         if (eval_track_.timestamp == eval_rec_.timestamp)
00306                         {
00307                                 //std::cout<<"EVAL-->"<<std::endl;
00308                                 bool rec_res, track_res;
00309                                 bool cmp_successful = eval_rec_.compare(eval_track_, gt_name_, rec_res, track_res);
00310                                 if (cmp_successful)
00311                                 {
00312                                         if (rec_res)
00313                                                 correct_recognitions_++;
00314                                         if (track_res)
00315                                                 correct_trackings_++;
00316                                         if (track_res && !rec_res)
00317                                                 tracking_improvement_++;
00318                                         if (!track_res && rec_res)
00319                                                 tracking_decline_++;
00320                                         if (!track_res && !rec_res)
00321                                                 error_out_++;
00322                                         total_comparisons_++;
00323                                         this->print_result();
00324                                 }
00325                                 rec_rec = false;
00326                                 rec_rec = false;
00327                         }
00328                 }
00329         }
00330         void print_result()
00331         {
00332                 std::cout << "-----------------------------------" << std::endl;
00333                 std::cout << "total comparisons    : " << total_comparisons_ << std::endl;
00334                 std::cout << "correctly recognized : " << ((float)correct_recognitions_ / (float)total_comparisons_) * 100 << " \%" << std::endl;
00335                 std::cout << "correctly tracked    : " << ((float)correct_trackings_ / (float)total_comparisons_) * 100 << " \%" << std::endl;
00336                 std::cout << "tracking improvement : " << ((float)tracking_improvement_ / (float)total_comparisons_) * 100 << " \%" << std::endl;
00337                 std::cout << "tracking worsening   : " << ((float)tracking_decline_ / (float)total_comparisons_) * 100 << " \%" << std::endl;
00338                 std::cout << "errors after tracking: " << (error_out_ / total_comparisons_) * 100 << " \%" << std::endl;
00339                 std::cout << "-----------------------------------" << std::endl;
00340                 //std::cout<<"-----------------------------------"<<std::endl;
00341                 //std::cout<<"total comparisons    : "<<total_comparisons_<<std::endl;
00342                 //std::cout<<"correctly recognized : "<<correct_recognitions_<<std::endl;
00343                 //std::cout<<"correctly tracked    : "<<correct_trackings_<<std::endl;
00344                 //std::cout<<"tracking improvement : "<<tracking_improvement_<<std::endl;
00345                 //std::cout<<"tracking worsening   : "<<tracking_decline_<<std::endl;
00346                 //std::cout<<"errors after tracking: "<<error_out_<<std::endl;
00347                 //std::cout<<"-----------------------------------"<<std::endl;
00348         }
00349 };
00350 
00351 //#######################
00352 //#### main programm ####
00353 int main(int argc, char** argv)
00354 {
00355         // Initialize ROS, specify name of node
00356         ros::init(argc, argv, "tracking_evaluator");
00357 
00358         // Create a handle for this node, initialize node
00359         ros::NodeHandle nh;
00360 
00361         // Create FaceRecognizerNode class instance
00362         TrackingEvalNode tracking_eval_node(nh);
00363 
00364         // Create action nodes
00365         //DetectObjectsAction detect_action_node(object_detection_node, nh);
00366         //AcquireObjectImageAction acquire_image_node(object_detection_node, nh);
00367         //TrainObjectAction train_object_node(object_detection_node, nh);
00368 
00369         ros::spin();
00370 
00371         return 0;
00372 }


cob_people_detection
Author(s): Richard Bormann , Thomas Zwölfer
autogenerated on Fri Aug 28 2015 10:24:13