diff --git a/Superbuild/ITKExternal.cmake b/Superbuild/ITKExternal.cmake index 849217893..8631ec840 100644 --- a/Superbuild/ITKExternal.cmake +++ b/Superbuild/ITKExternal.cmake @@ -72,6 +72,7 @@ set(itk_CACHE_ARGS "-DModule_IITKIOMeta:BOOL=ON" "-DModule_ITKIONRRD:BOOL=ON" "-DModule_ITKDeprecated:BOOL=OFF" + "-DModule_GrowCut:BOOL=ON" "-DCMAKE_CXX_FLAGS:STATIC=${CMAKE_CXX_FLAGS}" "-DCMAKE_CXX_FLAGS_DEBUG:STATIC=${CMAKE_CXX_FLAGS_DEBUG}" "-DCMAKE_C_FLAGS:STATIC=${CMAKE_C_FLAGS}" @@ -89,7 +90,7 @@ if(BUILD_MOSAIC_TOOLS) ) endif() -SET(itk_GIT_TAG "v5.2.0") +SET(itk_GIT_TAG "v5.3rc01") # If CMake ever allows overriding the checkout command or adding flags, # git checkout -q will silence message about detached head (harmless). @@ -104,6 +105,6 @@ ExternalProject_Add(ITK_external # hardcoded, since we need this before ITK's configure step ExternalProject_Get_Property(ITK_external INSTALL_DIR) -SET(ITK_DIR "${INSTALL_DIR}/lib/cmake/ITK-5.2" CACHE PATH "") +SET(ITK_DIR "${INSTALL_DIR}/lib/cmake/ITK-5.3" CACHE PATH "") message(STATUS "ITK_DIR=${ITK_DIR}") diff --git a/src/Application/Tools/Algorithm/FastGrowCut.h b/src/Application/Tools/Algorithm/FastGrowCut.h deleted file mode 100644 index 3deb9075a..000000000 --- a/src/Application/Tools/Algorithm/FastGrowCut.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - For more information, please see: http://software.sci.utah.edu - - The MIT License - - Copyright (c) 2021 Scientific Computing and Imaging Institute, - University of Utah. - - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ - // Adapted from: https://github.com/ljzhu/FastGrowCut - -#ifndef FASTGROWCUT_H -#define FASTGROWCUT_H - -#include -#include -#include -#include -#include -#include -#include - -#include "utilities.h" - -#include "fibheap.h" -#include "HeapNode.h" -namespace FGC { - -const float DIST_INF = std::numeric_limits::max(); -const float DIST_EPSION = 1e-3; -const unsigned char NNGBH = 26; -typedef float FPixelType; - -template -class FastGrowCut { -public: - void SetSourceImage( const std::vector& imSrc ); - void SetSeedlImage( std::vector& imSeed ); - void SetWorkMode( bool bSegInitialized = false ); - void SetImageSize( const std::vector& imSize ); - void DoSegmentation(); - void GetLabeImage( std::vector& imLab ); - void GetForegroundmage( std::vector& imFgrd ); - -private: - void InitializationAHP(); - void DijkstraBasedClassificationAHP(); - - std::vector m_imSrc; - std::vector m_imSeed; - std::vector m_imLabPre; - std::vector m_imDistPre; - std::vector m_imLab; - std::vector m_imDist; - - std::vector m_imSize; - long m_DIMX{0}, m_DIMY{0}, m_DIMZ{0}, m_DIMXY{0}, m_DIMXYZ{0}; - std::vector m_indOff; - std::vector m_NBSIZE; - - FibHeap m_heap; - std::vector m_hpNodes; - bool m_bSegInitialized {false}; -}; -} // end namespace FGC - -#include "FastGrowCut.hxx" - -#endif // ifndef FASTGROWCUT_H diff --git a/src/Application/Tools/Algorithm/FastGrowCut.hxx b/src/Application/Tools/Algorithm/FastGrowCut.hxx deleted file mode 100644 index eb8ba733b..000000000 --- a/src/Application/Tools/Algorithm/FastGrowCut.hxx +++ /dev/null @@ -1,275 +0,0 @@ - -/* - For more information, please see: http://software.sci.utah.edu - - The MIT License - - Copyright (c) 2021 Scientific Computing and Imaging Institute, - University of Utah. - - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ - // Adapted from: https://github.com/ljzhu/FastGrowCut - -#include "FastGrowCut.h" - -#include "itkImageRegionIterator.h" -#include "itkImageRegionIteratorWithIndex.h" -#include "itkNumericTraits.h" -#include "itkRegionOfInterestImageFilter.h" -#include "HeapNode.h" - -namespace FGC { - -template -void FastGrowCut -::SetSourceImage(const std::vector& imSrc) { - - m_imSrc = imSrc; -} - -template -void FastGrowCut -::SetSeedlImage(std::vector& imSeed) { - - m_imSeed = imSeed; -} - -template -void FastGrowCut -::SetWorkMode(bool bSegUnInitialized ) { - - m_bSegInitialized = bSegUnInitialized; -} -template -void FastGrowCut -::SetImageSize(const std::vector& imSize) { - - m_imSize = imSize; -} - -template -void FastGrowCut -::InitializationAHP() { - - m_DIMX = m_imSize[0]; - m_DIMY = m_imSize[1]; - m_DIMZ = m_imSize[2]; - m_DIMXY = m_DIMX*m_DIMY; - m_DIMXYZ = m_DIMXY*m_DIMZ; - - m_hpNodes.resize(m_DIMXYZ+1); - m_heap.ClearHeapOwnership(); - - long i,j,k, index; - if(!m_bSegInitialized) { - m_imLab.resize(m_DIMXYZ); - m_imDist.resize(m_DIMXYZ); - m_imLabPre.resize(m_DIMXYZ); - m_imDistPre.resize(m_DIMXYZ); - // Compute index offset - m_indOff.clear(); - long ix,iy,iz; - for(ix = -1; ix <= 1; ix++) - for(iy = -1; iy <= 1; iy++) - for(iz = -1; iz <= 1; iz++) { - if(!(ix == 0 && iy == 0 && iz == 0)) { - m_indOff.push_back(ix + iy*m_DIMX + iz*m_DIMXY); - } - } - - // Determine neighborhood size at each vertice - m_NBSIZE = std::vector(m_DIMXYZ, 0); - for(i = 1; i < m_DIMX - 1; i++) - for(j = 1; j < m_DIMY - 1; j++) - for(k = 1; k < m_DIMZ - 1; k++) { - index = i + j*m_DIMX + k*m_DIMXY; - m_NBSIZE[index] = NNGBH; - } - - for(index = 0; index < m_DIMXYZ; index++) { - m_imLab[index] = m_imSeed[index]; - if(m_imLab[index] == 0) { - m_hpNodes[index] = (float)DIST_INF; - m_imDist[index] = DIST_INF; - } - else { - m_hpNodes[index] = (float)DIST_EPSION; - m_imDist[index] = DIST_EPSION; - } - - m_heap.Insert(&m_hpNodes[index]); - m_hpNodes[index].SetIndexValue(index); - } - } - // SB: If already initialized, then build heap - else { - for(index = 0; index < m_DIMXYZ; index++) { - if(m_imSeed[index] != 0 && m_imSeed[index] != m_imLabPre[index]) { -// if(m_imSeed[index] != 0 && (m_imDistPre[index] != 0 || (m_imDistPre[index] == 0 && \ -// m_imSeed[index] != m_imLabPre[index]))) { - m_hpNodes[index] = (float)DIST_EPSION; - m_imDist[index] = DIST_EPSION; - m_imLab[index] = m_imSeed[index]; - } - else { - m_hpNodes[index] = (float)DIST_INF; - m_imDist[index] = DIST_INF; - m_imLab[index] = 0; - } - m_heap.Insert(&m_hpNodes[index]); - m_hpNodes[index].SetIndexValue(index); - } - } -} - -template -void FastGrowCut -::DijkstraBasedClassificationAHP() { - - HeapNode *hnMin, hnTmp; - float t, tOri, tSrc; - long i, index, indexNgbh; - LabPixelType labSrc; - SrcPixelType pixCenter; - - // Insert 0 then extract it, which will balance heap - m_heap.Insert(&hnTmp); m_heap.ExtractMin(); - - long k = 0; - - // Adpative Dijkstra if already initialized - if(m_bSegInitialized) { - while(!m_heap.IsEmpty()) { - hnMin = (HeapNode *) m_heap.ExtractMin(); - index = hnMin->GetIndexValue(); - tSrc = hnMin->GetKeyValue(); - - // stop propagation when the new distance is larger than the previous one - if(tSrc == DIST_INF) break; - if(tSrc > m_imDistPre[index]) { - m_imDist[index] = m_imDistPre[index]; - m_imLab[index] = m_imLabPre[index]; - continue; - } - - labSrc = m_imLab[index]; - m_imDist[index] = tSrc; - - // Update neighbors - pixCenter = m_imSrc[index]; - for(i = 0; i < m_NBSIZE[index]; i++) { - - indexNgbh = index + m_indOff[i]; - tOri = m_imDist[indexNgbh]; - t = std::abs(pixCenter - m_imSrc[indexNgbh]) + tSrc; - if(tOri > t) { - m_imDist[indexNgbh] = t; - m_imLab[indexNgbh] = labSrc; - - hnTmp = m_hpNodes[indexNgbh]; - hnTmp.SetKeyValue(t); - m_heap.DecreaseKey(&m_hpNodes[indexNgbh], hnTmp); - } - - } - - k++; - - } - - // Update previous labels and distance information - for(long i = 0; i < m_DIMXYZ; i++) { - if(m_imDist[i] < DIST_INF) { - m_imLabPre[i] = m_imLab[i]; - m_imDistPre[i] = m_imDist[i]; - } - } - std::copy(m_imLabPre.begin(), m_imLabPre.end(), m_imLab.begin()); - std::copy(m_imDistPre.begin(), m_imDistPre.end(), m_imDist.begin()); - } - // Normal Dijkstra to be used in initializing the segmenter for the current image - else { - while(!m_heap.IsEmpty()) { - hnMin = (HeapNode *) m_heap.ExtractMin(); - index = hnMin->GetIndexValue(); - tSrc = hnMin->GetKeyValue(); - labSrc = m_imLab[index]; - m_imDist[index] = tSrc; - - // Update neighbors - pixCenter = m_imSrc[index]; - for(i = 0; i < m_NBSIZE[index]; i++) { - - indexNgbh = index + m_indOff[i]; - tOri = m_imDist[indexNgbh]; - t = std::abs(pixCenter - m_imSrc[indexNgbh]) + tSrc; - if(tOri > t) { - m_imDist[indexNgbh] = t; - m_imLab[indexNgbh] = labSrc; - - hnTmp = m_hpNodes[indexNgbh]; - hnTmp.SetKeyValue(t); - m_heap.DecreaseKey(&m_hpNodes[indexNgbh], hnTmp); - } - - } - - k++; - - } - } - - std::copy(m_imLab.begin(), m_imLab.end(), m_imLabPre.begin()); - std::copy(m_imDist.begin(), m_imDist.end(), m_imDistPre.begin()); - - m_hpNodes.clear(); -} - -template -void FastGrowCut -::DoSegmentation() { - - InitializationAHP(); - - DijkstraBasedClassificationAHP(); -} - -template -void FastGrowCut -::GetLabeImage(std::vector& imLab) { - - imLab.resize(m_DIMXYZ); - std::copy(m_imLab.begin(), m_imLab.end(), imLab.begin()); -} - -template -void FastGrowCut -::GetForegroundmage(std::vector& imFgrd) { - - long index; - imFgrd.resize(m_DIMXYZ); - index = 0; - for(index = 0; index < m_DIMXYZ; index++) { - imFgrd[index] = m_imLab[index] == 1 ? 1 :0; - } - -} -} // end FGC diff --git a/src/Application/Tools/Algorithm/GrowCutter.cc b/src/Application/Tools/Algorithm/GrowCutter.cc index f910b9e11..62967a2d8 100644 --- a/src/Application/Tools/Algorithm/GrowCutter.cc +++ b/src/Application/Tools/Algorithm/GrowCutter.cc @@ -158,14 +158,12 @@ void GrowCutter::execute() { this->fast_grow_cut_->SetInput( data_image_ ); this->fast_grow_cut_->SetSeedImage( background_image_ ); - this->fast_grow_cut_->SetInitializationFlag( this->initialization_flag_ ); this->fast_grow_cut_->GenerateData(); this->initialization_flag_ = true; } else { this->fast_grow_cut_->SetSeedImage( background_image_ ); - this->fast_grow_cut_->SetInitializationFlag( this->initialization_flag_ ); this->fast_grow_cut_->GenerateData(); } this->output_image_ = this->fast_grow_cut_->GetOutput(); diff --git a/src/Application/Tools/Algorithm/HeapNode.cc b/src/Application/Tools/Algorithm/HeapNode.cc deleted file mode 100644 index 8749cd167..000000000 --- a/src/Application/Tools/Algorithm/HeapNode.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* - For more information, please see: http://software.sci.utah.edu - - The MIT License - - Copyright (c) 2021 Scientific Computing and Imaging Institute, - University of Utah. - - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ -// Created by Salma Bengali on 4/15/14. - -#include "HeapNode.h" - -namespace FGC{ -void HeapNode::Print() { - FibHeapNode::Print(); - // mexPrintf( "%f (%d)" , N , IndexV ); -} - -void HeapNode::operator =(double NewKeyVal) { - HeapNode Tmp; - Tmp.N = N = NewKeyVal; - FHN_Assign(Tmp); -} - -void HeapNode::operator =(FibHeapNode& RHS) { - FHN_Assign(RHS); - N = ((HeapNode&) RHS).N; -} - -int HeapNode::operator ==(FibHeapNode& RHS) { - if (FHN_Cmp(RHS)) return 0; - return N == ((HeapNode&) RHS).N ? 1 : 0; -} - -int HeapNode::operator <(FibHeapNode& RHS) { - int X; - if ((X=FHN_Cmp(RHS)) != 0) - return X < 0 ? 1 : 0; - return N < ((HeapNode&) RHS).N ? 1 : 0; -} -} // end namespace diff --git a/src/Application/Tools/Algorithm/HeapNode.h b/src/Application/Tools/Algorithm/HeapNode.h deleted file mode 100644 index d875d5d55..000000000 --- a/src/Application/Tools/Algorithm/HeapNode.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - For more information, please see: http://software.sci.utah.edu - - The MIT License - - Copyright (c) 2021 Scientific Computing and Imaging Institute, - University of Utah. - - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ -// Created by Salma Bengali on 4/15/14. - -#ifndef ____HeapNode__ -#define ____HeapNode__ - -#include "fibheap.h" -/*************************************************************************** - * class HeapNode - ***************************************************************************/ -namespace FGC { - class HeapNode : public FibHeapNode { - float N; - long IndexV; - - public: - HeapNode() : FibHeapNode() { N = 0; } - virtual void operator =(FibHeapNode& RHS); - virtual int operator ==(FibHeapNode& RHS); - virtual int operator <(FibHeapNode& RHS); - virtual void operator =(double NewKeyVal ); - virtual void Print(); - double GetKeyValue() { return N; } - void SetKeyValue(double n) { N = n; } - long int GetIndexValue() { return IndexV; } - void SetIndexValue( long int v) { IndexV = v; } - }; -} - -#endif /* defined(____HeapNode__) */ diff --git a/src/Application/Tools/Algorithm/fibheap.cc b/src/Application/Tools/Algorithm/fibheap.cc deleted file mode 100644 index 46f64ee04..000000000 --- a/src/Application/Tools/Algorithm/fibheap.cc +++ /dev/null @@ -1,657 +0,0 @@ -#define _FIBHEAP_CPP - -//*************************************************************************** -// This Fibonacci heap implementation is Copyright (c) 1996 by John Boyer. -// See the header file for free usage information. -//*************************************************************************** -//https://github.com/ljzhu/FastGrowCut - -//*************************************************************************** -// The classes in this package are designed to allow the package user -// to quickly and easily develop applications that require a heap data -// structure. Using amortized analysis, the asymptotically fastest heap -// data structure is the Fibonacci heap. The constants are a little -// high so the real speed gain will not be seen until larger data sets -// are required, but in most cases, if the data set is small, then the -// run-time will be neglible anyway. -// -// To use this heap class you need do only two things. First, subclass -// the FibHeapNode class to create the class of objects that you'd -// like to store in a heap. Second, create an instance of the FibHeap -// class, which can then be used to Insert(), ExtractMin(), etc., -// instances of your FibHeapNode subclass. Notice that you don't need -// to create a subclass of the FibHeap class. -// -// The application-specific data object that you'd like to store in a heap -// will have a key value. In the class that you derive from FibHeapNode, -// you will need to define the key structure then provide assignment (=), -// equality (==) and less-than operators and a destructor. These functions -// are declared virtual so that the code in the FibHeap class can compare, -// assign and destroy your objects by calling on your code. -// -// The overloaded operators in your defined class MUST call functions in -// the Fibonacci heap node class first. For assignment, the function -// FHN_Assign() should be called before code that deals with the copy of -// the key value. For comparison operators, the function FHN_Cmp() should -// appear first. If it returns 0, then keys can be compared as normal. -// The following indicates what the three most common operators must do -// based on the return value of FHN_Cmp() -// -// For ==, if zero returned, then compare keys -// if non-zero X returned, then return 0 -// For <, if zero returned, then compare keys -// if non-zero X returned, then return X<0?1:0 -// For >, if zero returned, then compare keys -// if non-zero X returned, then return X>0?1:0 -//*************************************************************************** - - -#include -#include -#include -#include "fibheap.h" -using namespace std; - -//*************************************************************************** -//========================================================= -// FibHeapNode Constructor -//========================================================= -//*************************************************************************** - -//FibHeapNode::FibHeapNode() { -// Left = Right = Parent = Child = NULL; -// Degree = Mark = NegInfinityFlag = 0; -//} - -//========================================================= -// FibHeapNode Destructor -// -// Body is empty, but declaration is required in order to -// force virtual. This will ensure that FibHeap class -// calls derived class destructors. -//========================================================= - -FibHeapNode::~FibHeapNode() {} - -//========================================================= -// FHN_Assign() -// -// To be used as first step of an assignment operator in a -// derived class. The derived class will handle assignment -// of key value, and this function handles copy of the -// NegInfinityFlag (which overrides the key value if it is -// set). -//========================================================= - -//void FibHeapNode::FHN_Assign(FibHeapNode& RHS) { -// NegInfinityFlag = RHS.NegInfinityFlag; -//} - -//========================================================= -// FHN_Cmp() -// -// To be used as the first step of ALL comparators in a -// derived class. -// -// Compares the relative state of the two neg. infinity -// flags. Note that 'this' is the left hand side. If -// LHS neg. infinity is set, then it will be less than (-1) -// the RHS unless RHS neg. infinity flag is also set. -// Only if function returns 0 should the key comparison -// defined in the derived class be performed, e.g. -// -// For ==, if zero returned, then compare keys -// if non-zero X returned, then return 0 -// For <, if zero returned, then compare keys -// if non-zero X returned, then return X<0?1:0 -// For >, if zero returned, then compare keys -// if non-zero X returned, then return X>0?1:0 -//========================================================= - -//int FibHeapNode::FHN_Cmp(FibHeapNode& RHS) { -// if (NegInfinityFlag) -// return RHS.NegInfinityFlag ? 0 : -1; -// return RHS.NegInfinityFlag ? 1 : 0; -//} - -//======================================================================== -// We do, on occasion, compare and assign objects of type FibHeapNode, but -// only when the NegInfinityFlag is set. See for example FibHeap::Delete(). -// -// Also, these functions exemplify what a derived class should do. -//======================================================================== - -void FibHeapNode::operator =(FibHeapNode& RHS) { - FHN_Assign(RHS); - // Key assignment goes here in derived classes -} - -int FibHeapNode::operator ==(FibHeapNode& RHS) { - if (FHN_Cmp(RHS)) return 0; - // Key compare goes here in derived classes - return 1; -} - -int FibHeapNode::operator <(FibHeapNode& RHS) { - int X; - if ((X=FHN_Cmp(RHS)) != 0) - return X < 0 ? 1 : 0; - // Key compare goes here in derived classes - return 0; -} - -//========================================================= -// Print() -//========================================================= - -void FibHeapNode::Print() { - if (NegInfinityFlag) - cout << "-inf."; -} - -//*************************************************************************** -//=========================================================================== -// FibHeap Constructor -//=========================================================================== -//*************************************************************************** - -FibHeap::FibHeap() { - MinRoot = NULL; - NumNodes = NumTrees = NumMarkedNodes = 0; - ClearHeapOwnership(); -} - -//=========================================================================== -// FibHeap Destructor -//=========================================================================== - -FibHeap::~FibHeap() { - FibHeapNode *Temp; - - if (GetHeapOwnership()) { - while (MinRoot != NULL) { - Temp = ExtractMin(); - delete Temp; - } - } -} - -//=========================================================================== -// Insert() - O(1) actual; O(2) amortized -// -// I am using O(2) here to indicate that although Insert() is -// constant time, its amortized rating is more costly because some -// of the work of inserting is done by other operations such as -// ExtractMin(), which is where tree-balancing occurs. -// -// The child pointer is deliberately not set to NULL because Insert() -// is also used internally to help put whole trees onto the root list. -//=========================================================================== - -void FibHeap::Insert(FibHeapNode *NewNode) { - if (NewNode == NULL) return; - - // If the heap is currently empty, then new node becomes singleton - // circular root list - - if (MinRoot == NULL) - MinRoot = NewNode->Left = NewNode->Right = NewNode; - - else { - // Pointers from NewNode set to insert between MinRoot and MinRoot->Right - - NewNode->Right = MinRoot->Right; - NewNode->Left = MinRoot; - - // Set Pointers to NewNode - - NewNode->Left->Right = NewNode; - NewNode->Right->Left = NewNode; - - // The new node becomes new MinRoot if it is less than current MinRoot - - if (*NewNode < *MinRoot) - MinRoot = NewNode; - } - - // We have one more node in the heap, and it is a tree on the root list - - NumNodes++; - - NumTrees++; - NewNode->Parent = NULL; -} - -//=========================================================================== -// Union() - O(1) actual; O(1) amortized -//=========================================================================== - -void FibHeap::Union(FibHeap *OtherHeap) { - FibHeapNode *Min1, *Min2, *Next1, *Next2; - - if (OtherHeap == NULL || OtherHeap->MinRoot == NULL) return; - - // We join the two circular lists by cutting each list between its - // min node and the node after the min. This code just pulls those - // nodes into temporary variables so we don't get lost as changes - // are made. - - Min1 = MinRoot; - Min2 = OtherHeap->MinRoot; - Next1 = Min1->Right; - Next2 = Min2->Right; - - // To join the two circles, we join the minimum nodes to the next - // nodes on the opposite chains. Conceptually, it looks like the way - // two bubbles join to form one larger bubble. They meet at one point - // of contact, then expand out to make the bigger circle. - - Min1->Right = Next2; - Next2->Left = Min1; - Min2->Right = Next1; - Next1->Left = Min2; - - // Choose the new minimum for the heap - - if (*Min2 < *Min1) - MinRoot = Min2; - - // Set the amortized analysis statistics and size of the new heap - - NumNodes += OtherHeap->NumNodes; - NumMarkedNodes += OtherHeap->NumMarkedNodes; - NumTrees += OtherHeap->NumTrees; - - // Complete the union by setting the other heap to emptiness - // then destroying it - - OtherHeap->MinRoot = NULL; - OtherHeap->NumNodes = - OtherHeap->NumTrees = - OtherHeap->NumMarkedNodes = 0; - - delete OtherHeap; -} - -//=========================================================================== -// Minimum - O(1) actual; O(1) amortized -//=========================================================================== - -//FibHeapNode *FibHeap::Minimum() { -// return MinRoot; -//} - -//=========================================================================== -// ExtractMin() - O(n) worst-case actual; O(lg n) amortized -//=========================================================================== - -FibHeapNode *FibHeap::ExtractMin() { - FibHeapNode *Result; - FibHeap *ChildHeap = NULL; - - // Remove minimum node and set MinRoot to next node - - if ((Result = Minimum()) == NULL) - return NULL; - - MinRoot = Result->Right; - Result->Right->Left = Result->Left; - Result->Left->Right = Result->Right; - Result->Left = Result->Right = NULL; - - NumNodes --; - if (Result->Mark) { - NumMarkedNodes --; - Result->Mark = 0; - } - Result->Degree = 0; - - // Attach child list of Minimum node to the root list of the heap - // If there is no child list, then do no work - - if (Result->Child == NULL) { - if (MinRoot == Result) - MinRoot = NULL; - } - - // If MinRoot==Result then there was only one root tree, so the - // root list is simply the child list of that node (which is - // NULL if this is the last node in the list) - - else if (MinRoot == Result) - MinRoot = Result->Child; - - // If MinRoot is different, then the child list is pushed into a - // new temporary heap, which is then merged by Union() onto the - // root list of this heap. - - else { - ChildHeap = new FibHeap(); - ChildHeap->MinRoot = Result->Child; - } - - // Complete the disassociation of the Result node from the heap - - if (Result->Child != NULL) - Result->Child->Parent = NULL; - Result->Child = Result->Parent = NULL; - - // If there was a child list, then we now merge it with the - // rest of the root list - - if (ChildHeap) - Union(ChildHeap); - - // Consolidate heap to find new minimum and do reorganize work - - if (MinRoot != NULL) - _Consolidate(); - - // Return the minimum node, which is now disassociated with the heap - // It has Left, Right, Parent, Child, Mark and Degree cleared. - - return Result; -} - -//=========================================================================== -// DecreaseKey() - O(lg n) actual; O(1) amortized -// -// The O(lg n) actual cost stems from the fact that the depth, and -// therefore the number of ancestor parents, is bounded by O(lg n). -//=========================================================================== - -int FibHeap::DecreaseKey(FibHeapNode *theNode, FibHeapNode& NewKey) { - FibHeapNode *theParent; - - if (theNode==NULL || *theNode < NewKey) - return NOTOK; - - *theNode = NewKey; - - theParent = theNode->Parent; - if (theParent != NULL && *theNode < *theParent) { - _Cut(theNode, theParent); - _CascadingCut(theParent); - } - - if (*theNode < *MinRoot) - MinRoot = theNode; - - return OK; -} - -//=========================================================================== -// Delete() - O(lg n) amortized; ExtractMin() dominates -// -// Notice that if we don't own the heap nodes, then we clear the -// NegInfinityFlag on the deleted node. Presumably, the programmer -// will be reusing the node. -//=========================================================================== - -int FibHeap::Delete(FibHeapNode *theNode) { - FibHeapNode Temp; - int Result; - - if (theNode == NULL) return NOTOK; - - Temp.NegInfinityFlag = 1; - Result = DecreaseKey(theNode, Temp); - - if (Result == OK) - if (ExtractMin() == NULL) - Result = NOTOK; - - if (Result == OK) { - if (GetHeapOwnership()) - delete theNode; - else - theNode->NegInfinityFlag = 0; - } - - return Result; -} - -//======================================================================== -// Print() -// -// Used internally for debugging purposes. The function prints the key -// value for each node along the root list, then it calls itself on each -// child list. -//======================================================================== - -void FibHeap::Print(FibHeapNode *Tree, FibHeapNode *theParent) { - FibHeapNode* Temp = NULL; - - if (Tree == NULL) Tree = MinRoot; - - Temp = Tree; - do { - if (Temp->Left == NULL) - cout << "(Left is NULL)"; - Temp->Print(); - if (Temp->Parent != theParent) - cout << "(Parent is incorrect)"; - if (Temp->Right == NULL) - cout << "(Right is NULL)"; - else if (Temp->Right->Left != Temp) - cout << "(Error in left link left) ->"; - else cout << " <-> "; - - Temp = Temp->Right; - /* - if (kbhit() && getch() == 27) - { - cout << "Hit a key to resume or ESC to break\n"; - if (getch() == 27) - break; - } - */ - } while (Temp != NULL && Temp != Tree); - cout << '\n'; - - Temp = Tree; - do { - cout << "Children of "; - Temp->Print(); - cout << ": "; - if (Temp->Child == NULL) - cout << "NONE\n"; - else Print(Temp->Child, Temp); - Temp = Temp->Right; - } while (Temp!=NULL && Temp != Tree); - - if (theParent == NULL) { - char ch; - - cout << "Done Printing. Hit a key.\n"; - cin >> ch; - } -} - -//=========================================================================== -//=========================================================================== - -//void FibHeap::_Exchange(FibHeapNode*& N1, FibHeapNode*& N2) { -// FibHeapNode *Temp; -// Temp = N1; -// N1 = N2; -// N2 = Temp; -//} - -//=========================================================================== -// Consolidate() -// -// Internal function that reorganizes heap as part of an ExtractMin(). -// We must find new minimum in heap, which could be anywhere along the -// root list. The search could be O(n) since all nodes could be on -// the root list. So, we reorganize the tree into more of a binomial forest -// structure, and then find the new minimum on the consolidated O(lg n) sized -// root list, and in the process set each Parent pointer to NULL, and count -// the number of resulting subtrees. -// -// Note that after a list of n inserts, there will be n nodes on the root -// list, so the first ExtractMin() will be O(n) regardless of whether or -// not we consolidate. However, the consolidation causes subsequent -// ExtractMin() operations to be O(lg n). Furthermore, the extra cost of -// the first ExtractMin() is covered by the higher amortized cost of -// Insert(), which is the real governing factor in how costly the first -// ExtractMin() will be. -//=========================================================================== - -void FibHeap::_Consolidate() { - FibHeapNode *x, *y, *w; - FibHeapNode *A[1+8*sizeof(long)]; // 1+lg(n) - int I=0, Dn = 1+8*sizeof(long); - short d; - - // Initialize the consolidation detection array - - for (I=0; I < Dn; I++) - A[I] = NULL; - - // We need to loop through all elements on root list. - // When a collision of degree is found, the two trees - // are consolidated in favor of the one with the lesser - // element key value. We first need to break the circle - // so that we can have a stopping condition (we can't go - // around until we reach the tree we started with - // because all root trees are subject to becoming a - // child during the consolidation). - - MinRoot->Left->Right = NULL; - MinRoot->Left = NULL; - w = MinRoot; - - do { - //cout << "Top of Consolidate's loop\n"; - //Print(w); - - x = w; - d = x->Degree; - w = w->Right; - - // We need another loop here because the consolidated result - // may collide with another large tree on the root list. - - while (A[d] != NULL) { - y = A[d]; - if (*y < *x) - _Exchange(x, y); - if (w == y) w = y->Right; - _Link(y, x); - A[d] = NULL; - d++; - //cout << "After a round of Linking\n"; - //Print(x); - } - A[d] = x; - - } while (w != NULL); - - // Now we rebuild the root list, find the new minimum, - // set all root list nodes' parent pointers to NULL and - // count the number of subtrees. - - MinRoot = NULL; - NumTrees = 0; - for (I = 0; I < Dn; I++) - if (A[I] != NULL) - _AddToRootList(A[I]); -} - -//=========================================================================== -// The node y is removed from the root list and becomes a subtree of node x. -//=========================================================================== - -void FibHeap::_Link(FibHeapNode *y, FibHeapNode *x) { - // Remove node y from root list - - if (y->Right != NULL) - y->Right->Left = y->Left; - if (y->Left != NULL) - y->Left->Right = y->Right; - NumTrees--; - - // Make node y a singleton circular list with a parent of x - - y->Left = y->Right = y; - y->Parent = x; - - // If node x has no children, then list y is its new child list - - if (x->Child == NULL) - x->Child = y; - - // Otherwise, node y must be added to node x's child list - - else { - y->Left = x->Child; - y->Right = x->Child->Right; - x->Child->Right = y; - y->Right->Left = y; - } - - // Increase the degree of node x because it's now a bigger tree - - x->Degree ++; - - // Node y has just been made a child, so clear its mark - - if (y->Mark) NumMarkedNodes--; - y->Mark = 0; -} - -//=========================================================================== -//=========================================================================== - -void FibHeap::_AddToRootList(FibHeapNode *x) { - if (x->Mark) NumMarkedNodes --; - x->Mark = 0; - - NumNodes--; - Insert(x); -} - -//=========================================================================== -// Remove node x from the child list of its parent node y -//=========================================================================== - -void FibHeap::_Cut(FibHeapNode *x, FibHeapNode *y) { - if (y->Child == x) - y->Child = x->Right; - if (y->Child == x) - y->Child = NULL; - - y->Degree --; - - x->Left->Right = x->Right; - x->Right->Left = x->Left; - - _AddToRootList(x); -} - -//=========================================================================== -// Cuts each node in parent list, putting successive ancestor nodes on the -// root list until we either arrive at the root list or until we find an -// ancestor that is unmarked. When a mark is set (which only happens during -// a cascading cut), it means that one child subtree has been lost; if a -// second subtree is lost later during another cascading cut, then we move -// the node to the root list so that it can be re-balanced on the next -// consolidate. -//=========================================================================== - -void FibHeap::_CascadingCut(FibHeapNode *y) { - FibHeapNode *z = y->Parent; - - while (z != NULL) { - if (y->Mark == 0) { - y->Mark = 1; - NumMarkedNodes++; - z = NULL; - } else { - _Cut(y, z); - y = z; - z = y->Parent; - } - } -} diff --git a/src/Application/Tools/Algorithm/fibheap.h b/src/Application/Tools/Algorithm/fibheap.h deleted file mode 100644 index ff058455b..000000000 --- a/src/Application/Tools/Algorithm/fibheap.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef FIBHEAP_H -#define FIBHEAP_H - -//*************************************************************************** -// The Fibonacci heap implementation contained in FIBHEAP.H and FIBHEAP.CPP -// is Copyright (c) 1996 by John Boyer -// -// Once this Fibonacci heap implementation (the software) has been published -// by Dr. Dobb's Journal, permission to use and distribute the software is -// granted provided that this copyright notice remains in the source and -// and the author (John Boyer) is acknowledged in works that use this program. -// -// Every effort has been made to ensure that this implementation is free of -// errors. Nonetheless, the author (John Boyer) assumes no liability regarding -// your use of this software. -// -// The author would also be very glad to hear from anyone who uses the -// software or has any feedback about it. -// Email: jboyer@gulf.csc.uvic.ca -//*************************************************************************** -//https://github.com/ljzhu/FastGrowCut - -#define OK 0 -#define NOTOK -1 - -#include - -//====================================================== -// Fibonacci Heap Node Class -//====================================================== - -class FibHeap; - -class FibHeapNode -{ - friend class FibHeap; - FibHeapNode *Left, *Right, *Parent, *Child; - short Degree, Mark, NegInfinityFlag; - -protected: - inline int FHN_Cmp(FibHeapNode& RHS) { - if (NegInfinityFlag) - return RHS.NegInfinityFlag ? 0 : -1; - return RHS.NegInfinityFlag ? 1 : 0; - } - inline void FHN_Assign(FibHeapNode& RHS) { - NegInfinityFlag = RHS.NegInfinityFlag; - } - -public: - inline FibHeapNode() { - Left = Right = Parent = Child = NULL; - Degree = Mark = NegInfinityFlag = 0; - } - virtual ~FibHeapNode(); - virtual void operator =(FibHeapNode& RHS); - virtual int operator ==(FibHeapNode& RHS); - virtual int operator <(FibHeapNode& RHS); - - virtual void Print(); -}; - -//======================================================================== -// Fibonacci Heap Class -//======================================================================== - -class FibHeap -{ - FibHeapNode *MinRoot; - long NumNodes, NumTrees, NumMarkedNodes; - int HeapOwnershipFlag; - -public: - FibHeap(); - virtual ~FibHeap(); - - // The Standard Heap Operations - void Insert(FibHeapNode *NewNode); - void Union(FibHeap *OtherHeap); - inline FibHeapNode *Minimum() { return MinRoot; } - FibHeapNode *ExtractMin(); - int DecreaseKey(FibHeapNode *theNode, FibHeapNode& NewKey); - int Delete(FibHeapNode *theNode); - bool IsEmpty() {return (MinRoot == NULL);} - - // Extra utility functions - int GetHeapOwnership() { return HeapOwnershipFlag; }; - void SetHeapOwnership() { HeapOwnershipFlag = 1; }; - void ClearHeapOwnership() { HeapOwnershipFlag = 0; }; - long GetNumNodes() { return NumNodes; }; - long GetNumTrees() { return NumTrees; }; - long GetNumMarkedNodes() { return NumMarkedNodes; }; - void Print(FibHeapNode *Tree = NULL, FibHeapNode *theParent=NULL); - -private: - // Internal functions that help to implement the Standard Operations - inline void _Exchange(FibHeapNode* &N1, FibHeapNode* &N2) { - FibHeapNode *Temp; Temp = N1; N1 = N2; N2 = Temp; - } - void _Consolidate(); - void _Link(FibHeapNode *, FibHeapNode *); - void _AddToRootList(FibHeapNode *); - void _Cut(FibHeapNode *, FibHeapNode *); - void _CascadingCut(FibHeapNode *); -}; - -#endif /* FIBHEAP_H */ diff --git a/src/Application/Tools/Algorithm/itkFastGrowCut.h b/src/Application/Tools/Algorithm/itkFastGrowCut.h deleted file mode 100644 index c13fcb8a4..000000000 --- a/src/Application/Tools/Algorithm/itkFastGrowCut.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - For more information, please see: http://software.sci.utah.edu - - The MIT License - - Copyright (c) 2021 Scientific Computing and Imaging Institute, - University of Utah. - - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ - // Adapted from: https://github.com/ljzhu/FastGrowCut - -#ifndef itkFastGrowCut_h -#define itkFastGrowCut_h - -#include - -#include -#include -#include - -namespace itk -{ -template -class ITK_TEMPLATE_EXPORT FastGrowCut : public ImageToImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_MOVE(FastGrowCut); - - /** Standard class type aliases. */ - using Self = FastGrowCut; - using Superclass = ImageToImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(FastGrowCut, ImageToImageFilter); - - using InputImageType = TInputImage; - using InputImagePointer = typename InputImageType::Pointer; - using InputImageRegionType = typename InputImageType::RegionType; - using InputImagePixelType = typename InputImageType::PixelType; - using IndexType = typename InputImageType::IndexType; - using SizeType = typename InputImageType::SizeType; - - using LabelImageType = TLabelImage; - using LabelPixelType = typename LabelImageType::PixelType; - using LabelImagePointer = typename LabelImageType::Pointer; - using LabelImageRegionType = typename LabelImageType::RegionType; - using LabelImagePixelType = typename LabelImageType::PixelType; - - using SeedsContainerType = std::vector; - - using InputRealType = typename NumericTraits::RealType; - - itkSetMacro(InitializationFlag, bool); - - void - PrintSelf(std::ostream & os, Indent indent) const override; - - void - SetSeedImage(const LabelImageType* seedImage) - { - // Process object is not const-correct so the const casting is required. - this->SetNthInput(1, const_cast(seedImage)); - } - const LabelImageType* - GetSeedImage() - { - return static_cast(this->ProcessObject::GetInput(1)); - } - - void GenerateData() override; - - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - static_assert(TInputImage::ImageDimension == 3, "FastGrowCut only works with 3D images"); - static_assert(TLabelImage::ImageDimension == 3, "FastGrowCut only works with 3D images"); - itkConceptMacro(InputHasNumericTraitsCheck, (Concept::HasNumericTraits)); - itkConceptMacro(OutputHasNumericTraitsCheck, (Concept::HasNumericTraits)); - // End concept checking -#endif - -protected: - FastGrowCut() = default; - ~FastGrowCut() override; - - // Override since the filter needs all the data for the algorithm - void - GenerateInputRequestedRegion() override; - - // Override since the filter produces the entire dataset - void - EnlargeOutputRequestedRegion(DataObject * output) override; - -private: - std::vector m_imSeedVec; - std::vector m_imLabVec; - std::vector m_imSrcVec; - std::vector m_imROI; - - //logic code - //Make smart pointer - FGC::FastGrowCut* m_fastGC = new FGC::FastGrowCut(); - - //state variables - bool m_InitializationFlag = false; -}; -} - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkFastGrowCut.hxx" -#endif - -#endif // ifndef itkFastGrowCut_h diff --git a/src/Application/Tools/Algorithm/itkFastGrowCut.hxx b/src/Application/Tools/Algorithm/itkFastGrowCut.hxx deleted file mode 100644 index 7d35255b4..000000000 --- a/src/Application/Tools/Algorithm/itkFastGrowCut.hxx +++ /dev/null @@ -1,159 +0,0 @@ -/* - For more information, please see: http://software.sci.utah.edu - - The MIT License - - Copyright (c) 2021 Scientific Computing and Imaging Institute, - University of Utah. - - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ - // Adapted from: https://github.com/ljzhu/FastGrowCut - -#ifndef itkFastGrowCut_hxx -#define itkFastGrowCut_hxx - -#include - -#include "itkFastGrowCut.h" -#include "FastGrowCut.h" - -#include -#include -#include -#include -#include - -namespace itk -{ -//if using smart pointer, don't need this destructor -template -FastGrowCut::~FastGrowCut() -{ - if ( this->m_fastGC != nullptr ) - { - delete m_fastGC; - } -} - -template -void -FastGrowCut::GenerateData() -{ - using OutputImageType = TOutputImage; - using OutputImageRegionType = typename OutputImageType::RegionType; - - using InputImageType = TInputImage; - using InputImageRegionType = typename InputImageType::RegionType; - - auto inputImage = this->GetInput(); - auto seedImage = this->GetSeedImage(); - auto outputImage = this->GetOutput(); - - // Copy seedImage into the output - InputImageRegionType region = inputImage->GetRequestedRegion(); - outputImage->SetLargestPossibleRegion(region); - outputImage->SetBufferedRegion(region); - outputImage->Allocate(); - ImageAlgorithm::Copy(seedImage,outputImage,region,region); - - itk::TimeProbe timer; - - timer.Start(); - - std::cerr << "InitializationFlag: " << m_InitializationFlag << std::endl; - // Find ROI - if ( !m_InitializationFlag ) - { - FGC::FindITKImageROI( outputImage, m_imROI ); - std::cerr << "image ROI = [" << m_imROI[0] << "," << m_imROI[1] << "," << m_imROI[2] << ";" \ - << m_imROI[3] << "," << m_imROI[4] << "," << m_imROI[5] << "]" << std::endl; - // SB: Find the ROI from the seed volume in the source volume and store it in m_imSrcVec - FGC::ExtractITKImageROI( inputImage, m_imROI, m_imSrcVec ); - } - // SB: Store the ROI from the seed volume in m_imSeedVec - FGC::ExtractITKImageROI( outputImage, m_imROI, m_imSeedVec ); - - // Initialize FastGrowCut - std::vector imSize( 3 ); - for ( int i = 0; i < 3; i++ ) - { - imSize[i] = m_imROI[i + 3] - m_imROI[i]; - } - m_fastGC->SetSourceImage( m_imSrcVec ); - m_fastGC->SetSeedlImage( m_imSeedVec ); - m_fastGC->SetImageSize( imSize ); - m_fastGC->SetWorkMode( m_InitializationFlag ); - - // Do Segmentation - m_fastGC->DoSegmentation(); - m_fastGC->GetForegroundmage( m_imLabVec ); - - // Update result. SB: Seed volume is replaced with grow cut result - FGC::UpdateITKImageROI( m_imLabVec, m_imROI, outputImage ); - - timer.Stop(); - - if ( !m_InitializationFlag ) - { - std::cout << "Initial fast GrowCut segmentation time: " << timer.GetMean() << " seconds\n"; - } - else - { - std::cout << "Adaptive fast GrowCut segmentation time: " << timer.GetMean() << " seconds\n"; - } -} - -template -void -FastGrowCut::EnlargeOutputRequestedRegion(DataObject * output) -{ - Superclass::EnlargeOutputRequestedRegion(output); - output->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -FastGrowCut::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - if (this->GetInput()) - { - InputImagePointer input = const_cast(this->GetInput()); - input->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -FastGrowCut::PrintSelf(std::ostream& os, Indent indent) const -{ - Superclass::PrintSelf(os, indent); - using namespace itk::print_helper; - os << indent << "InitializationFlag: " << m_InitializationFlag << std::endl; - os << indent << "imSeedVec: " << m_imSeedVec << std::endl; - os << indent << "imLabVec: " << m_imLabVec << std::endl; - os << indent << "imSrcVec: " << m_imSrcVec << std::endl; - os << indent << "imROI: " << m_imROI << std::endl; - os << indent << "FastGC: " << m_fastGC << std::endl; -} - -} -#endif // ifndef itkFastGrowCut_hxx diff --git a/src/Application/Tools/Algorithm/utilities.h b/src/Application/Tools/Algorithm/utilities.h deleted file mode 100644 index 0bd9af8ae..000000000 --- a/src/Application/Tools/Algorithm/utilities.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - For more information, please see: http://software.sci.utah.edu - - The MIT License - - Copyright (c) 2021 Scientific Computing and Imaging Institute, - University of Utah. - - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ - // Adapted from: https://github.com/ljzhu/FastGrowCut - -#ifndef utilities_hxx_ -#define utilities_hxx_ - -// std -#include -#include -#include - -// itk -#include "itkImage.h" -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" -#include "itkImportImageFilter.h" -#include "itkImageRegionIteratorWithIndex.h" -#include "itkRegionOfInterestImageFilter.h" - -#include - -namespace FGC -{ - - /* - * createImage - */ - - template - typename itkImageType::Pointer createImage(typename itkImageType::SizeType size, int iniValue) { - - typename itkImageType::Pointer img = itkImageType::New(); - typename itkImageType::SpacingType spacing; - typename itkImageType::IndexType start; - start.Fill(0); - spacing.Fill(1); - spacing[itkImageType::ImageDimension - 1] = 2; - - typename itkImageType::RegionType region; - img->SetSpacing(spacing); - region.SetSize(size); - region.SetIndex(start); - img->SetRegions(region); - img->Allocate(); - img->FillBuffer(static_cast(iniValue)); - - const typename itkImageType::SpacingType& sp = img->GetSpacing(); - std::cout << "Spacing = "; - std::cout << sp[0] << ", " << sp[1] << std::endl; - - - return img; - - } - -template -void FindITKImageROI(ITKImageType* im, std::vector& imROI) { - - typename ITKImageType::IndexType roiStart; - typename ITKImageType::IndexType roiEnd; - typename ITKImageType::IndexType start; - typename ITKImageType::SizeType size; - - size = im->GetLargestPossibleRegion().GetSize(); - start = im->GetLargestPossibleRegion().GetIndex(); - - - roiStart[0] = 0; roiStart[1] = 0; roiStart[2] = 0; - roiEnd[0] = 0; roiEnd[1] = 0; roiEnd[2] = 0; - - unsigned int ndims = im->GetImageDimension(); - - bool foundLabel = false; - itk::ImageRegionIteratorWithIndex< ITKImageType > label(im, im->GetBufferedRegion() ); - for(label.GoToBegin(); !label.IsAtEnd(); ++label) { - if(label.Get() != 0) { - typename ITKImageType::IndexType idx = label.GetIndex(); - for (unsigned i = 0; i < ndims; i++) { - if(!foundLabel) { - roiStart[i] = idx[i]; - roiEnd[i] = idx[i]; - } - else - { - if(idx[i] <= roiStart[i]) - { - roiStart[i] = idx[i]; - } - if(idx[i] >= roiEnd[i]) - { - roiEnd[i] = idx[i]; - } - } - } - foundLabel = true; - } - } - - int radius = 17; - for (unsigned i = 0; i < ndims; i++) { - int diff = static_cast< int > (roiStart[i] - radius); - if (diff >= start[i]) { - roiStart[i] -= radius; - } - else { - roiStart[i] = start[i]; - } - roiEnd[i] = (static_cast(roiEnd[i] + radius) < size[i]) ? (roiEnd[i] + radius) : size[i]-1; - - } - - // copy ROI to vector - imROI.resize(6); - for(unsigned i = 0; i < 3; i++) { - imROI[i] = roiStart[i]; - imROI[i + 3] = roiEnd[i]; - } -} - -template -void ExtractITKImageROI(const itk::Image* im, const std::vector& imROI, \ - std::vector& imROIVec) { - - // Copy itk image ROI to vector - typedef itk::Image ImageType; - typename ImageType::IndexType index; - long i,j,k,kk,DIMXYZ; - - DIMXYZ = (imROI[3] - imROI[0])*(imROI[4] - imROI[1])*(imROI[5] - imROI[2]); - imROIVec.clear(); - imROIVec.resize(DIMXYZ); - kk = 0; - for(k = imROI[2]; k < imROI[5]; k++) - for(j = imROI[1]; j < imROI[4]; j++) - for(i = imROI[0]; i < imROI[3]; i++) { - index[0] = i; index[1] = j; index[2] = k; - imROIVec[kk++] = im->GetPixel(index); - } -} - -template -void UpdateITKImageROI(const std::vector& imROIVec, const std::vector& imROI, \ - typename itk::Image::Pointer im) { - - typedef itk::Image ImageType; - typename ImageType::IndexType index; - long i,j,k,kk; - - // Set non-ROI as zeros - im->FillBuffer(0); - kk = 0; - for(k = imROI[2]; k < imROI[5]; k++) - for(j = imROI[1]; j < imROI[4]; j++) - for(i = imROI[0]; i < imROI[3]; i++) { - index[0] = i; index[1] = j; index[2] = k; - im->SetPixel(index, imROIVec[kk++]); - } -} - - - - - /** - * readImage - */ - template< typename itkImage_t > - typename itkImage_t::Pointer readImage(const char *fileName) - { - typedef itk::ImageFileReader< itkImage_t > ImageReaderType; - typename ImageReaderType::Pointer reader = ImageReaderType::New(); - reader->SetFileName(fileName); - - typename itkImage_t::Pointer image; - - try - { - reader->Update(); - image = reader->GetOutput(); - } - catch ( itk::ExceptionObject &err) - { - std::cerr<< "ExceptionObject caught !" << std::endl; - std::cerr<< err << std::endl; - raise(SIGABRT); - } - - return image; - } - - /** - * writeImage - */ - template< typename itkImage_t > void writeImage(typename itkImage_t::Pointer img, const char *fileName) - { - typedef itk::ImageFileWriter< itkImage_t > WriterType; - - typename WriterType::Pointer writer = WriterType::New(); - writer->SetFileName( fileName ); - writer->SetInput(img); - writer->UseCompressionOn(); - - try - { - writer->Update(); - } - catch ( itk::ExceptionObject &err) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - raise(SIGABRT); - } - } - - template - void WriteVectorIntoFile(const char* fnSave, const std::vector& vec) { - - try{ - std::ofstream outfile(fnSave); - outfile.write((const char *)&vec[0], vec.size()*sizeof(VType)); - } - catch ( itk::ExceptionObject &err) - { - std::cout << "Fail to write to file " << fnSave << std::endl; - std::cout << err << std::endl; - raise(SIGABRT); - } - } - - template - void LoadVectorIntoFile(const char* fnLoad, std::vector& vec, const long VEC_SIZE) { - - try{ - std::ifstream infile(fnLoad); - vec.resize(VEC_SIZE); - infile.read((char *)&vec[0], vec.size()*sizeof(VType)); - } - catch ( itk::ExceptionObject &err) - { - std::cout << "Fail to load file " << fnLoad << std::endl; - std::cout << err << std::endl; - raise(SIGABRT); - } - } -}// douher - -#endif diff --git a/src/Application/Tools/CMakeLists.txt b/src/Application/Tools/CMakeLists.txt index 8d2132fd7..f9a12c5a7 100644 --- a/src/Application/Tools/CMakeLists.txt +++ b/src/Application/Tools/CMakeLists.txt @@ -164,18 +164,9 @@ SET(APPLICATION_TOOLS_ACTIONS_SRCS ) SET(APPLICATION_TOOLS_ALGORITHM_SRCS - Algorithm/FastGrowCut.h - Algorithm/FastGrowCut.hxx - Algorithm/fibheap.h - Algorithm/fibheap.cc Algorithm/GrowCutter.h Algorithm/GrowCutter.cc - Algorithm/HeapNode.h - Algorithm/HeapNode.cc Algorithm/IslandRemoval.h - Algorithm/itkFastGrowCut.h - Algorithm/itkFastGrowCut.hxx - Algorithm/utilities.h ) IF(BUILD_WITH_PYTHON) @@ -184,6 +175,7 @@ IF(BUILD_WITH_PYTHON) endif() ITK_MODULE_LOAD(ITKCommon) +ITK_MODULE_LOAD(GrowCut) CORE_ADD_LIBRARY(Application_Tools ${APPLICATION_TOOLS_SRCS} @@ -208,6 +200,7 @@ target_link_libraries(Application_Tools Application_ToolManager ${SCI_BOOST_LIBRARY} ${ITKCommon_LIBRARIES} + ${GrowCut_LIBRARIES} ) # Register tool classes