00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkParallelSparseFieldLevelSetImageFilter_h_
00018 #define __itkParallelSparseFieldLevelSetImageFilter_h_
00019
00020 #include <vector>
00021 #include "itkFiniteDifferenceImageFilter.h"
00022 #include "itkSparseFieldLayer.h"
00023 #include "itkObjectStore.h"
00024 #include "itkNeighborhoodIterator.h"
00025 #include "itkConstNeighborhoodIterator.h"
00026 #include "itkMultiThreader.h"
00027 #include "itkBarrier.h"
00028 #include "itkSemaphore.h"
00029
00030 namespace itk
00031 {
00032
00037 template <class TNodeIndexType>
00038 class ParallelSparseFieldLevelSetNode
00039 {
00040 public:
00041 TNodeIndexType m_Index;
00042 float m_Value;
00043 ParallelSparseFieldLevelSetNode *Next;
00044 ParallelSparseFieldLevelSetNode *Previous;
00045 };
00046
00073 template <class TNeighborhoodType>
00074 class ParallelSparseFieldCityBlockNeighborList
00075 {
00076 public:
00077 typedef TNeighborhoodType NeighborhoodType;
00078 typedef typename NeighborhoodType::OffsetType OffsetType;
00079 typedef typename NeighborhoodType::RadiusType RadiusType;
00080
00081 itkStaticConstMacro(Dimension, unsigned int, NeighborhoodType::Dimension);
00082
00083 const RadiusType &GetRadius() const
00084 {
00085 return m_Radius;
00086 }
00087
00088 const unsigned int &GetArrayIndex(unsigned int i) const
00089 {
00090 return m_ArrayIndex[i];
00091 }
00092
00093 const OffsetType &GetNeighborhoodOffset(unsigned int i) const
00094 {
00095 return m_NeighborhoodOffset[i];
00096 }
00097
00098 const unsigned int &GetSize() const
00099 {
00100 return m_Size;
00101 }
00102
00103 unsigned int GetStride(unsigned int i)
00104 {
00105 return m_StrideTable[i];
00106 }
00107
00108 ParallelSparseFieldCityBlockNeighborList();
00109
00110 ~ParallelSparseFieldCityBlockNeighborList()
00111 {
00112 m_ArrayIndex.clear();
00113 m_NeighborhoodOffset.clear();
00114 }
00115
00116 void Print(std::ostream &os) const;
00117
00118 private:
00119 char pad1[128];
00120 unsigned int m_Size;
00121 RadiusType m_Radius;
00122 std::vector<unsigned int> m_ArrayIndex;
00123 std::vector<OffsetType> m_NeighborhoodOffset;
00124
00127 unsigned int m_StrideTable[Dimension];
00128 char pad2[128];
00129 };
00130
00246 template <class TInputImage, class TOutputImage>
00247 class ITK_EXPORT ParallelSparseFieldLevelSetImageFilter :
00248 public FiniteDifferenceImageFilter<TInputImage, TOutputImage>
00249 {
00250 public:
00252 typedef ParallelSparseFieldLevelSetImageFilter Self;
00253 typedef FiniteDifferenceImageFilter<TInputImage, TOutputImage> Superclass;
00254 typedef SmartPointer<Self> Pointer;
00255 typedef SmartPointer<const Self> ConstPointer;
00256
00258 typedef typename Superclass::TimeStepType TimeStepType;
00259 typedef typename Superclass::FiniteDifferenceFunctionType FiniteDifferenceFunctionType;
00260
00262 itkNewMacro(Self);
00263
00265 itkTypeMacro(ParallelSparseFieldLevelSetImageFilter, FiniteDifferenceImageFilter);
00266
00268 typedef TInputImage InputImageType;
00269 typedef TOutputImage OutputImageType;
00270 typedef typename OutputImageType::IndexType IndexType;
00271
00272 itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension);
00273
00274 typedef typename OutputImageType::PixelType PixelType;
00275
00276 typedef typename OutputImageType::RegionType ThreadRegionType;
00277
00280 typedef typename OutputImageType::ValueType ValueType;
00281
00283 typedef ParallelSparseFieldLevelSetNode<IndexType> LayerNodeType;
00284
00286 typedef SparseFieldLayer<LayerNodeType> LayerType;
00287 typedef typename LayerType::Pointer LayerPointerType;
00288
00290 typedef std::vector<LayerPointerType> LayerListType;
00291
00293 typedef signed char StatusType;
00294
00297 typedef Image<StatusType, itkGetStaticConstMacro(ImageDimension)> StatusImageType;
00298
00301 typedef ObjectStore<LayerNodeType> LayerNodeStorageType;
00302
00303 typedef Offset<itkGetStaticConstMacro(ImageDimension)> OffsetType;
00304
00308 itkSetMacro(NumberOfLayers, StatusType);
00309 itkGetMacro(NumberOfLayers, StatusType);
00310
00312 itkSetMacro(IsoSurfaceValue, ValueType);
00313 itkGetMacro(IsoSurfaceValue, ValueType);
00314
00318 itkGetMacro(RMSChange, ValueType);
00319
00320 protected:
00321 ParallelSparseFieldLevelSetImageFilter();
00322 ~ParallelSparseFieldLevelSetImageFilter() {}
00323 virtual void PrintSelf(std::ostream& os, Indent indent) const;
00324
00326 ParallelSparseFieldCityBlockNeighborList < NeighborhoodIterator<OutputImageType> >
00327 m_NeighborList;
00328
00331 static double m_ConstantGradientValue;
00332
00334 static ValueType m_ValueOne;
00335
00337 static ValueType m_ValueZero;
00338
00341 static StatusType m_StatusActiveChangingUp;
00342
00345 static StatusType m_StatusActiveChangingDown;
00346
00349 static StatusType m_StatusNull;
00350
00353 static StatusType m_StatusChanging;
00354
00357 static StatusType m_StatusBoundaryPixel;
00358
00363 typename OutputImageType::Pointer m_ShiftedImage;
00364
00369 LayerListType m_Layers;
00370
00374 StatusType m_NumberOfLayers;
00375
00377 typename StatusImageType::Pointer m_StatusImage;
00378 typename OutputImageType::Pointer m_OutputImage;
00379
00381 typename StatusImageType::Pointer m_StatusImageTemp;
00382 typename OutputImageType::Pointer m_OutputImageTemp;
00383
00385 typename LayerNodeStorageType::Pointer m_LayerNodeStore;
00386
00388 ValueType m_IsoSurfaceValue;
00389
00393 ValueType m_RMSChange;
00394
00397 virtual void GenerateData();
00398
00403 void CopyInputToOutput();
00404
00406 void AllocateUpdateBuffer() {}
00407
00410 void Initialize();
00411
00416 void ConstructActiveLayer();
00417
00419 void InitializeActiveLayerValues();
00420
00424 void ConstructLayer(StatusType from, StatusType to);
00425
00427 void ProcessStatusList(LayerType *InputList, StatusType ChangeToStatus,
00428 StatusType SearchForStatus, unsigned int ThreadId);
00429
00434 void PropagateAllLayerValues();
00435
00443 void PropagateLayerValues(StatusType from, StatusType to, StatusType promote,
00444 unsigned int InOrOut);
00445
00450 virtual void InitializeBackgroundPixels();
00451
00455 void ThreadedAllocateData(unsigned int ThreadId);
00456 void ThreadedInitializeData(unsigned int ThreadId, const ThreadRegionType & ThreadRegion);
00457
00467 void ComputeInitialThreadBoundaries();
00468
00470 unsigned int GetThreadNumber(unsigned int splitAxisValue);
00471
00473 void GetThreadRegionSplitByBoundary(unsigned int ThreadId, ThreadRegionType& ThreadRegion);
00474
00477 void DeallocateData();
00478
00480 struct ParallelSparseFieldLevelSetThreadStruct
00481 {
00482 ParallelSparseFieldLevelSetImageFilter* Filter;
00483 TimeStepType* TimeStepList;
00484 bool* ValidTimeStepList;
00485 TimeStepType TimeStep;
00486 };
00487
00492 void Iterate();
00493 static ITK_THREAD_RETURN_TYPE IterateThreaderCallback(void * arg);
00494
00499 inline virtual ValueType CalculateUpdateValue(const IndexType,
00500 const TimeStepType &dt,
00501 const ValueType &value,
00502 const ValueType &change)
00503 {
00504 return (value + dt * change);
00505 }
00506
00508 void ApplyUpdate(TimeStepType) {}
00509
00512 virtual void ThreadedApplyUpdate(TimeStepType dt, unsigned int ThreadId);
00513
00515 TimeStepType CalculateChange()
00516 {
00517 return NumericTraits<TimeStepType>::Zero;
00518 }
00519
00522 virtual TimeStepType ThreadedCalculateChange(unsigned int ThreadId);
00523
00527 void ThreadedUpdateActiveLayerValues(TimeStepType dt, LayerType *StatusUpList,
00528 LayerType *StatusDownList, unsigned int ThreadId);
00529
00531 void CopyInsertList(unsigned int ThreadId, LayerPointerType FromListPtr,
00532 LayerPointerType ToListPtr);
00533
00535 void ClearList(unsigned int ThreadId, LayerPointerType ListPtr);
00536
00539 void CopyInsertInterNeighborNodeTransferBufferLayers(unsigned int ThreadId,
00540 LayerPointerType InputList,
00541 unsigned int InOrOut,
00542 unsigned int BufferLayerNumber);
00543
00546 void ClearInterNeighborNodeTransferBufferLayers(unsigned int ThreadId, unsigned int InOrOut,
00547 unsigned int BufferLayerNumber);
00548
00556 void ThreadedProcessFirstLayerStatusLists(unsigned int InputLayerNumber,
00557 unsigned int OutputLayerNumber,
00558 StatusType SearchForStatus,
00559 unsigned int InOrOut,
00560 unsigned int BufferLayerNumber, unsigned int ThreadId);
00561
00563 void ThreadedProcessStatusList(unsigned int InputLayerNumber, unsigned int OutputLayerNumber,
00564 StatusType ChangeToStatus, StatusType SearchForStatus,
00565 unsigned int InOrOut,
00566 unsigned int BufferLayerNumber, unsigned int ThreadId);
00567
00569 void ThreadedProcessOutsideList(unsigned int InputLayerNumber, StatusType ChangeToStatus,
00570 unsigned int InOrOut, unsigned int BufferLayerNumber, unsigned int ThreadId);
00571
00573 void ThreadedPropagateLayerValues(StatusType from, StatusType to, StatusType promote,
00574 unsigned int InorOut, unsigned int ThreadId);
00575
00578 void GetThreadRegionSplitUniformly(unsigned int ThreadId, ThreadRegionType& ThreadRegion);
00579
00581 void ThreadedPostProcessOutput(const ThreadRegionType & regionToProcess);
00582
00593 virtual void CheckLoadBalance();
00594
00597 virtual void ThreadedLoadBalance(unsigned int ThreadId);
00598
00600 void WaitForAll();
00601 void SignalNeighborsAndWait (unsigned int ThreadId);
00602 void SignalNeighbor (unsigned int SemaphoreArrayNumber, unsigned int ThreadId);
00603 void WaitForNeighbor (unsigned int SemaphoreArrayNumber, unsigned int ThreadId);
00604
00607
00608
00610 unsigned int m_NumOfThreads;
00611
00613 unsigned int m_SplitAxis;
00614
00616 unsigned int m_ZSize;
00617
00620 bool m_BoundaryChanged;
00621
00623 unsigned int * m_Boundary;
00624
00626 int * m_GlobalZHistogram;
00627
00629 unsigned int * m_MapZToThreadNumber;
00630
00633 int * m_ZCumulativeFrequency;
00634
00636 typename Barrier::Pointer m_Barrier;
00637
00639 struct ThreadData
00640 {
00641 char pad1 [128];
00642
00643 TimeStepType TimeStep;
00644 ThreadRegionType ThreadRegion;
00645 ValueType m_RMSChange;
00646 unsigned int m_Count;
00647
00649 LayerListType m_Layers;
00650
00652 LayerListType * m_LoadTransferBufferLayers;
00653
00655 typename LayerNodeStorageType::Pointer m_LayerNodeStore;
00656
00657 LayerPointerType UpList[2];
00658 LayerPointerType DownList[2];
00659
00662 LayerPointerType** m_InterNeighborNodeTransferBufferLayers[2];
00663
00666 void * globalData;
00667
00669 int * m_ZHistogram;
00670
00674 typename Semaphore::Pointer m_Semaphore[2];
00675
00677 unsigned int m_SemaphoreArrayNumber;
00678
00679 char pad2 [128];
00680 };
00681
00683 ThreadData *m_Data;
00684
00687 bool m_Stop;
00688
00693 bool m_InterpolateSurfaceLocation;
00694
00695 private:
00696
00697 ParallelSparseFieldLevelSetImageFilter(const Self&);
00698 void operator=(const Self&);
00699
00702 bool m_BoundsCheckingActive;
00703 };
00704
00705 }
00706
00707 #ifndef ITK_MANUAL_INSTANTIATION
00708 #include "itkParallelSparseFieldLevelSetImageFilter.txx"
00709 #endif
00710
00711 #endif