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
00315
LayerPointerType GetActiveListForIndex (
const IndexType index)
00316 {
00317
00318 const unsigned int indexZ= index[m_SplitAxis];
00319
00320
const unsigned int ThreadNum= this->GetThreadNumber (indexZ);
00321
00322
return m_Data[ThreadNum].m_Layers[0];
00323 }
00324
00325
protected:
00326 ParallelSparseFieldLevelSetImageFilter();
00327 ~ParallelSparseFieldLevelSetImageFilter() {}
00328
virtual void PrintSelf(std::ostream& os, Indent indent)
const;
00329
00331 ParallelSparseFieldCityBlockNeighborList < NeighborhoodIterator<OutputImageType> >
00332 m_NeighborList;
00333
00336
static double m_ConstantGradientValue;
00337
00339 static ValueType m_ValueOne;
00340
00342 static ValueType m_ValueZero;
00343
00346
static StatusType m_StatusActiveChangingUp;
00347
00350
static StatusType m_StatusActiveChangingDown;
00351
00354
static StatusType m_StatusNull;
00355
00358
static StatusType m_StatusChanging;
00359
00362
static StatusType m_StatusBoundaryPixel;
00363
00368
typename OutputImageType::Pointer m_ShiftedImage;
00369
00374
LayerListType m_Layers;
00375
00379
StatusType m_NumberOfLayers;
00380
00382 typename StatusImageType::Pointer m_StatusImage;
00383
typename OutputImageType::Pointer m_OutputImage;
00384
00386 typename StatusImageType::Pointer m_StatusImageTemp;
00387
typename OutputImageType::Pointer m_OutputImageTemp;
00388
00390 typename LayerNodeStorageType::Pointer m_LayerNodeStore;
00391
00393 ValueType m_IsoSurfaceValue;
00394
00398
00399
00402
virtual void GenerateData();
00403
00408
void CopyInputToOutput();
00409
00411
void AllocateUpdateBuffer() {}
00412
00415
void Initialize();
00416
00421
void ConstructActiveLayer();
00422
00424
void InitializeActiveLayerValues();
00425
00429
void ConstructLayer(StatusType from, StatusType to);
00430
00432
void ProcessStatusList(LayerType *InputList, StatusType ChangeToStatus,
00433 StatusType SearchForStatus,
unsigned int ThreadId);
00434
00439
void PropagateAllLayerValues();
00440
00448
void PropagateLayerValues(StatusType from, StatusType to, StatusType promote,
00449
unsigned int InOrOut);
00450
00455
virtual void InitializeBackgroundPixels();
00456
00460
void ThreadedAllocateData(
unsigned int ThreadId);
00461
void ThreadedInitializeData(
unsigned int ThreadId,
const ThreadRegionType & ThreadRegion);
00462
00472
void ComputeInitialThreadBoundaries();
00473
00475
unsigned int GetThreadNumber(
unsigned int splitAxisValue);
00476
00478
void GetThreadRegionSplitByBoundary(
unsigned int ThreadId, ThreadRegionType& ThreadRegion);
00479
00482
void DeallocateData();
00483
00485
struct ParallelSparseFieldLevelSetThreadStruct
00486 {
00487 ParallelSparseFieldLevelSetImageFilter* Filter;
00488 TimeStepType* TimeStepList;
00489 bool* ValidTimeStepList;
00490
TimeStepType TimeStep;
00491 };
00492
00497
void Iterate();
00498
static ITK_THREAD_RETURN_TYPE IterateThreaderCallback(
void * arg);
00499
00504
inline virtual ValueType ThreadedCalculateUpdateValue(
const unsigned int itkNotUsed(ThreadId),
00505
const IndexType itkNotUsed(index),
00506
const TimeStepType &dt,
00507
const ValueType &value,
00508
const ValueType &change)
00509 {
00510
return (value + dt * change);
00511 }
00512
00513
00514
00515
00516
virtual void ThreadedProcessPixelEnteringActiveLayer (
const IndexType
itkNotUsed(index),
00517
const ValueType
itkNotUsed(value),
00518
const unsigned int itkNotUsed(ThreadId));
00519
00521
void ApplyUpdate(TimeStepType) {}
00522
00525
virtual void ThreadedApplyUpdate(TimeStepType dt,
unsigned int ThreadId);
00526
00528
TimeStepType CalculateChange()
00529 {
00530
return NumericTraits<TimeStepType>::Zero;
00531 }
00532
00535
virtual TimeStepType ThreadedCalculateChange(
unsigned int ThreadId);
00536
00543
void ThreadedUpdateActiveLayerValues(TimeStepType dt, LayerType *StatusUpList,
00544 LayerType *StatusDownList,
unsigned int ThreadId);
00545
00547
void CopyInsertList(
unsigned int ThreadId, LayerPointerType FromListPtr,
00548 LayerPointerType ToListPtr);
00549
00551
void ClearList(
unsigned int ThreadId, LayerPointerType ListPtr);
00552
00555
void CopyInsertInterNeighborNodeTransferBufferLayers(
unsigned int ThreadId,
00556 LayerPointerType InputList,
00557
unsigned int InOrOut,
00558
unsigned int BufferLayerNumber);
00559
00562
void ClearInterNeighborNodeTransferBufferLayers(
unsigned int ThreadId,
unsigned int InOrOut,
00563
unsigned int BufferLayerNumber);
00564
00572
void ThreadedProcessFirstLayerStatusLists(
unsigned int InputLayerNumber,
00573
unsigned int OutputLayerNumber,
00574 StatusType SearchForStatus,
00575
unsigned int InOrOut,
00576
unsigned int BufferLayerNumber,
unsigned int ThreadId);
00577
00583
void ThreadedProcessStatusList(
unsigned int InputLayerNumber,
unsigned int OutputLayerNumber,
00584 StatusType ChangeToStatus, StatusType SearchForStatus,
00585
unsigned int InOrOut,
00586
unsigned int BufferLayerNumber,
unsigned int ThreadId);
00587
00591
void ThreadedProcessOutsideList(
unsigned int InputLayerNumber, StatusType ChangeToStatus,
00592
unsigned int InOrOut,
unsigned int BufferLayerNumber,
unsigned int ThreadId);
00593
00595
void ThreadedPropagateLayerValues(StatusType from, StatusType to, StatusType promote,
00596
unsigned int InorOut,
unsigned int ThreadId);
00597
00600
void GetThreadRegionSplitUniformly(
unsigned int ThreadId, ThreadRegionType& ThreadRegion);
00601
00607
void ThreadedPostProcessOutput(
const ThreadRegionType & regionToProcess);
00608
00619
virtual void CheckLoadBalance();
00620
00623
virtual void ThreadedLoadBalance(
unsigned int ThreadId);
00624
00626
void WaitForAll();
00627
void SignalNeighborsAndWait (
unsigned int ThreadId);
00628
void SignalNeighbor (
unsigned int SemaphoreArrayNumber,
unsigned int ThreadId);
00629
void WaitForNeighbor (
unsigned int SemaphoreArrayNumber,
unsigned int ThreadId);
00630
00633
virtual void ThreadedInitializeIteration (
unsigned int ThreadId);
00634
00637
00638
00640
unsigned int m_NumOfThreads;
00641
00643
unsigned int m_SplitAxis;
00644
00646 unsigned int m_ZSize;
00647
00650
bool m_BoundaryChanged;
00651
00653
unsigned int * m_Boundary;
00654
00656 int * m_GlobalZHistogram;
00657
00659 unsigned int * m_MapZToThreadNumber;
00660
00663
int * m_ZCumulativeFrequency;
00664
00666
typename Barrier::Pointer m_Barrier;
00667
00669 struct ThreadData
00670 {
00671
char pad1 [128];
00672
00673
TimeStepType TimeStep;
00674
ThreadRegionType ThreadRegion;
00675 ValueType m_RMSChange;
00676
unsigned int m_Count;
00677
00679 LayerListType m_Layers;
00680
00682 LayerListType * m_LoadTransferBufferLayers;
00683
00685 typename LayerNodeStorageType::Pointer m_LayerNodeStore;
00686
00687
LayerPointerType UpList[2];
00688 LayerPointerType DownList[2];
00689
00692
LayerPointerType** m_InterNeighborNodeTransferBufferLayers[2];
00693
00696
void * globalData;
00697
00699
int * m_ZHistogram;
00700
00704
typename Semaphore::Pointer m_Semaphore[2];
00705
00707
unsigned int m_SemaphoreArrayNumber;
00708
00709
char pad2 [128];
00710 };
00711
00713 ThreadData *m_Data;
00714
00717
bool m_Stop;
00718
00723 bool m_InterpolateSurfaceLocation;
00724
00725
private:
00726
00727 ParallelSparseFieldLevelSetImageFilter(
const Self&);
00728
void operator=(
const Self&);
00729
00732
bool m_BoundsCheckingActive;
00733 };
00734
00735 }
00736
00737
#ifndef ITK_MANUAL_INSTANTIATION
00738
#include "itkParallelSparseFieldLevelSetImageFilter.txx"
00739
#endif
00740
00741
#endif