00001 #include <octomap_tensor_field/MyOcTree.h>
00002
00003 namespace octomap {
00004
00005
00006
00007 std::ostream& MyOcTreeNode::writeValue (std::ostream &s) const {
00008
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
00017 s.write((const char*) &value, sizeof(value));
00018 s.write((const char*) &color, sizeof(Color));
00019 s.write((const char*) &sqrtRecipStd, sizeof(sqrtRecipStd));
00020 s.write((char*)&children_char, sizeof(char));
00021
00022
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
00030 char children_char;
00031 s.read((char*) &value, sizeof(value));
00032 s.read((char*) &color, sizeof(Color));
00033 s.read((char*) &sqrtRecipStd, sizeof(sqrtRecipStd));
00034 s.read((char*)&children_char, sizeof(char));
00035
00036
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 {
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();
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();
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
00110
00111 bool MyOcTreeNode::pruneNode() {
00112
00113 if (!this->collapsible()) return false;
00114
00115 setLogOdds(getChild(0)->getLogOdds());
00116
00117 if (isColorSet()) color = getAverageChildColor();
00118 sqrtRecipStd=getMaxChildSqrtRecipStd();
00119
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
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
00259 if (node->hasChildren()){
00260
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
00277
00278
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
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
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 }