MeVisLabToolboxReference
MeVisLab/Standard/Sources/ML/MLVesselGraph/mlGraphAnalyser.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //----------------------------------------------------------------------------------
00004 
00009 //----------------------------------------------------------------------------------
00010 #ifndef __GraphAnalyser_H
00011 #define __GraphAnalyser_H
00012 
00013 
00014 // Include dll-specific settings.
00015 #include "mlVesselGraphSystem.h"
00016 
00017 // Include ml Macros for implementation support.
00018 #include "mlDebug.h"
00019 
00020 // Include vessel graph class.
00021 #include "mlSystemWarningsDisable.h"
00022 #include <map>
00023 #include <memory.h>
00024 #include "mlSystemWarningsRestore.h"
00025 #include "mlGraph.h"
00026 #include "mlGraphComponents.h"
00027 #include "mlFloatingPointVector.h"
00028 #include "mlMatrixTemplate.h"
00029 #include "AssocGraph.h"
00030 
00031 
00032 
00033 // Be sure that all your modules are part of the ml. So collisions
00034 // with names in system files or other libraries are minimized.
00035 ML_START_NAMESPACE
00036 
00037   // ------------------------------------------------------------------
00039 
00040   // ------------------------------------------------------------------
00043   typedef enum 
00044   {
00045     DATA_NO         = 0,
00046     DATA_SCL,
00047     DATA_BARYCENTER,
00048     DATA_DISTANCE,
00049     DATA_FLAG,
00050     DATA_NODE,
00051     DATA_GET_FKT,
00052     DATA_SET_FKT,
00053     DATA_AV_LEN,
00054     OUTDATA_CLUSTER,
00055     OUTDATA_LENGTH,
00056     OUTDATA_VOLUME,
00057     OUTDATA_POS,
00058     OUTDATA_GLOBAL_MIN_DIST,
00059     OUTDATA_AV_MIN_DIST,
00060     OUTDATA_ROOT,
00061   } NData;
00062   
00063   typedef std::map<NData, void *> DataMap;
00065 
00066   //----------------------------------------------------------
00068 
00069   //----------------------------------------------------------
00072   typedef enum 
00073   {
00074     PROC_NONE         = 0x000,
00075     PROC_LENGTH       = 0x001,
00076     PROC_VOLUME       = 0x002,
00077     PROC_WEIGHTED_POS = 0x004,
00078     PROC_AV_MIN_DIST  = 0x008,
00079     PROC_SCL          = 0x010,
00080     PROC_SKELETON_AREA= 0x020,
00081     PROC_ROOT         = 0x100,
00082     PROC_ST_VOLUME    = 0x202,
00083     PROC_ST_POS       = 0x204,
00084     PROC_ST_NODE_SUM  = 0x208,
00085     PROC_CLUSTER      = 0x400
00086   } NProcessMode;
00087 
00088   
00089 
00090 
00092 
00093   // ------------------------------------------------------------------
00095 
00096   // ------------------------------------------------------------------
00102   struct CIdxFloat{
00103     int   _nIdx;
00104     float _fValue;
00105 
00106 
00107     CIdxFloat(const CIdxFloat & oIF) : _nIdx(oIF._nIdx), _fValue(oIF._fValue)  {};
00108     CIdxFloat(int nIdx = 0, float fValue = 0.0) : _nIdx(nIdx), _fValue(fValue) {};
00109     CIdxFloat& operator=(const CIdxFloat &oIF) {if (this != &oIF){ this->_nIdx = oIF._nIdx; this->_fValue=oIF._fValue;} return *this; }
00110 
00111 
00113     inline bool operator> (const CIdxFloat& oIF) const { if(_fValue != oIF._fValue){return _fValue > oIF._fValue;} else {return _nIdx > oIF._nIdx;} }
00114     inline bool operator< (const CIdxFloat& oIF) const { if(_fValue != oIF._fValue){return _fValue < oIF._fValue;} else {return _nIdx < oIF._nIdx;} }
00115     inline bool operator==(const CIdxFloat& oIF) const { return ((_nIdx == oIF._nIdx) && (_fValue == oIF._fValue)); }
00117   };
00118 
00122   struct CIdxIdx{
00123     int _n1;
00124     int _n2;
00125     CIdxIdx(const CIdxIdx & oII) : _n1(oII._n1), _n2(oII._n2)  {};
00126     CIdxIdx& operator=(const CIdxIdx &oII) {if (this != &oII){ this->_n1 = oII._n1; this->_n2=oII._n2;} return *this; }
00128     inline bool operator< (const CIdxIdx& oII) const { if(_n1 != oII._n1){return _n1 < oII._n1;} else {return _n2 < oII._n2;} }
00129     inline bool operator==(const CIdxIdx& oII) const { return ((_n1 == oII._n1) && (_n2 == oII._n2)); }
00131   };
00133 
00134 
00135 
00136   // ------------------------------------------------------------------
00138   // ------------------------------------------------------------------
00143   class VESSELGRAPH_EXPORT GraphAnalyser 
00144   {
00145   public:
00146     //--------------------------------------------------------
00148 
00149     //--------------------------------------------------------
00152     explicit GraphAnalyser (Graph * pGraph) : _pGraph(pGraph) {};
00154 
00155     //----------------------------------------------------------
00157 
00158     //----------------------------------------------------------
00161     void measureLength();
00162 
00165     void measureVolume();
00166 
00170     void measureST_Volume(bool bIgnoreOrientation=false     
00171 
00172                          );
00173 
00176     float measureAvMinDistance();
00177 
00179     void measureSkeletonArea(int nAvLength=5);
00180 
00182     Vector3 measureBarycenter();
00183 
00187     void measureST_Barycenter(bool bIgnoreOrientation=false 
00188 
00189                              );
00190 
00192     inline void sumupST_DrainVolume(bool bIgnoreOrientation=false  
00193 
00194                                                             )
00195     { sumupST_Value (&VesselNode::getDrainVolume, &VesselNode::setDrainVolume, bIgnoreOrientation); }
00196 
00197     void sumupST_Value(VesselNode::NodeGetFkt getFkt,       
00198                        VesselNode::NodeSetFkt setFkt,       
00199                        bool bIgnoreOrientation=false        
00200 
00201                        );
00202 
00204     void measureMaxPathValue(VesselNode* pRootNode, VesselEdge::EdgeGetFkt edgeGetFkt, VesselNode::NodeGetFkt nodeGetFkt, VesselNode::NodeSetFkt nodeSetFkt);
00205 
00208     void searchMaxSubTrees(std::vector<VesselEdge *>::iterator iBegin, 
00209                            std::vector<VesselEdge *>::iterator iEnd,
00210                            int nNum,                                
00211                            std::vector<VesselEdge *> * pvMaxEdges,  
00212                            float * pfActValue,                      
00213                            float * pfActSum                         
00214                            );
00215 
00218     inline void searchMaxSubTrees(std::vector<VesselEdge *> vStartEdges,   
00219                            unsigned int nNum,                       
00220                            std::vector<VesselEdge *> * pvMaxEdges,  
00221                            float * pfActValue,                      
00222                            float * pfActSum                         
00223                            )
00224     {
00225       searchMaxSubTrees(vStartEdges.begin(), vStartEdges.end(), (int) nNum, pvMaxEdges, pfActValue, pfActSum);
00226     }
00227 
00230     inline void searchMaxSubTrees(std::vector<VesselEdge *> vStartEdges,   
00231                            int nPos,                                
00232                            unsigned int nNum,                       
00233                            std::vector<VesselEdge *> * pvMaxEdges,  
00234                            float * pfActValue,                      
00235                            float * pfActSum                         
00236                            )
00237     {
00238       searchMaxSubTrees(vStartEdges.begin()+nPos, vStartEdges.begin()+nPos+1, (int) nNum, pvMaxEdges, pfActValue, pfActSum);
00239     }
00240 
00241     // Starting at node pRoot, search for two subtrees (originating from a common node) with barycenters at a large distance 
00242     // in separationDirection and large volumes. Push_back() them to vClassifiedEdges ordered by descending position in separationDirection.
00243     // If (pRoot==NULL) all nodes in the graph are considered.
00244     void searchSubTreeSeparation(VesselNode* pRoot, const Vector3& separationDirection, std::vector<VesselEdge*>& vClassifiedEdges);
00245 
00249     void searchST_MajorBifurcation(VesselEdge *pStartEdge,          
00250                                    float fMinorLimit,               
00251                                    std::vector<VesselEdge *> *pvEdges, 
00252                                    bool bClear = true               
00253                                    );
00254 
00259     void searchST_MajorBifurcation(VesselEdge *pStartEdge,          
00260                                    float fMinorLimitStart,          
00261                                    float fMinorLimitStep,           
00262                                    int   nMinorLimitNumber,         
00263                                    std::vector<VesselEdge *> *pvEdges, 
00264                                    bool bClear = true               
00265                                    );
00266 
00267 
00274     bool calcDistanceMatrix(MatrixTemplate<double>& dm, std::vector<int>& vId, int nMaxNodes);
00275     
00276 
00295     bool calcNodeClassifikator(CDoubleArray * pArAssoc, std::vector<int>* pvId, int nMaxNodes);
00296 
00297 
00301     bool calcNodeBaseFromPosition(const Vector3 & vPosition, const std::vector<int> & vId, std::vector<CIdxFloat> * pvResult);
00302 
00306     bool calcPositionFromNodeBase(std::vector<CIdxFloat> vBase, Vector3 * pvResult);
00307 
00309     double calcSpannedVolume(const std::vector<int> & vId);
00311 
00312 
00313 
00314     //----------------------------------------------------------
00316 
00317     //----------------------------------------------------------
00320     VesselNode* suggestRoot(float fSignificanceLevel = 0.7, int nPreferedDirection = 0);
00321 
00322 
00325     short sampleConnectedCluster();
00326 
00328     const VesselNode * getParent(const VesselNode *pN1, const VesselNode *pN2) const;
00329     const VesselNode * getParent(const VesselEdge *pE1, const VesselEdge *pE2) const;
00330     VesselNode* getParent(VesselNode* pN1, VesselNode* pN2);
00331     VesselNode* getParent(VesselEdge *pE1, VesselEdge* pE2);
00333 
00335     void tansferLabels(Skeleton::LABELTYPE NType, float fThresh = 0.1);
00337     void tansferLabelsInverse(void);
00339     void scanSkeletonLabelMinMax( float *min, float *max );
00340 
00342     void collectLeafs(VesselNode *pRoot, std::vector<VesselNode*>& pLeafs);
00343 
00344   private:
00345     //----------------------------------------------------------
00347 
00348     //----------------------------------------------------------
00352     void calcRootPath(int nParentStart, int nParentEnd, int * pFreeIdx, std::vector<PathInfo>::iterator iPathBase, std::vector<PathInfo>::iterator iPathEnd);
00354     
00355 
00356 
00357     //----------------------------------------------------------
00359 
00360     //----------------------------------------------------------
00362     Graph * _pGraph;
00363 
00365     DataMap _MData;
00367 
00368   };
00369 
00370 
00371 
00372 
00373 
00374   // ------------------------------------------------------------------
00376   // ------------------------------------------------------------------
00381   class VESSELGRAPH_EXPORT EdgeAnalyser
00382   {
00383   public:    
00384     
00385     //--------------------------------------------------------
00387 
00388     //--------------------------------------------------------
00391     explicit EdgeAnalyser (long NMode, DataMap * pData = NULL);
00393 
00394 
00395 
00396     //--------------------------------------------------------
00398 
00399     //--------------------------------------------------------
00400     // function \c operator() provide singular outer access point
00401     inline void operator() (VesselEdge *pEdge){(this->*_actMeasure)(pEdge);}
00403 
00404   
00405   private:
00406     //--------------------------------------------------------
00408 
00409     //--------------------------------------------------------
00411     void measureNothing(VesselEdge * /*pEdge*/) {}
00412 
00415     void measureLength      (VesselEdge *pEdge);
00416 
00419     void measureVolume      (VesselEdge *pEdge);
00420 
00422     void measurePosition    (VesselEdge *pEdge);
00423 
00425     void averageMinDistance (VesselEdge *pEdge);
00426 
00429     void measureST_Volume(VesselEdge *pEdge);
00430 
00433     void measureST_Barycenter(VesselEdge *pEdge);
00434 
00436     void measure_avSkeletonArea(VesselEdge *pEdge);
00437 
00438 
00441     void sumupST_NodeValue(VesselEdge *pEdge);
00442 
00444 
00445     //----------------------------------------------------------
00447 
00448     //----------------------------------------------------------
00450     void (EdgeAnalyser::*_actMeasure) (VesselEdge *pEdge);
00451 
00453     float     _fVoxVolume;
00455     DataMap * _pData;
00457     long _NMode;
00459   };
00460 
00461 
00462 
00463     typedef enum {
00464     CMP_LENGTH,
00465     CMP_VOLUME,
00466     CMP_STVOLUME,
00467     CMP_STCENTER_X,
00468     CMP_STCENTER_Y,
00469     CMP_STCENTER_Z,
00470     CMP_STCENTER_PLANE,
00471     CMP_LABEL
00472   } CMP_FEATURE;
00473 
00474     // ------------------------------------------------------------------
00476     // ------------------------------------------------------------------
00480   class compareEdges{
00481   public:
00484     explicit compareEdges (CMP_FEATURE NFeature, Vector3 planeNormal = Vector3(0)){
00485       _planeNormal = planeNormal;
00486       switch(NFeature){
00487         case (CMP_LENGTH):
00488           _actComperator = &compareEdges::compareLength;
00489           break;
00490         case (CMP_VOLUME):
00491           _actComperator = &compareEdges::compareVolume;
00492           break;
00493         case (CMP_STVOLUME):
00494           _actComperator = &compareEdges::compareSTVolume;
00495           break;
00496         case (CMP_STCENTER_X):
00497           _actComperator = &compareEdges::compareSTCenterX;
00498           break;
00499         case (CMP_STCENTER_Y):
00500           _actComperator = &compareEdges::compareSTCenterY;
00501           break;
00502         case (CMP_STCENTER_Z):
00503           _actComperator = &compareEdges::compareSTCenterZ;
00504           break;
00505         case (CMP_STCENTER_PLANE):
00506           _actComperator = &compareEdges::compareSTCenterPlane;
00507           break;
00508         case (CMP_LABEL):
00509         default:
00510           _actComperator = &compareEdges::compareLabel;
00511           break;
00512       }
00513     }
00514 
00515     int operator() (const VesselEdge *pE1, const VesselEdge *pE2) const
00516       { return (this->*_actComperator)(pE1, pE2); }
00517 
00518   private: 
00520     int (compareEdges::*_actComperator) (const VesselEdge *pE1, const VesselEdge *pE2) const;
00521     Vector3 _planeNormal;
00522 
00523     int compareLabel         (const VesselEdge *pE1, const VesselEdge *pE2) const { return pE1->getLabel()             > pE2->getLabel(); }
00524     int compareLength        (const VesselEdge *pE1, const VesselEdge *pE2) const { return pE1->getLength()            > pE2->getLength(); }
00525     int compareVolume        (const VesselEdge *pE1, const VesselEdge *pE2) const { return pE1->getVolume()            > pE2->getVolume(); }
00526     int compareSTVolume      (const VesselEdge *pE1, const VesselEdge *pE2) const { return pE1->getSTVolume()          > pE2->getSTVolume(); }
00527     int compareSTCenterX     (const VesselEdge *pE1, const VesselEdge *pE2) const { return (pE1->getSTBarycenter())[0] > (pE2->getSTBarycenter())[0]; }
00528     int compareSTCenterY     (const VesselEdge *pE1, const VesselEdge *pE2) const { return (pE1->getSTBarycenter())[1] > (pE2->getSTBarycenter())[1]; }
00529     int compareSTCenterZ     (const VesselEdge *pE1, const VesselEdge *pE2) const { return (pE1->getSTBarycenter())[2] > (pE2->getSTBarycenter())[2]; }
00530     int compareSTCenterPlane (const VesselEdge *pE1, const VesselEdge *pE2) const { return (pE1->getSTBarycenter()-pE2->getSTBarycenter()).dot(_planeNormal) > 0; }
00531 
00532   };
00533 
00534 
00535   // ------------------------------------------------------------------
00537   // ------------------------------------------------------------------
00542   class VESSELGRAPH_EXPORT NodeAnalyser
00543   {
00544   public:    
00545     
00546     //--------------------------------------------------------
00548 
00549     //--------------------------------------------------------
00552     explicit NodeAnalyser (long NMode, DataMap * pData = NULL) : 
00553     _actMeasure (&NodeAnalyser::doNothing),
00554     _pData(pData)
00555     { 
00556       switch(NMode){
00557         case PROC_ROOT:
00558           if(_pData != NULL){
00559             if((*pData)[OUTDATA_ROOT] != NULL){
00560               *((long *) (*pData)[OUTDATA_ROOT]) = 0;
00561               _fDist = 0.0;
00562               _actMeasure = &NodeAnalyser::suggestRoot;
00563             }
00564           } else {
00565             _actMeasure = &NodeAnalyser::doNothing;
00566           }
00567           break;
00568         case PROC_CLUSTER:
00569           if(_pData != NULL){
00570             if((*pData)[OUTDATA_CLUSTER] != NULL){
00571               _actMeasure = &NodeAnalyser::setClusterLabel;
00572             }
00573           } else {
00574             _actMeasure = &NodeAnalyser::doNothing;
00575           }
00576           break;
00577         default:
00578           _actMeasure = &NodeAnalyser::doNothing;
00579       }
00580     }
00582 
00583 
00584     //--------------------------------------------------------
00586 
00587     //--------------------------------------------------------
00588     // function \c operator() provide singular outer access point
00589     inline void operator() (VesselNode *pNode){(this->*_actMeasure)(pNode);}
00591 
00592   
00593   private:
00594     //--------------------------------------------------------
00596 
00597     //--------------------------------------------------------
00599     void doNothing          (VesselNode * /*pNode*/) {}
00600 
00602     void suggestRoot        (VesselNode *pNode);
00603 
00605     void setClusterLabel    (VesselNode *pNode);
00607 
00608     //----------------------------------------------------------
00610 
00611     //----------------------------------------------------------
00613     void (NodeAnalyser::*_actMeasure) (VesselNode *pNode);
00614 
00616     DataMap * _pData;
00617 
00618     float _fDist;
00620   };
00621 
00622   // ------------------------------------------------------------------
00624   // ------------------------------------------------------------------
00631   class measureSkeletonAgent
00632   {
00633 
00635     class Process 
00636     {
00638       typedef void (measureSkeletonAgent::*ProcessFkt) (const Skeleton & oSkeleton, Process * pProcess);
00639     public:
00641       Process () : oProcess (&measureSkeletonAgent::doNothing), pResult (NULL)  {}
00642       Process(const Process & oP) : oProcess (oP.oProcess), pResult(oP.pResult) {}
00643 
00644         ProcessFkt      oProcess;         
00645         void            *pResult;         
00646     };
00647 
00649     friend class Process;
00650 
00652     typedef std::map<NProcessMode, Process>::iterator IProcess;
00653 
00654   public:
00655 
00656 
00657     //--------------------------------------------------------
00659 
00660     //--------------------------------------------------------
00663     measureSkeletonAgent(int nMode, DataMap * pData = NULL) : 
00664         _fLastLength(0.0),
00665         _pScale(NULL),
00666         _pData(pData)
00667       { 
00668         _MProcess.erase(_MProcess.begin(), _MProcess.end());
00669 
00670         if(_pData != NULL){
00671           if(nMode & PROC_LENGTH)
00672           {
00673             Process oProcess;
00674             oProcess.pResult = (*_pData)[OUTDATA_LENGTH];
00675             if(nMode & PROC_SCL){
00676               _pScale = (Vector3 *) (*_pData)[DATA_SCL];
00677               oProcess.oProcess = &measureSkeletonAgent::ProcessL1Scale;
00678             }
00679             else {
00680               oProcess.oProcess =&measureSkeletonAgent::ProcessL1;
00681             }
00682             _MProcess[PROC_LENGTH] = oProcess;
00683           }
00684 
00685           if(nMode & PROC_VOLUME)
00686           {
00687             Process oProcess;
00688             oProcess.pResult = (*_pData)[OUTDATA_VOLUME];
00689             oProcess.oProcess = &measureSkeletonAgent::ProcessV1;
00690             _MProcess[PROC_VOLUME] = oProcess;
00691           }
00692 
00693           if(nMode & PROC_WEIGHTED_POS)
00694           {
00695             Process oProcess;
00696             oProcess.pResult = (*_pData)[OUTDATA_POS];
00697             oProcess.oProcess = &measureSkeletonAgent::ProcessP1;
00698             _MProcess[PROC_WEIGHTED_POS] = oProcess;
00699           }
00700 
00701           if(nMode & PROC_AV_MIN_DIST)
00702           {
00703             Process oProcess;
00704             oProcess.pResult = (*_pData)[OUTDATA_AV_MIN_DIST];
00705             oProcess.oProcess = &measureSkeletonAgent::ProcessD1;
00706             _MProcess[PROC_AV_MIN_DIST] = oProcess;
00707           }
00708         }
00709       }
00711 
00712 
00713     //--------------------------------------------------------
00715 
00716     //--------------------------------------------------------
00718     inline void operator() (const Skeleton & oSkeleton) 
00719     {
00720       for(IProcess iProcess = _MProcess.begin(); iProcess != _MProcess.end(); ++iProcess){
00721          (this->*((iProcess->second).oProcess))(oSkeleton, &(iProcess->second));
00722       }
00723     }
00724     inline void operator() (Skeleton* oSkeleton)
00725     {
00726       for(IProcess iProcess = _MProcess.begin(); iProcess != _MProcess.end(); ++iProcess){
00727         (this->*((iProcess->second).oProcess))(*oSkeleton, &(iProcess->second));
00728       }
00729     }
00731 
00732 
00733 
00734   private:
00735 
00736     //--------------------------------------------------------
00738 
00739     //--------------------------------------------------------
00741     void doNothing       (const Skeleton & /*oSkeleton*/, Process * /*pProcess*/) {}
00742     
00745     void ProcessL1       (const Skeleton & oSkeleton, Process * pProcess);  
00746     void ProcessL1Scale  (const Skeleton & oSkeleton, Process * pProcess);  
00748     void ProcessL2       (const Skeleton & oSkeleton, Process * pProcess);  
00749     void ProcessL2Scale  (const Skeleton & oSkeleton, Process * pProcess);  
00751     void ProcessL3       (const Skeleton & oSkeleton, Process * pProcess);  
00752     void ProcessL3Scale  (const Skeleton & oSkeleton, Process * pProcess);
00753     
00755     void ProcessV1       (const Skeleton & oSkeleton, Process * pProcess);
00756 
00758     void ProcessP1       (const Skeleton & oSkeleton, Process * pProcess);
00759 
00761     void ProcessD1      (const Skeleton & oSkeleton, Process * pProcess);
00762 
00763 
00765 
00766     //----------------------------------------------------------
00768 
00769     //----------------------------------------------------------
00771     std::map<NProcessMode, Process> _MProcess;
00772 
00773 
00775     float _fLastLength;
00776 
00778     std::list<Vector3>  _LPoints;
00780     std::list<Vector3>::iterator IBack;    
00782     std::list<Vector3>::iterator IMiddle;  
00784     std::list<Vector3>::iterator IFront;
00785 
00786     // interpolated Skeleton position
00787     Vector3      _vMean;
00789     Vector3      * _pScale;
00790 
00792     DataMap   * _pData;
00794   };
00795 
00796   ML_END_NAMESPACE
00797 
00798 #endif // __GRAPHANALYSER_H
00799 
00800 
00801 
00802