calibTree.cpp
Go to the documentation of this file.
00001 
00008 #include <youbot_overhead_vision/calibTree.h>
00009 
00010 calibTree::calibTree()
00011 {
00012   calibPoints = *(new vector<calib>());
00013   treeHead = NULL;
00014   idCount = 0;
00015 }
00016 
00017 calibTree::~calibTree()
00018 {
00019   freeTree();
00020 }
00021 
00022 void calibTree::newCalibPoint(uint8_t red, uint8_t green, uint8_t blue, int camera, int calibType)
00023 {
00024   calibPoints.push_back(*(new calib()));
00025   calibPoints[calibPoints.size() - 1].r = red;
00026   calibPoints[calibPoints.size() - 1].g = green;
00027   calibPoints[calibPoints.size() - 1].b = blue;
00028   calibPoints[calibPoints.size() - 1].camera = camera;
00029   calibPoints[calibPoints.size() - 1].calibType = calibType;
00030   calibPoints[calibPoints.size() - 1].redTreeLeftChild = NULL;
00031   calibPoints[calibPoints.size() - 1].redTreeLeftChild = NULL;
00032   idCount++;
00033   calibPoints[calibPoints.size() - 1].id = idCount;
00034 
00035 }
00036 
00037 int calibTree::getCalibPointsSize()
00038 {
00039   return calibPoints.size();
00040 }
00041 
00042 int calibTree::getCalibPointColor(int index, int colorIndex)
00043 {
00044   if (colorIndex == 0)
00045     return calibPoints[index].r;
00046   else if (colorIndex == 1)
00047     return calibPoints[index].g;
00048   else
00049     return calibPoints[index].b;
00050 }
00051 
00052 int calibTree::getCalibPointCamera(int index)
00053 {
00054   return calibPoints[index].camera;
00055 }
00056 
00057 int calibTree::getCalibPointType(int index)
00058 {
00059   return calibPoints[index].calibType;
00060 }
00061 
00062 void calibTree::removeCalibPoint(int index)
00063 {
00064   if (getCalibPointsSize() > 1)
00065     calibPoints.erase(calibPoints.begin() + index);
00066   else
00067     calibPoints.pop_back();
00068 }
00069 
00070 void calibTree::createTree()
00071 {
00072   if (getCalibPointsSize() > 0)
00073     createTreeRecursion(0, getCalibPointsSize());
00074 
00075 }
00076 
00077 void calibTree::createTreeRecursion(int start, int end)
00078 {
00079   int range = end - start;
00080   if (range <= 3)
00081   {
00082     if (range >= 2)
00083     {
00084       addToTree(start + 1);
00085     }
00086     if (range == 3)
00087     {
00088       addToTree(start + 2);
00089     }
00090     addToTree(start);
00091   }
00092   else
00093   {
00094     int middleIndex = (end + start) / 2;
00095     addToTree(middleIndex);
00096     createTreeRecursion(start, middleIndex);
00097     createTreeRecursion(middleIndex + 1, end);
00098   }
00099 
00100 }
00101 
00102 int calibTree::parseCalibTree(int R, int G, int B, int camera, int calibAccuracy)
00103 {
00104   return parseCalibTreeRecursion(treeHead, R, G, B, camera, calibAccuracy);
00105 }
00106 
00107 int calibTree::parseCalibTreeRecursion(calib * treeNode, int R, int G, int B, int camera, int calibAccuracy)
00108 {
00109   if (treeNode)
00110   {
00111     //Calib Node's R value is in the interval.  As such, the other colors must be checked.  If the other values of
00112     //that node dont match the pixel colors (R, G, B), both children of that node must be checked.
00113     if (abs(treeNode->r - R) <= calibAccuracy)
00114     {
00115       if ((abs(treeNode->b - B) < calibAccuracy) && (abs(treeNode->g - G) < calibAccuracy)
00116           && (treeNode->camera == BOTH_CAMERAS || camera == treeNode->camera))
00117         return treeNode->calibType;
00118       else
00119       {
00120         int left = parseCalibTreeRecursion(treeNode->redTreeLeftChild, R, G, B, camera, calibAccuracy);
00121         return (
00122             (left != NOT_SET) ? left :
00123                 (parseCalibTreeRecursion(treeNode->redTreeRightChild, R, G, B, camera, calibAccuracy)));
00124       }
00125     }
00126     //The calib Node's R value is greater than the pixel R value.  As such, the left side of the tree must be scanned
00127     else if ((treeNode->r - R) > 0)
00128     {
00129       return parseCalibTreeRecursion(treeNode->redTreeLeftChild, R, G, B, camera, calibAccuracy);
00130     }
00131     //The calib Node's R value is lesser than the pixel R value.  As such, the right side of the tree must be scanned
00132     else
00133     {
00134       return parseCalibTreeRecursion(treeNode->redTreeRightChild, R, G, B, camera, calibAccuracy);
00135     }
00136 
00137   }
00138   else //treenode is equal to NULL
00139   {
00140     return NOT_SET;
00141   }
00142 }
00143 
00144 void calibTree::orderCalibsByRed()
00145 {
00146   if (calibPoints.size() > 0)
00147   {
00148     //Resets left and right child in preparation for the creation of the new tree
00149     calibPoints[0].redTreeLeftChild = NULL;
00150     calibPoints[0].redTreeLeftChild = NULL;
00151     //Order Calib Points by red using insertion sort:         
00152   }
00153 
00154   calib * temp = new calib();
00155 
00156   int i;
00157   for (int j = 1; j < (int)calibPoints.size(); j++)
00158   {
00159     temp->r = calibPoints[j].r;
00160     temp->g = calibPoints[j].g;
00161     temp->b = calibPoints[j].b;
00162     temp->camera = calibPoints[j].camera;
00163     temp->calibType = calibPoints[j].calibType;
00164     temp->id = calibPoints[j].id;
00165 
00166     i = j - 1;
00167     while (calibPoints[i].r > temp->r && i >= 0)
00168     {
00169       calibPoints[i + 1].r = calibPoints[i].r;
00170       calibPoints[i + 1].g = calibPoints[i].g;
00171       calibPoints[i + 1].b = calibPoints[i].b;
00172       calibPoints[i + 1].camera = calibPoints[i].camera;
00173       calibPoints[i + 1].calibType = calibPoints[i].calibType;
00174       calibPoints[i + 1].id = calibPoints[i].id;
00175       calibPoints[i + 1].redTreeLeftChild = NULL;
00176       calibPoints[i + 1].redTreeRightChild = NULL;
00177 
00178       i--;
00179     }
00180     calibPoints[i + 1].r = temp->r;
00181     calibPoints[i + 1].g = temp->g;
00182     calibPoints[i + 1].b = temp->b;
00183     calibPoints[i + 1].camera = temp->camera;
00184     calibPoints[i + 1].calibType = temp->calibType;
00185     calibPoints[i + 1].id = temp->id;
00186     calibPoints[i + 1].redTreeLeftChild = NULL;
00187     calibPoints[i + 1].redTreeRightChild = NULL;
00188   }
00189 }
00190 
00191 bool calibTree::removeLastNodeFromTree(int cameraShown)
00192 {
00193 
00194   int size = getCalibPointsSize();
00195   if (size > 0)
00196   {
00197     int highestIndex = 0;
00198     for (int itt = 0; itt < size; itt++)
00199     {
00200       if (calibPoints[itt].id > calibPoints[highestIndex].id)
00201         highestIndex = itt;
00202     }
00203 
00204     if (removeLastNodeFromTreeRecursion(treeHead, getCalibPointColor(highestIndex, RED),
00205                                         getCalibPointColor(highestIndex, GREEN), getCalibPointColor(highestIndex, BLUE),
00206                                         calibPoints[highestIndex].id))
00207     {
00208       removeCalibPoint(highestIndex);
00209       idCount--;
00210       if (getCalibPointsSize() == 0)
00211       {
00212         freeTree();
00213       }
00214       return true;
00215     }
00216 
00217   }
00218   return false;
00219 }
00220 
00221 bool calibTree::removeLastNodeFromTreeRecursion(calib * nodePtr, int r, int g, int b, int id)
00222 {
00223   if (!nodePtr)
00224     return false;
00225 
00226   //If the node being looked at is the one that needs to be removed, This removes it.  
00227   if (nodePtr->id == id)
00228   {
00229     //If the the node being removed has child nodes, one of the child nodes must be used to take the position of the node 
00230     //being destroyed in the tree. This child node then has to be removed to ensure there is no doubles in the tree.
00231     calib * replacementNode;
00232     if ((replacementNode = nodePtr->redTreeLeftChild))
00233     {
00234       while (replacementNode->redTreeRightChild)
00235       {
00236         replacementNode = replacementNode->redTreeRightChild;
00237       }
00238     }
00239     else if ((replacementNode = nodePtr->redTreeRightChild))
00240     {
00241       while (replacementNode->redTreeLeftChild)
00242       {
00243         replacementNode = replacementNode->redTreeLeftChild;
00244       }
00245     }
00246     else //Removes the node from the tree if the node has no children.
00247     {
00248 
00249       //Removes the link to the node from the parent node.
00250       if (nodePtr->redTreeParent)
00251       {
00252         calib * parent = nodePtr->redTreeParent;
00253         //If node being removed is the left child of its parent, remove left node. else, remove right node.
00254         if (parent->redTreeLeftChild && parent->redTreeLeftChild->r == r && parent->redTreeLeftChild->g == g
00255             && parent->redTreeLeftChild->b == b)
00256           parent->redTreeLeftChild = NULL;
00257         else
00258           parent->redTreeRightChild = NULL;
00259       }
00260       delete (nodePtr);
00261 
00262       return true;
00263     }
00264 
00265     //Replace Node Info with replacement Node Info
00266     nodePtr->r = replacementNode->r;
00267     nodePtr->g = replacementNode->g;
00268     nodePtr->b = replacementNode->b;
00269     nodePtr->camera = replacementNode->camera;
00270     nodePtr->calibType = replacementNode->calibType;
00271     nodePtr->id = replacementNode->id;
00272 
00273     //Remove Replacement Node
00274     return removeLastNodeFromTreeRecursion(replacementNode, replacementNode->r, replacementNode->g, replacementNode->b,
00275                                            replacementNode->id);
00276   }
00277 
00278   else //Searches tree for the node with values r, g, b
00279   {
00280     if (r < nodePtr->r && nodePtr->redTreeLeftChild)
00281       return removeLastNodeFromTreeRecursion(nodePtr->redTreeLeftChild, r, g, b, id);
00282     else if (r > nodePtr->r && nodePtr->redTreeRightChild)
00283       return removeLastNodeFromTreeRecursion(nodePtr->redTreeRightChild, r, g, b, id);
00284     else
00285     {
00286       bool foundRight = false, foundLeft = false;
00287       if (nodePtr->redTreeLeftChild)
00288       {
00289         foundLeft = removeLastNodeFromTreeRecursion(nodePtr->redTreeLeftChild, r, g, b, id);
00290       }
00291       if (nodePtr->redTreeRightChild)
00292       {
00293         foundRight = removeLastNodeFromTreeRecursion(nodePtr->redTreeRightChild, r, g, b, id);
00294       }
00295       return foundRight || foundLeft;
00296     }
00297   }
00298 
00299   return false;
00300 }
00301 
00302 void calibTree::freeTree()
00303 {
00304   if (getCalibPointsSize() > 0)
00305     freeTreeRecursion(treeHead);
00306   else
00307     treeHead = NULL;
00308 }
00309 
00310 void calibTree::freeTreeRecursion(calib * node)
00311 {
00312   if (node)
00313   {
00314     freeTreeRecursion(node->redTreeLeftChild);
00315     freeTreeRecursion(node->redTreeRightChild);
00316     delete (node);
00317   }
00318   treeHead = NULL;
00319 }
00320 
00321 void calibTree::addToTree(int calibNode)
00322 {
00323   //If this is the first node found, assign the head of the trees to that node.
00324   if (!treeHead)
00325   {
00326     createTreeNode(calibNode, treeHead, NULL);
00327 
00328     treeHead = new calib();
00329     treeHead->r = calibPoints[calibNode].r;
00330     treeHead->g = calibPoints[calibNode].g;
00331     treeHead->b = calibPoints[calibNode].b;
00332     treeHead->camera = calibPoints[calibNode].camera;
00333     treeHead->calibType = calibPoints[calibNode].calibType;
00334     treeHead->id = calibPoints[calibNode].id;
00335 
00336     treeHead->redTreeLeftChild = NULL;
00337     treeHead->redTreeRightChild = NULL;
00338     treeHead->redTreeParent = NULL;
00339     return;
00340   }
00341   else
00342   {
00343     //Right now, the head of the tree is always the first node
00344     struct calib * redTreePtr = treeHead;
00345 
00346     //Adding nodes to all three trees
00347     bool nodeAddedFlag = false;
00348     while (!nodeAddedFlag)
00349     { //Node being added smaller than or equal to the node in tree.  Look at left child. 
00350       if (redTreePtr->r >= calibPoints[calibNode].r)
00351       {
00352         if (!redTreePtr->redTreeLeftChild)
00353         {
00354           createTreeNode(calibNode, redTreePtr->redTreeLeftChild, redTreePtr);
00355           nodeAddedFlag = true;
00356         }
00357         else
00358         {
00359           redTreePtr = redTreePtr->redTreeLeftChild;
00360         }
00361       }
00362       else //Node being added larger than the node in tree.  Look at right child.
00363       {
00364         if (!redTreePtr->redTreeRightChild)
00365         {
00366           createTreeNode(calibNode, redTreePtr->redTreeRightChild, redTreePtr);
00367           nodeAddedFlag = true;
00368         }
00369         else
00370         {
00371           redTreePtr = redTreePtr->redTreeRightChild;
00372         }
00373       }
00374     }
00375   }
00376 }
00377 
00378 void calibTree::createTreeNode(int vectorIndex, calib * nodePtr, calib * parentPtr)
00379 {
00380   nodePtr = new calib();
00381   nodePtr->r = calibPoints[vectorIndex].r;
00382   nodePtr->g = calibPoints[vectorIndex].g;
00383   nodePtr->b = calibPoints[vectorIndex].b;
00384   nodePtr->camera = calibPoints[vectorIndex].camera;
00385   nodePtr->calibType = calibPoints[vectorIndex].calibType;
00386   nodePtr->id = calibPoints[vectorIndex].id;
00387 
00388   nodePtr->redTreeLeftChild = NULL;
00389   nodePtr->redTreeRightChild = NULL;
00390   nodePtr->redTreeParent = parentPtr;
00391 
00392   if (parentPtr)
00393   {
00394     if (parentPtr->r >= nodePtr->r)
00395       parentPtr->redTreeLeftChild = nodePtr;
00396     else
00397       parentPtr->redTreeRightChild = nodePtr;
00398   }
00399 }
00400 
00401 void calibTree::printTree()
00402 {
00403   if (getCalibPointsSize() > 0)
00404     printTreeRecursion(treeHead, 0);
00405 }
00406 
00407 void calibTree::printTreeRecursion(calib * node, int level)
00408 {
00409   if (level == 0)
00410     ROS_INFO("Printing Tree:");
00411   if (node)
00412   {
00413     ROS_INFO(
00414         "calibType: %d R %d G %d B %d Camera: %d ID: %d Level: %d Child pts: %p %p", node->calibType, node->r, node->g, node->b, node->camera, node->id, level, node->redTreeLeftChild, node->redTreeRightChild);
00415 
00416     printTreeRecursion(node->redTreeLeftChild, level + 1);
00417     printTreeRecursion(node->redTreeRightChild, level + 1);
00418   }
00419 }
00420 


youbot_overhead_vision
Author(s): Fred Clinckemaillie, Maintained by David Kent
autogenerated on Thu Jan 2 2014 12:14:12