/* * airwaysTree.h * * Created on: May 3, 2014 * Author: caceres@creatis.insa-lyon.fr */ #ifndef _AIRWAYS_TREE_H_ #define _AIRWAYS_TREE_H_ #include "airwaysTreeTypeDefinition.h" // VTK #include #include #include #include #include #include #include #include #include #include #include // ITK #include "itkImage.h" #include "itkImageRegionIterator.h" #include "itkLineIterator.h" #include #include namespace airways { // Types // Vector of nodes typedef std::vector vec_nodes; // Pair of nodes typedef std::pair pair_nodes; //Pair of a pair of nodes and a score typedef std::pair Pair_PairNodes_Score; /** * */ //typedef std::pair Pair_PairNodes_Score; /** * Vector of pairs of a pair of nodes and a score */ typedef std::vector Vector_Pair_PairNodes_Score; /*! * A vector stocking all the points between two nodes */ typedef std::vector vec_pair_posVox_rad; class AirwaysLib_EXPORT AirwaysTree { public: AirwaysTree(); AirwaysTree(TInputImage::Pointer img, TInputImage::Pointer img_sk, Node* root); AirwaysTree(TInputImage::Pointer image_airwaySegmentation, TInputImage::Pointer image_skeletonDM, EdgeVector& vector_edges, Edge* edge_trachea); //CERON // New constructor that doesn't update path info between nodes. AirwaysTree(TInputImage::Pointer image, TInputImage::Pointer image_skeleton, Node* root, bool shouldUpdate); virtual ~AirwaysTree(); /** * Getters */ Node* GetRoot() const; std::string GetImageName() const; std::string GetResultPath() const; TInputImage::Pointer GetSegmentedImage() const; TInputImage::Pointer GetSkeletonImage() const; const Node* GetNode(const Vec3 nodeCoords) const; /** * Method that return the node with the specified id * @param nId is id of the requested node * @return the requested id, NULL if not found */ Node* GetNodeById(unsigned int nId); /** * Method that returns the depth of the node whose id is given by parameter * @pre the node exist in the sub-tree * @param idNode is the search node id * @return the depth of the node up to the actual node */ int GetDepthById(unsigned int nId); unsigned int CountMarkedNodes(Node* current = NULL) const; /** * Method that returns the weight of the tree * @return the weight of the tree which is the number of nodes in the tree. */ unsigned int GetWeight( ) const; unsigned int GetHeight(Node* current = NULL) const; unsigned int GetLevels(Node* current = NULL, unsigned int cLevel = 0) const; /** * Method that returns the number of leafs in the tree * @return the number of leafs in the tree */ unsigned int GetNumberOfLeafs() const; const EdgeVector& GetEdges() const; const vec_nodes& GetNodes() const; /** * Method that returns the closest node of a given voxel. * The closes node is the one whose path to the father has the closest point to the given point * in real coordinates of the image. * @param voxel_x x componente of the voxel * @param voxel_y y componente of the voxel * @param voxel_z z componente of the voxel * @return the closest node to the given voxel */ const Node* GetClosestBrachNodeToIndex(float point_x, float point_y, float point_z) const; /** * Method that returns the list of nodes that influence the given point * @param point_x, point_y, point_z are the position of the point in real coordinates x, y, and z respectively. * @param vec_nodes_influence vector to save the nodes */ void GetBrancheNodesInfluencingPoint(float point_x, float point_y, float point_z, vec_nodes& vec_nodes_influence); AirwaysTree& GetTreeFromMarkedNodes(Node* currentNode = NULL, AirwaysTree* tree = NULL); AirwaysTree& GetSubTreeFromNode(Node* node, AirwaysTree* tree = NULL); AirwaysTree& GetSubTreeByLevels(const int& level, Node* node = NULL, AirwaysTree* tree = NULL); AirwaysTree& GetSubTreeByLength(const double& length, Node* node = NULL, AirwaysTree* tree = NULL, double cLenght = 0.0); AirwaysTree& GetSubTreeByRadius(const double& radius, Node* node = NULL, AirwaysTree* tree = NULL, double cRadius = 0.0); void MarkLevels(const int& level, Node* currentNode = NULL); bool IsEmpty() const; /** * Method that search a node inside a path. The path is defined by the starting and ending nodes * @param idNode_starting is the id of the starting node * @param idNode_ending is the id of the ending node * @param idNode_searched is the of the searched node * @return true if the searched node is inside the path, false otherwise */ bool IsNodeInsidePath(unsigned int idNode_starting, unsigned int idNode_ending, unsigned int idNode_searched); void SetRoot(Node* root); void SetImageName(const std::string& img_name); void SetResultPath(const std::string& folderPath); bool Insert(Edge* edge); void UnMarkAll(Node* currentNode = NULL); /** * Method that compares two tree starting from the root node. * @param treeB is the tree to be compared with * @param Q is the depth to select "fathers" nodes * @param F is the depth to select "family" nodes * @param commonA vector to save the common nodes for this subtree * @param commonA vector to save the common nodes for the subtree given by parameter * @param nonCommonA vector to save the non-common nodes for this subtree * @param nonCommonB vector to save the non-common nodes for the subtree given by parameter */ void CompareTreesOrkiszMorales(AirwaysTree& treeB, unsigned int Q, unsigned int F, vec_nodes& commonA, vec_nodes& commonB, vec_nodes& nonCommonA, vec_nodes& nonCommonB, std::map< unsigned int, std::vector >& map_A_to_B, std::map< unsigned int, std::vector >& map_B_to_A, std::vector< std::pair< std::pair, std::pair > >& vector_pair_edges_A_to_B); void MarkPathFromNodeToNode(Node* node_begin, Node* node_end); /** * Method that compares the actual tree with another given by parameter * @param treeB the tree to be compared with */ void CompareTrees(AirwaysTree& treeB); /** * Method that finds the pair, at least one is a leaf, with the lowest score * @param vectorPairNodesScore is the vector of pairs * @return the pair, at least one is a leaf, with the lowest score */ Pair_PairNodes_Score GetBestLeaf(Vector_Pair_PairNodes_Score vectorPairNodesScore); /** * Method that returns the pair of pair nodes and score for the given ids. * @param vectorPairNodesScore vector of pair nodes and score * @param idA is the first id if the pair nodes * @param idB is the second id if the pair nodes * @return the score for the given pair. */ double GetPairNodes_Score(Vector_Pair_PairNodes_Score vectorPairNodesScore, const unsigned int idA, const unsigned int idB); /** * Method that returns a copy of the tree * @return the copy of this tree */ AirwaysTree* GetCopy(); /** * Method that deleted a node, all his children, from the tree * @return true if the node was deleted (found), false otherwise */ bool DeleteNodeById(unsigned int nId); /** * Method that removes all the pairs that contains the a given id is a given component position. * @param vectorPairNodesScore the vector of pair nodes and score * @param component is the component position to be analyzed * @param nId is the searched id * @return the number of deleted pairs */ unsigned int DeleteEntriesByIdNode(Vector_Pair_PairNodes_Score& vectorPairNodesScore, unsigned int component, unsigned int nId); /** * Method that compares all the actual branches to all branches in the tree given by parameter * @param treeB in the tree to be compared with */ Vector_Pair_PairNodes_Score CompareAllBranches(AirwaysTree& treeB); /** * Method that return the composed edge from the root node to the node whose id is given by parameter * @param idNode is the id of the node where the complex edge ends. */ Edge* GetComposedEdge(unsigned int idNode); /** * Method that detaches a node and return a tree with a root and just the detaches node * @param nId is the id node to be searched * @return a tree with a root and just the detaches node */ AirwaysTree* GetSingleDetachedTreeNodeById(unsigned int nId); void UpdateLevels(unsigned int levels = 0); void SubIsomorphism(AirwaysTree& treeB); bool Isomorphism(AirwaysTree& tree); void ImageReconstructionFromNode(TInputImage::Pointer& result, Node* node, bool skeleton = false); void ImageReconstruction(TInputImage::Pointer& result, bool skeleton = false, Node* node = NULL); void ImageReconstructionBySpheres(TInputImage::Pointer& result, Node* node = NULL, bool useMarks = false); /** * Method that prints the airway up to a given level * @level is the level where the printing stops */ void printUpToLevel(int level); void printNodeAndChildrenIds(); /** * Method that creates the quaternions of the airways up to a given level * @level is the level where the creation stops. * @pre level >= 2 */ void createQuaternionsUpToLevel(int level); /** * Method that prints the statistics of number of bifurcations in each node */ void getStatisticsBifurcations(); void saveAirwayAsVTK(const std::string filename, bool common = false); /** * Method that save the airways in a image * @param filename is the name of the image to be saved * @param dims is the image dimensions * @param spacing is the image spacing * @param origin is the image origin */ void saveAirwayToImage(std::string filename, int dims[3], double spc[3], double origin[3]); /** * Method that draws a line in an image * @initVoxel is the initial voxel * @endVoxel is the final voxel * @imagePointer is the image pointer */ void drawLineInImage(Vec3 initVoxel, Vec3 endVoxel, TInputImage::Pointer imagePointer); void drawLine(int* pixelPointInit, int* pixelPointEnd, TInputImage::Pointer _imagePointer); protected: Node* GetNode(const Vec3 nodeCoords, Node* current = NULL); Node* GetLeaf(Node* current = NULL); void UpdateEdges(Node* node = NULL); AirwaysTree& GetSubTreeByDetachingNode(Node* node); /** * Method that adds an edge to the graph given by parameter * @param source is the source vertex of the edge * @param target is the target vertex of the edge * @param graph is the graph to add the new edge */ DiGraph_EdgePair AddBoostEdge(const pair_posVox_rad& source, const pair_posVox_rad& target, DiGraph& graph); bool FindNeighborhood(DiGraph& graph, Vec3Queue& queue, Vec3List& used, const Vec3& end, ConstNeighborhoodIterator& iterator); /** * Method that return the shortest* path between two nodes, begin and end. *As we are dealing with arborescent trees * then there is just one path between two nodes! * The path goes from the end to the begin pixel! * @param graph containing all the nodes and edges * @param begin is the starting node * @param end is the ending node * @return the shortest path between the starting and ending nodes or vertices. */ DiGraph GetGraphShortestPath(const DiGraph& graph, const Vec3& begin, const Vec3& end); vec_pair_posVox_rad GetGraphShortestPath_AMP(const DiGraph& graph, const Vec3& begin, const Vec3& end); vec_pair_posVox_rad GetSkeletonInfoFromEdge(const Vec3& begin, const Vec3& end); bool ComputeSimpleRegionGrowing(TInputImage::Pointer& img, const Vec3 seedPtn); void RemoveBranchFromImage(TInputImage::Pointer& img, Node* node); void CreateSpheres(TInputImage::Pointer& img, Node* node); void CalculateVTKLinesFromEdges(const Node* node, const unsigned int& parentId, unsigned int& cId, vtkSmartPointer& pts, vtkSmartPointer& lines, vtkSmartPointer& colors, bool common); void FillTree(Node* node); protected: std::string m_img_name; std::string m_result_path; TInputImage::Pointer m_skeleton; TInputImage::Pointer m_img; Node* m_root; vec_nodes m_nodes; EdgeVector m_edges; }; } /* namespace airways */ #endif /* AIRWAYSTREE_H_ */