Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #ifndef EVAL_H_
00009 #define EVAL_H_
00010
00011 class BinaryClassification {
00012
00013 public:
00014
00015 struct Data {
00016 size_t num;
00017 size_t true_pos;
00018 size_t false_pos;
00019 int label, mark;
00020
00021 Data():num(0), true_pos(0), false_pos(0), label(-1), mark(-1) {}
00022 };
00023
00024 private:
00025
00026 std::map<int, std::map<int, size_t> > label_to_mark;
00027 std::map<int, Data> stat_label;
00028
00029 std::map<int, std::map<int, size_t> > mark_to_label;
00030 std::map<int, Data> stat_mark;
00031
00032 bool isMarkMaxForLabel(int mark, int l) {
00033 const size_t g = mark_to_label[mark][l];
00034 size_t m = g;
00035 for(std::map<int, size_t>::const_iterator it2 = mark_to_label[mark].begin(); it2!=mark_to_label[mark].end(); it2++)
00036 m = std::max(m, it2->second);
00037 return m==g;
00038 }
00039
00040 public:
00041
00042 template<typename PointLabel>
00043 void addPC(const boost::shared_ptr<const pcl::PointCloud<PointLabel> > &labeled_pc) {
00044 if(!labeled_pc) return;
00045
00046 for(size_t x=0; x<labeled_pc->size(); x++)
00047 if(pcl_isfinite((*labeled_pc)[x].z)) addLabelPoint( (*labeled_pc)[x].label );
00048 }
00049
00050 void addLabelPoint(const int l) {
00051 stat_label[l].num++;
00052 stat_label[l].label = l;
00053 }
00054
00055 void addMark(const int mark, const int l) {
00056 if(label_to_mark[l].find(mark)==label_to_mark[l].end())
00057 label_to_mark[l][mark]=0;
00058 else
00059 label_to_mark[l][mark]++;
00060
00061 stat_mark[mark].num++;
00062 stat_mark[mark].label = mark;
00063 if(mark_to_label[mark].find(l)==mark_to_label[mark].end())
00064 mark_to_label[mark][l]=0;
00065 else
00066 mark_to_label[mark][l]++;
00067 }
00068
00069 const BinaryClassification &finish() {
00070 for(std::map<int, Data>::iterator it = stat_label.begin(); it!=stat_label.end(); it++) {
00071 const int l = it->first;
00072 ROS_ASSERT(l==it->second.label);
00073
00074 for(std::map<int, size_t>::const_iterator it2 = label_to_mark[l].begin(); it2!=label_to_mark[l].end(); it2++) {
00075 if(it2->second > it->second.true_pos &&
00076 isMarkMaxForLabel(it2->second, l)
00077 ) {
00078 it->second.false_pos += it->second.true_pos;
00079 it->second.true_pos = it2->second;
00080 it->second.mark = it2->first;
00081 }
00082 else
00083 it->second.false_pos += it2->second;
00084 }
00085 }
00086
00087 std::cout<<*this;
00088
00089 return *this;
00090 }
00091
00092 void get_rate(double &true_positive, double &false_positive) const {
00093 true_positive = false_positive = 0;
00094 size_t num = 0;
00095
00096 for(std::map<int, Data>::const_iterator it = stat_label.begin(); it!=stat_label.end(); it++) {
00097 true_positive += it->second.true_pos;
00098 false_positive += it->second.false_pos;
00099 num += std::max(it->second.num, it->second.true_pos+it->second.false_pos);
00100 }
00101
00102 true_positive/=num;
00103 false_positive/=num;
00104 }
00105
00107 friend std::ostream &operator<<(ostream &os, const BinaryClassification &bc);
00108 };
00109
00110 std::ostream &operator<<(ostream &os, const BinaryClassification &bc) {
00111 os<<"Num Labels: "<<bc.stat_label.size()<<"\n";
00112
00113 for(std::map<int, BinaryClassification::Data>::const_iterator it = bc.stat_label.begin(); it!=bc.stat_label.end(); it++) {
00114 const int l = it->first;
00115 os<<"Label: "<<l<<" "<<it->second.num<<"\n";
00116
00117 if(bc.label_to_mark.find(l)==bc.label_to_mark.end()) continue;
00118
00119 for(std::map<int, size_t>::const_iterator it2 = bc.label_to_mark.find(l)->second.begin(); it2!=bc.label_to_mark.find(l)->second.end(); it2++)
00120 os<<"Mark: "<<it2->first<<" "<<it2->second<<"\n";
00121 }
00122
00123 return os;
00124 }
00125
00126 class RunningStat
00127 {
00128 public:
00129 RunningStat() : m_n(0),m_oldM(0),m_newM(0),m_oldS(0),m_newS(0) {}
00130
00131 void Clear()
00132 {
00133 m_n = 0;
00134 }
00135
00136 void Push(double x)
00137 {
00138 m_n++;
00139
00140
00141 if (m_n == 1)
00142 {
00143 m_oldM = m_newM = x;
00144 m_oldS = 0.0;
00145 }
00146 else
00147 {
00148 m_newM = m_oldM + (x - m_oldM)/m_n;
00149 m_newS = m_oldS + (x - m_oldM)*(x - m_newM);
00150
00151
00152 m_oldM = m_newM;
00153 m_oldS = m_newS;
00154 }
00155 }
00156
00157 void Push(double x, double w)
00158 {
00159
00160 if (m_n == 0)
00161 {
00162 m_n+=w;
00163 m_oldM = m_newM = w*x;
00164 m_oldS = 0.0;
00165 }
00166 else
00167 {
00168 m_n+=w;
00169 m_newM = m_oldM + (w*x - m_oldM)/m_n;
00170 m_newS = m_oldS + (w*x - m_oldM)*(w*x - m_newM);
00171
00172
00173 m_oldM = m_newM;
00174 m_oldS = m_newS;
00175 }
00176 }
00177
00178 int NumDataValues() const
00179 {
00180 return m_n;
00181 }
00182
00183 double Mean() const
00184 {
00185 return (m_n > 0) ? m_newM : 0.0;
00186 }
00187
00188 double Variance() const
00189 {
00190 return ( (m_n > 1) ? m_newS/(m_n - 1) : 0.0 );
00191 }
00192
00193 double StandardDeviation() const
00194 {
00195 return sqrt( Variance() );
00196 }
00197
00198 private:
00199 double m_n;
00200 double m_oldM, m_newM, m_oldS, m_newS;
00201 };
00202
00203
00204
00205 #endif