00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <iostream>
00028
00029 #include <qvdta/qvdta.h>
00030
00031 #define NULL_NODE 256*256*256
00032
00095 class QVComponentTree
00096 {
00097 public:
00111 QVComponentTree(const QVImage<uChar,1> &image, bool inverseTree= false, bool useAlternative = false);
00112
00115 bool isInverseTree() const { return inverseTree; }
00116
00123 uInt & rootNode() { return rootNodeID; }
00124
00134 uInt & seedX(uInt index) { return nodes[index].seedX; }
00135
00145 uInt & seedY(uInt index) { return nodes[index].seedY; }
00146
00153 uChar & firstThreshold(uInt index) { return nodes[index].firstThreshold; }
00154
00161 uChar & lastThreshold(uInt index) { return nodes[index].lastThreshold; }
00162
00166 uInt & numChilds(uInt index) { return nodes[index].numChilds; }
00167
00171 uInt & firstChild(uInt index) { return nodes[index].child; }
00172
00176 uInt & nextSibling(uInt index) { return nodes[index].sibling; }
00177
00195 uInt *area(uInt index) { return nodes[index].area; }
00196
00199 uInt getNumNodes() const { return numNodes; }
00200
00203 uInt getLeafNodes() const { return leafNodes; }
00204
00209 uInt getTotalPoints() const { return totalPoints; }
00210
00211 private:
00212 void getComponentTree(const QVImage<uChar> &image);
00213 void getComponentTree2(const QVImage<uChar> &image);
00214
00215 uInt numNodes, freePoints, totalPoints, leafNodes, rootNodeID, maxNodes;
00216 bool inverseTree;
00217
00219 bool & closedNode(uInt index) { return nodes[index].closed; }
00220
00221 uInt newNode(uInt SeedX, uInt SeedY, uChar Threshold)
00222 {
00223 uInt newNodeID = this->numNodes++;
00224
00225 seedX(newNodeID) = SeedX;
00226 seedY(newNodeID) = SeedY;
00227 firstThreshold(newNodeID) = lastThreshold(newNodeID) = Threshold;
00228 firstChild(newNodeID) = nextSibling(newNodeID) = NULL_NODE;
00229 numChilds(newNodeID) = 0;
00230 area(newNodeID)[Threshold] = 0;
00231 closedNode(newNodeID) = false;
00232
00233 return newNodeID;
00234 }
00235
00236 void addChild(uInt ParentNodeID, uInt ChildNodeID)
00237 {
00238 nextSibling(ChildNodeID) = firstChild(ParentNodeID);
00239 firstChild(ParentNodeID) = ChildNodeID;
00240 numChilds(ParentNodeID)++;
00241 }
00242
00243 void mergeNodes(uInt actualNodeID, uInt vecinoNodeID)
00244 {
00245 uInt child;
00246 for (child = firstChild(actualNodeID); nextSibling(child) != NULL_NODE; child = nextSibling(child));
00247
00248 uInt lastActualChildNodeID = firstChild(actualNodeID);
00249 while (nextSibling(lastActualChildNodeID) != NULL_NODE)
00250 lastActualChildNodeID = nextSibling(lastActualChildNodeID);
00251
00252 numChilds(actualNodeID) += numChilds(vecinoNodeID);
00253 nextSibling(lastActualChildNodeID) = firstChild(vecinoNodeID);
00254 }
00255
00256 class QVComponentTreeNode
00257 {
00258 public:
00259 uInt seedX, seedY;
00260 uInt child, sibling, numChilds;
00261 uChar firstThreshold, lastThreshold;
00262 uInt area[256];
00263 bool closed;
00264 };
00265
00266 QVector<QVComponentTreeNode> nodes;
00267
00268 void testComponentTree(const QVImage<uChar,1> &image, QVDisjointSet &disjointSet);
00269 };
00270
00272 void FilterComponentTreeSmallRegions(QVImage<uChar> &image, QVComponentTree &componentTree, uInt area);
00273