MyOcTree.cpp
Go to the documentation of this file.
00001 #include <octomap_tensor_field/MyOcTree.h>
00002 
00003 namespace octomap {
00004 
00005 
00006   // node implementation  --------------------------------------
00007   std::ostream& MyOcTreeNode::writeValue (std::ostream &s) const {
00008     // 1 bit for each children; 0: empty, 1: allocated
00009     std::bitset<8> children;
00010     for (unsigned int i=0; i<8; i++) {
00011       if (childExists(i)) children[i] = 1;
00012       else                children[i] = 0;
00013     }
00014     char children_char = (char) children.to_ulong();
00015 
00016     // write node data
00017     s.write((const char*) &value, sizeof(value)); // occupancy
00018     s.write((const char*) &color, sizeof(Color)); // color
00019     s.write((const char*) &sqrtRecipStd, sizeof(sqrtRecipStd)); // sqrtRecipStd
00020     s.write((char*)&children_char, sizeof(char)); // child existence
00021 
00022     // write existing children
00023     for (unsigned int i=0; i<8; ++i)
00024       if (children[i] == 1) this->getChild(i)->writeValue(s);
00025     return s;
00026   }
00027 
00028   std::istream& MyOcTreeNode::readValue (std::istream &s) {
00029     // read node data
00030     char children_char;
00031     s.read((char*) &value, sizeof(value)); // occupancy
00032     s.read((char*) &color, sizeof(Color)); // color
00033     s.read((char*) &sqrtRecipStd, sizeof(sqrtRecipStd)); // sqrtRecipStd
00034     s.read((char*)&children_char, sizeof(char)); // child existence
00035 
00036     // read existing children
00037     std::bitset<8> children ((unsigned long long) children_char);
00038     for (unsigned int i=0; i<8; i++) {
00039       if (children[i] == 1){
00040         createChild(i);
00041         getChild(i)->readValue(s);
00042       }
00043     }
00044     return s;
00045   }
00046 
00047   MyOcTreeNode::Color MyOcTreeNode::getAverageChildColor() const {
00048     int mr(0), mg(0), mb(0);
00049     int c(0);
00050     for (int i=0; i<8; i++) {
00051       if (childExists(i) && getChild(i)->isColorSet()) {
00052         mr += getChild(i)->getColor().r;
00053         mg += getChild(i)->getColor().g;
00054         mb += getChild(i)->getColor().b;
00055         ++c;
00056       }
00057     }
00058     if (c) {
00059       mr /= c;
00060       mg /= c;
00061       mb /= c;
00062       return Color((unsigned char) mr, (unsigned char) mg, (unsigned char) mb);
00063     }
00064     else { // no child had a color other than white
00065       return Color(255, 255, 255);
00066     }
00067   }
00068   double MyOcTreeNode::getMeanChildSqrtRecipStd() const{
00069     double mean = 0;
00070     double c = 0;
00071     if (hasChildren()){
00072       for (unsigned int i=0; i<8; i++) {
00073         if (childExists(i)) {
00074           mean += getChild(i)->getSqrtRecipStd(); // TODO check if works generally
00075           ++c;
00076         }
00077       }
00078     }
00079 
00080     if (c > 0)
00081       mean /= (double) c;
00082 
00083     return mean;
00084   }
00085 
00086   double MyOcTreeNode::getMaxChildSqrtRecipStd() const{
00087     double max = -std::numeric_limits<float>::max();
00088 
00089     if (hasChildren()){
00090       for (unsigned int i=0; i<8; i++) {
00091         if (childExists(i)) {
00092           double l = getChild(i)->getSqrtRecipStd(); // TODO check if works generally
00093           if (l > max)
00094             max = l;
00095         }
00096       }
00097     }
00098     return max;
00099   }
00100 
00101 
00102   void MyOcTreeNode::updateColorChildren() {
00103     color = getAverageChildColor();
00104   }
00105   void MyOcTreeNode::updateSqrtRecipStdChildren() {
00106     sqrtRecipStd = getMaxChildSqrtRecipStd();
00107   }
00108 
00109   // pruning =============
00110 
00111   bool MyOcTreeNode::pruneNode() {
00112     // checks for equal occupancy only, color ignored
00113     if (!this->collapsible()) return false;
00114     // set occupancy value
00115     setLogOdds(getChild(0)->getLogOdds());
00116     // set color to average color
00117     if (isColorSet()) color = getAverageChildColor();
00118     sqrtRecipStd=getMaxChildSqrtRecipStd();
00119     // delete children
00120     for (unsigned int i=0;i<8;i++) {
00121       delete children[i];
00122     }
00123     delete[] children;
00124     children = NULL;
00125     return true;
00126   }
00127 
00128   void MyOcTreeNode::expandNode() {
00129     assert(!hasChildren());
00130     for (unsigned int k=0; k<8; k++) {
00131       createChild(k);
00132       children[k]->setValue(value);
00133       getChild(k)->setColor(color);
00134       getChild(k)->setSqrtRecipStd(sqrtRecipStd);
00135     }
00136   }
00137   void MyOcTreeNode::addSqrtRecipStd(const double& sqrtRecipStd_update){
00138         sqrtRecipStd+=sqrtRecipStd_update;
00139   }
00140 
00141 
00142   // tree implementation  --------------------------------------
00143 
00144   MyOcTreeNode* MyOcTree::setNodeColor(const OcTreeKey& key,
00145                                              const unsigned char& r,
00146                                              const unsigned char& g,
00147                                              const unsigned char& b) {
00148     MyOcTreeNode* n = search (key);
00149     if (n != 0) {
00150       n->setColor(r, g, b);
00151     }
00152     return n;
00153   }
00154 
00155   MyOcTreeNode* MyOcTree::setNodeSqrtRecipStd(const OcTreeKey& key,const double &sqrtRecipStd_  ) {
00156     MyOcTreeNode* n = search (key);
00157     if (n != 0) {
00158       n->setSqrtRecipStd(sqrtRecipStd_);
00159     }
00160     return n;
00161   }
00162   MyOcTreeNode* MyOcTree::setNodeCurDist(const OcTreeKey& key,const double &dist  ) {
00163     MyOcTreeNode* n = search (key);
00164     if (n != 0) {
00165       n->setCurDist(dist);
00166     }
00167     return n;
00168   }
00169 
00170 double MyOcTree::getNodeCurDist(const OcTreeKey& key){
00171     MyOcTreeNode* n = search (key);
00172     if (n != 0) {
00173       return n->getCurDist();
00174     }
00175     return -1.0;
00176 }
00177 double MyOcTree::getNodeSqrtRecipStdt(const OcTreeKey& key){
00178     MyOcTreeNode* n = search (key);
00179     if (n != 0) {
00180       return n->getSqrtRecipStd();
00181     }
00182     return -1.0;
00183 }
00184 
00185 int MyOcTree::getNodeVisCount(const OcTreeKey& key){
00186     MyOcTreeNode* n = search (key);
00187     if (n != 0) {
00188       return n->getVisCount();
00189     }
00190     return -1;
00191 }
00192 
00193 
00194   MyOcTreeNode* MyOcTree::averageNodeColor(const OcTreeKey& key,
00195                                                  const unsigned char& r,
00196                                                  const unsigned char& g,
00197                                                  const unsigned char& b) {
00198     MyOcTreeNode* n = search (key);
00199     if (n != 0) {
00200       if (n->isColorSet()) {
00201         MyOcTreeNode::Color prev_color = n->getColor();
00202         n->setColor((prev_color.r + r)/2, (prev_color.g + g)/2, (prev_color.b + b)/2);
00203       }
00204       else {
00205         n->setColor(r, g, b);
00206       }
00207     }
00208     return n;
00209   }
00210 
00211   MyOcTreeNode* MyOcTree::integrateNodeColor(const OcTreeKey& key,
00212                                                    const unsigned char& r,
00213                                                    const unsigned char& g,
00214                                                    const unsigned char& b) {
00215     MyOcTreeNode* n = search (key);
00216     if (n != 0) {
00217       if (n->isColorSet()) {
00218         MyOcTreeNode::Color prev_color = n->getColor();
00219         double node_prob = n->getOccupancy();
00220         unsigned char new_r = (unsigned char) ((double) prev_color.r * node_prob
00221                                                +  (double) r * (0.99-node_prob));
00222         unsigned char new_g = (unsigned char) ((double) prev_color.g * node_prob
00223                                                +  (double) g * (0.99-node_prob));
00224         unsigned char new_b = (unsigned char) ((double) prev_color.b * node_prob
00225                                                +  (double) b * (0.99-node_prob));
00226         n->setColor(new_r, new_g, new_b);
00227       }
00228       else {
00229         n->setColor(r, g, b);
00230       }
00231     }
00232     return n;
00233   }
00234 
00235    void MyOcTree::updateNodeSqrtRecipStd(const OcTreeKey& key,const double &sqrtRecipStd_update ){
00236        MyOcTreeNode* n = search (key);
00237        if (n != 0) {
00238          n->addSqrtRecipStd(sqrtRecipStd_update);
00239        }
00240    }
00241 
00242    void MyOcTree::updateNodeVisCount(const OcTreeKey& key){
00243        MyOcTreeNode* n = search (key);
00244        if (n != 0) {
00245          int curVisCount=n->getVisCount();
00246          if (curVisCount==claming_visCount_thres)
00247              return;
00248          n->setVisCount(curVisCount+1);
00249        }
00250    }
00251 
00252   void MyOcTree::updateInnerOccupancy() {
00253     if(this->root)
00254     this->updateInnerOccupancyRecurs(this->root, 0);
00255   }
00256 
00257   void MyOcTree::updateInnerOccupancyRecurs(MyOcTreeNode* node, unsigned int depth) {
00258     // only recurse and update for inner nodes:
00259     if (node->hasChildren()){
00260       // return early for last level:
00261       if (depth < this->tree_depth){
00262         for (unsigned int i=0; i<8; i++) {
00263           if (node->childExists(i)) {
00264             updateInnerOccupancyRecurs(node->getChild(i), depth+1);
00265           }
00266         }
00267       }
00268       node->updateOccupancyChildren();
00269       node->updateColorChildren();
00270       node->updateSqrtRecipStdChildren();
00271     }
00272   }
00273   void MyOcTree::groundColorMix(double* color, double x, double min, double max)
00274   {
00275      /*
00276       * Red = 0
00277       * Green = 1
00278       * Blue = 2
00279       */
00280       double posSlope = (max-min)/60;
00281       double negSlope = (min-max)/60;
00282 
00283       if( x < 60 )
00284       {
00285           color[0] = max;
00286           color[1] = posSlope*x+min;
00287           color[2] = min;
00288           return;
00289       }
00290       else if ( x < 120 )
00291       {
00292           color[0] = negSlope*x+2*max+min;
00293           color[1] = max;
00294           color[2] = min;
00295           return;
00296       }
00297       else if ( x < 180  )
00298       {
00299           color[0] = min;
00300           color[1] = max;
00301           color[2] = posSlope*x-2*max+min;
00302           return;
00303       }
00304       else if ( x < 240  )
00305       {
00306           color[0] = min;
00307           color[1] = negSlope*x+4*max+min;
00308           color[2] = max;
00309           return;
00310       }
00311       else if ( x < 300  )
00312       {
00313           color[0] = posSlope*x-4*max+min;
00314           color[1] = min;
00315           color[2] = max;
00316           return;
00317       }
00318       else
00319       {
00320           color[0] = max;
00321           color[1] = min;
00322           color[2] = negSlope*x+6*max;
00323           return;
00324       }
00325   }
00326 
00327 
00328   void MyOcTree::writeColorHistogram(std::string filename) {
00329 
00330 #ifdef _MSC_VER
00331     fprintf(stderr, "The color histogram uses gnuplot, this is not supported under windows.\n");
00332 #else
00333     // build RGB histogram
00334     std::vector<int> histogram_r (256,0);
00335     std::vector<int> histogram_g (256,0);
00336     std::vector<int> histogram_b (256,0);
00337     for(MyOcTree::tree_iterator it = this->begin_tree(),
00338           end=this->end_tree(); it!= end; ++it) {
00339       if (!it.isLeaf() || !this->isNodeOccupied(*it)) continue;
00340       MyOcTreeNode::Color& c = it->getColor();
00341       ++histogram_r[c.r];
00342       ++histogram_g[c.g];
00343       ++histogram_b[c.b];
00344     }
00345     // plot data
00346     FILE *gui = popen("gnuplot ", "w");
00347     fprintf(gui, "set term postscript eps enhanced color\n");
00348     fprintf(gui, "set output \"%s\"\n", filename.c_str());
00349     fprintf(gui, "plot [-1:256] ");
00350     fprintf(gui,"'-' w filledcurve lt 1 lc 1 tit \"r\",");
00351     fprintf(gui, "'-' w filledcurve lt 1 lc 2 tit \"g\",");
00352     fprintf(gui, "'-' w filledcurve lt 1 lc 3 tit \"b\",");
00353     fprintf(gui, "'-' w l lt 1 lc 1 tit \"\",");
00354     fprintf(gui, "'-' w l lt 1 lc 2 tit \"\",");
00355     fprintf(gui, "'-' w l lt 1 lc 3 tit \"\"\n");
00356 
00357     for (int i=0; i<256; ++i) fprintf(gui,"%d %d\n", i, histogram_r[i]);
00358     fprintf(gui,"0 0\n"); fprintf(gui, "e\n");
00359     for (int i=0; i<256; ++i) fprintf(gui,"%d %d\n", i, histogram_g[i]);
00360     fprintf(gui,"0 0\n"); fprintf(gui, "e\n");
00361     for (int i=0; i<256; ++i) fprintf(gui,"%d %d\n", i, histogram_b[i]);
00362     fprintf(gui,"0 0\n"); fprintf(gui, "e\n");
00363     for (int i=0; i<256; ++i) fprintf(gui,"%d %d\n", i, histogram_r[i]);
00364     fprintf(gui, "e\n");
00365     for (int i=0; i<256; ++i) fprintf(gui,"%d %d\n", i, histogram_g[i]);
00366     fprintf(gui, "e\n");
00367     for (int i=0; i<256; ++i) fprintf(gui,"%d %d\n", i, histogram_b[i]);
00368     fprintf(gui, "e\n");
00369     fflush(gui);
00370 #endif
00371   }
00372 
00373   std::ostream& operator<<(std::ostream& out, MyOcTreeNode::Color const& c) {
00374     return out << '(' << (unsigned int)c.r << ' ' << (unsigned int)c.g << ' ' << (unsigned int)c.b << ')';
00375   }
00376 
00377 
00378   MyOcTree::StaticMemberInitializer MyOcTree::MyOcTreeMemberInit;
00379 
00380 } // end namespace


octomap_tensor_field
Author(s): Lintao Zheng
autogenerated on Thu Jun 6 2019 19:50:39