octomap 1.5.0
include/octomap/ColorOcTree.h
Go to the documentation of this file.
00001 #ifndef OCTOMAP_COLOR_OCTREE_H
00002 #define OCTOMAP_COLOR_OCTREE_H
00003 
00004 // $Id: ColorOcTree.h 402 2012-08-06 13:39:42Z ahornung $
00005 
00014 /*
00015  * Copyright (c) 2009-2011, K. M. Wurm, A. Hornung, University of Freiburg
00016  * All rights reserved.
00017  *
00018  * Redistribution and use in source and binary forms, with or without
00019  * modification, are permitted provided that the following conditions are met:
00020  *
00021  *     * Redistributions of source code must retain the above copyright
00022  *       notice, this list of conditions and the following disclaimer.
00023  *     * Redistributions in binary form must reproduce the above copyright
00024  *       notice, this list of conditions and the following disclaimer in the
00025  *       documentation and/or other materials provided with the distribution.
00026  *     * Neither the name of the University of Freiburg nor the names of its
00027  *       contributors may be used to endorse or promote products derived from
00028  *       this software without specific prior written permission.
00029  *
00030  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00031  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00032  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00033  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00034  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00035  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00036  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00037  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00038  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00039  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00040  * POSSIBILITY OF SUCH DAMAGE.
00041  */
00042 
00043 #include <iostream>
00044 #include <octomap/OcTreeNode.h>
00045 #include <octomap/OccupancyOcTreeBase.h>
00046 
00047 namespace octomap {
00048   
00049   // node definition
00050   class ColorOcTreeNode : public OcTreeNode {    
00051   public:
00052     
00053     class Color {
00054     public:
00055     Color() : r(255), g(255), b(255) {}
00056     Color(unsigned char _r, unsigned char _g, unsigned char _b) 
00057       : r(_r), g(_g), b(_b) {}
00058       inline bool operator== (const Color &other) const {
00059         return (r==other.r && g==other.g && b==other.b);
00060       }
00061       inline bool operator!= (const Color &other) const {
00062         return (r!=other.r || g!=other.g || b!=other.b);
00063       }
00064       unsigned char r, g, b;
00065     };
00066 
00067   public:
00068     ColorOcTreeNode() : OcTreeNode() {}
00069 
00070     ColorOcTreeNode(const ColorOcTreeNode& rhs) : OcTreeNode(rhs), color(rhs.color) {}
00071 
00072     bool operator==(const ColorOcTreeNode& rhs) const{
00073       return (rhs.value == value && rhs.color == color);
00074     }
00075     
00076     // children
00077     inline ColorOcTreeNode* getChild(unsigned int i) {
00078       return static_cast<ColorOcTreeNode*> (OcTreeNode::getChild(i));
00079     }
00080     inline const ColorOcTreeNode* getChild(unsigned int i) const {
00081       return static_cast<const ColorOcTreeNode*> (OcTreeNode::getChild(i));
00082     }
00083 
00084     bool createChild(unsigned int i) {
00085       if (children == NULL) allocChildren();
00086       children[i] = new ColorOcTreeNode();
00087       return true;
00088     }
00089 
00090     bool pruneNode();
00091     void expandNode();
00092     
00093     inline Color getColor() const { return color; }
00094     inline void  setColor(Color c) {this->color = c; }
00095     inline void  setColor(unsigned char r, unsigned char g, unsigned char b) {
00096       this->color = Color(r,g,b); 
00097     }
00098 
00099     Color& getColor() { return color; }
00100 
00101     // has any color been integrated? (pure white is very unlikely...)
00102     inline bool isColorSet() const { 
00103       return ((color.r != 255) || (color.g != 255) || (color.b != 255)); 
00104     }
00105 
00106     void updateColorChildren();
00107 
00108 
00109     ColorOcTreeNode::Color getAverageChildColor() const;
00110   
00111     // file I/O
00112     std::istream& readValue (std::istream &s);
00113     std::ostream& writeValue(std::ostream &s) const;
00114     
00115   protected:
00116     Color color;
00117   };
00118 
00119 
00120   // tree definition
00121   class ColorOcTree : public OccupancyOcTreeBase <ColorOcTreeNode> {
00122 
00123   public:
00125     ColorOcTree(double resolution) : OccupancyOcTreeBase<ColorOcTreeNode>(resolution) {};  
00126       
00129     ColorOcTree* create() const {return new ColorOcTree(resolution); }
00130 
00131     std::string getTreeType() const {return "ColorOcTree";}
00132    
00133     // set node color at given key or coordinate. Replaces previous color.
00134     ColorOcTreeNode* setNodeColor(const OcTreeKey& key, const unsigned char& r, 
00135                                  const unsigned char& g, const unsigned char& b);
00136 
00137     ColorOcTreeNode* setNodeColor(const float& x, const float& y, 
00138                                  const float& z, const unsigned char& r, 
00139                                  const unsigned char& g, const unsigned char& b) {
00140       OcTreeKey key;
00141       if (!this->coordToKeyChecked(point3d(x,y,z), key)) return NULL;
00142       return setNodeColor(key,r,g,b);
00143     }
00144 
00145     // integrate color measurement at given key or coordinate. Average with previous color
00146     ColorOcTreeNode* averageNodeColor(const OcTreeKey& key, const unsigned char& r, 
00147                                   const unsigned char& g, const unsigned char& b);
00148     
00149     ColorOcTreeNode* averageNodeColor(const float& x, const float& y, 
00150                                       const float& z, const unsigned char& r, 
00151                                       const unsigned char& g, const unsigned char& b) {
00152       OcTreeKey key;
00153       if (!this->coordToKeyChecked(point3d(x,y,z), key)) return NULL;
00154       return averageNodeColor(key,r,g,b);
00155     }
00156 
00157     // integrate color measurement at given key or coordinate. Average with previous color
00158     ColorOcTreeNode* integrateNodeColor(const OcTreeKey& key, const unsigned char& r, 
00159                                   const unsigned char& g, const unsigned char& b);
00160     
00161     ColorOcTreeNode* integrateNodeColor(const float& x, const float& y, 
00162                                       const float& z, const unsigned char& r, 
00163                                       const unsigned char& g, const unsigned char& b) {
00164       OcTreeKey key;
00165       if (!this->coordToKeyChecked(point3d(x,y,z), key)) return NULL;
00166       return integrateNodeColor(key,r,g,b);
00167     }
00168 
00169     // update inner nodes, sets color to average child color
00170     void updateInnerOccupancy();
00171 
00172     // uses gnuplot to plot a RGB histogram in EPS format
00173     void writeColorHistogram(std::string filename);
00174     
00175   protected:
00176     void updateInnerOccupancyRecurs(ColorOcTreeNode* node, unsigned int depth);
00177 
00182     class StaticMemberInitializer{
00183        public:
00184          StaticMemberInitializer() {
00185            ColorOcTree* tree = new ColorOcTree(0.1);
00186            AbstractOcTree::registerTreeType(tree);
00187          }
00188     };
00190     static StaticMemberInitializer colorOcTreeMemberInit;
00191 
00192   };
00193 
00195   std::ostream& operator<<(std::ostream& out, ColorOcTreeNode::Color const& c);
00196 
00197 } // end namespace
00198 
00199 #endif