ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkParallelSparseFieldLevelSetImageFilter.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkParallelSparseFieldLevelSetImageFilter_h
19 #define itkParallelSparseFieldLevelSetImageFilter_h
20 
22 #include "itkSparseFieldLayer.h"
23 #include "itkObjectStore.h"
25 #include "itkMultiThreaderBase.h"
26 #include "itkBarrier.h"
27 #include <condition_variable>
28 #include <vector>
29 
30 namespace itk
31 {
37 template< typename TNodeIndexType >
38 class ITK_TEMPLATE_EXPORT ParallelSparseFieldLevelSetNode
39 {
40 public:
41  TNodeIndexType m_Index;
42  float m_Value;
45 };
46 
75 template< typename TNeighborhoodType >
77 {
78 public:
79  using NeighborhoodType = TNeighborhoodType;
82 
83  static constexpr unsigned int Dimension = NeighborhoodType::Dimension;
84 
85  const RadiusType & GetRadius() const
86  {
87  return m_Radius;
88  }
89 
90  const unsigned int & GetArrayIndex(unsigned int i) const
91  {
92  return m_ArrayIndex[i];
93  }
94 
95  const OffsetType & GetNeighborhoodOffset(unsigned int i) const
96  {
97  return m_NeighborhoodOffset[i];
98  }
99 
100  const unsigned int & GetSize() const
101  {
102  return m_Size;
103  }
104 
105  unsigned int GetStride(unsigned int i)
106  {
107  return m_StrideTable[i];
108  }
109 
111 
113  {
114  m_ArrayIndex.clear();
115  m_NeighborhoodOffset.clear();
116  }
117 
118  void Print(std::ostream & os) const;
119 
120 private:
121  char m_Pad1[128];
122  unsigned int m_Size;
124  std::vector< unsigned int > m_ArrayIndex;
125  std::vector< OffsetType > m_NeighborhoodOffset;
126 
129  unsigned int m_StrideTable[Dimension];
130  char m_Pad2[128];
131 };
132 
249 template< typename TInputImage, typename TOutputImage >
250 class ITK_TEMPLATE_EXPORT ParallelSparseFieldLevelSetImageFilter:
251  public FiniteDifferenceImageFilter< TInputImage, TOutputImage >
252 {
253 public:
254  ITK_DISALLOW_COPY_AND_ASSIGN(ParallelSparseFieldLevelSetImageFilter);
255 
261 
263  using TimeStepType = typename Superclass::TimeStepType;
264  using FiniteDifferenceFunctionType = typename Superclass::FiniteDifferenceFunctionType;
265  using RadiusType = typename Superclass::RadiusType;
266  using NeighborhoodScalesType = typename Superclass::NeighborhoodScalesType;
267 
269  itkNewMacro(Self);
270 
273 
275  using InputImageType = TInputImage;
276  using OutputImageType = TOutputImage;
278 
279  static constexpr unsigned int ImageDimension = TOutputImage::ImageDimension;
280 
281  using PixelType = typename OutputImageType::PixelType;
282 
284 
287  using ValueType = typename OutputImageType::ValueType;
288 
291 
295 
297  using LayerListType = std::vector< LayerPointerType >;
298 
300  using StatusType = signed char;
301 
305 
309 
311 
315  itkSetMacro(NumberOfLayers, StatusType);
316  itkGetConstMacro(NumberOfLayers, StatusType);
318 
320  itkSetMacro(IsoSurfaceValue, ValueType);
321  itkGetConstMacro(IsoSurfaceValue, ValueType);
323 
325  {
326  // get the 'z' value for the index
327  const unsigned int indexZ = index[m_SplitAxis];
328  // get the thread in whose region the index lies
329  const unsigned int ThreadNum = this->GetThreadNumber (indexZ);
330 
331  // get the active list for that thread
332  return m_Data[ThreadNum].m_Layers[0];
333  }
334 
335 #ifdef ITK_USE_CONCEPT_CHECKING
336  // Begin concept checking
337  itkConceptMacro( OutputEqualityComparableCheck,
339  itkConceptMacro( DoubleConvertibleToOutputCheck,
341  itkConceptMacro( OutputOStreamWritableCheck,
343  // End concept checking
344 #endif
345 
346 protected:
348  ~ParallelSparseFieldLevelSetImageFilter() override = default;
349  void PrintSelf(std::ostream & os, Indent indent) const override;
350 
354 
357  double m_ConstantGradientValue{1.0};
358 
361 
364 
368 
372 
376 
380 
384 
389  typename OutputImageType::Pointer m_ShiftedImage;
390 
396 
402 
405  typename OutputImageType::Pointer m_OutputImage;
406 
410  typename OutputImageType::Pointer m_OutputImageTemp;
411 
414 
417 
421  // ValueType m_RMSChange;
422 
425  void GenerateData() override;
426 
431  void CopyInputToOutput() override;
432 
434  void AllocateUpdateBuffer() override {}
435 
438  void Initialize() override;
439 
444  void ConstructActiveLayer();
445 
447  void InitializeActiveLayerValues();
448 
452  void ConstructLayer(const StatusType& from, const StatusType& to);
453 
455  void ProcessStatusList(LayerType *InputList, const StatusType& ChangeToStatus,
456  const StatusType& SearchForStatus, ThreadIdType ThreadId);
457 
462  void PropagateAllLayerValues();
463 
471  void PropagateLayerValues(const StatusType& from, const StatusType& to,
472  const StatusType& promote, unsigned int InOrOut);
473 
478  virtual void InitializeBackgroundPixels();
479 
483  void ThreadedAllocateData(ThreadIdType ThreadId);
484 
485  void ThreadedInitializeData(ThreadIdType ThreadId, const ThreadRegionType & ThreadRegion);
486 
496  void ComputeInitialThreadBoundaries();
497 
499  unsigned int GetThreadNumber(unsigned int splitAxisValue);
500 
502  void GetThreadRegionSplitByBoundary(ThreadIdType ThreadId, ThreadRegionType & ThreadRegion);
503 
506  void DeallocateData();
507 
511  std::vector< TimeStepType > TimeStepList;
512  std::vector< bool > ValidTimeStepList;
514  };
515 
520  void Iterate();
521 
522  static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION IterateThreaderCallback(void *arg);
523 
528  inline virtual ValueType ThreadedCalculateUpdateValue(const ThreadIdType itkNotUsed(ThreadId),
529  const IndexType itkNotUsed(index),
530  const TimeStepType & dt,
531  const ValueType & value,
532  const ValueType & change)
533  {
534  return ( value + static_cast< ValueType >( dt ) * change );
535  }
536 
537  // This method can be overridden in derived classes.
538  // The pixel at 'index' is entering the active layer for thread 'ThreadId'.
539  // The outputimage at 'index' will have the value as given by the
540  // 'value' parameter.
541  virtual void ThreadedProcessPixelEnteringActiveLayer( const IndexType& itkNotUsed(index),
542  const ValueType& itkNotUsed(value),
543  ThreadIdType itkNotUsed(ThreadId) );
544 
546  void ApplyUpdate(const TimeStepType&) override {}
547 
550  virtual void ThreadedApplyUpdate(const TimeStepType& dt, ThreadIdType ThreadId);
551 
554  {
556  }
557 
560  virtual TimeStepType ThreadedCalculateChange(ThreadIdType ThreadId);
561 
568  void ThreadedUpdateActiveLayerValues( const TimeStepType& dt,
569  LayerType *StatusUpList,
570  LayerType *StatusDownList,
571  ThreadIdType ThreadId);
572 
575  void CopyInsertList( ThreadIdType ThreadId,
576  LayerPointerType FromListPtr,
577  LayerPointerType ToListPtr);
578 
580  void ClearList(ThreadIdType ThreadId, LayerPointerType ListPtr);
581 
584  void CopyInsertInterNeighborNodeTransferBufferLayers(
585  ThreadIdType ThreadId,
586  LayerPointerType InputList,
587  unsigned int InOrOut,
588  unsigned int BufferLayerNumber);
589 
592  void ClearInterNeighborNodeTransferBufferLayers(
593  ThreadIdType ThreadId, unsigned int InOrOut,
594  unsigned int BufferLayerNumber);
595 
603  void ThreadedProcessFirstLayerStatusLists(
604  unsigned int InputLayerNumber,
605  unsigned int OutputLayerNumber,
606  const StatusType& SearchForStatus,
607  unsigned int InOrOut,
608  unsigned int BufferLayerNumber,
609  ThreadIdType ThreadId);
610 
616  void ThreadedProcessStatusList(
617  unsigned int InputLayerNumber,
618  unsigned int OutputLayerNumber,
619  const StatusType& ChangeToStatus,
620  const StatusType& SearchForStatus,
621  unsigned int InOrOut,
622  unsigned int BufferLayerNumber,
623  ThreadIdType ThreadId);
624 
628  void ThreadedProcessOutsideList(
629  unsigned int InputLayerNumber,
630  const StatusType& ChangeToStatus,
631  unsigned int InOrOut,
632  unsigned int BufferLayerNumber,
633  ThreadIdType ThreadId);
634 
636  void ThreadedPropagateLayerValues(
637  const StatusType& from,
638  const StatusType& to,
639  const StatusType& promote,
640  unsigned int InorOut,
641  ThreadIdType ThreadId);
642 
645  void GetThreadRegionSplitUniformly(
646  ThreadIdType ThreadId, ThreadRegionType & ThreadRegion);
647 
653  void ThreadedPostProcessOutput(const ThreadRegionType & regionToProcess);
654 
665  virtual void CheckLoadBalance();
666 
669  virtual void ThreadedLoadBalance(ThreadIdType ThreadId);
670 
672  void WaitForAll();
673 
674  void SignalNeighborsAndWait(ThreadIdType ThreadId);
675 
676  void SignalNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId);
677 
678  void WaitForNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId);
679 
682  virtual void ThreadedInitializeIteration(ThreadIdType ThreadId);
683 
686  // void WriteActivePointsToFile ();
687 
689  ThreadIdType m_NumOfThreads{0};
690 
692  unsigned int m_SplitAxis{0};
693 
695  unsigned int m_ZSize{0};
696 
699  bool m_BoundaryChanged{false};
700 
702  unsigned int *m_Boundary{nullptr};
703 
705  int *m_GlobalZHistogram{nullptr};
706 
709  unsigned int *m_MapZToThreadNumber{nullptr};
710 
713  int *m_ZCumulativeFrequency{nullptr};
714 
717 
719  struct ThreadData {
720  char pad1[128];
721 
725  unsigned int m_Count;
726 
729 
732 
735 
736  LayerPointerType UpList[2];
737  LayerPointerType DownList[2];
738 
741  LayerPointerType **m_InterNeighborNodeTransferBufferLayers[2];
742 
745  void *globalData;
746 
749 
754  int m_Semaphore[2];
755 
756  std::mutex m_Lock[2];
757  std::condition_variable m_Condition[2];
758 
762 
763  char m_Pad2[128];
764  };
765 
769 
772  bool m_Stop{false};
773 
778  bool m_InterpolateSurfaceLocation{true};
779 
780 private:
781 
784  bool m_BoundsCheckingActive{false};
785 };
786 } // end namespace itk
787 
788 #ifndef ITK_MANUAL_INSTANTIATION
789 #include "itkParallelSparseFieldLevelSetImageFilter.hxx"
790 #endif
791 
792 #endif
A convenience class for storing indices which reference neighbor pixels within a neighborhood.
typename FiniteDifferenceFunctionType::NeighborhoodScalesType NeighborhoodScalesType
Define numeric traits for std::vector.
ParallelSparseFieldCityBlockNeighborList< NeighborhoodIterator< OutputImageType > > m_NeighborList
The base class for all process objects (source, filters, mappers) in the Insight data processing pipe...
itk::ITK_THREAD_RETURN_TYPE ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
Base class for all process objects that output image data.
virtual ValueType ThreadedCalculateUpdateValue(const ThreadIdType, const IndexType, const TimeStepType &dt, const ValueType &value, const ValueType &change)
This class implements a finite difference partial differential equation solver for evolving surfaces ...
TOutputImage OutputImageType
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image...
Definition: itkOffset.h:67
unsigned int ThreadIdType
Definition: itkIntTypes.h:99
typename Superclass::RadiusType RadiusType
typename Superclass::OffsetType OffsetType
Control indentation during Print() invocation.
Definition: itkIndent.h:49
A very simple linked list that is used to manage nodes in a layer of a sparse field level-set solver...
typename FiniteDifferenceFunctionType::RadiusType RadiusType
#define itkConceptMacro(name, concept)
typename FiniteDifferenceFunctionType::TimeStepType TimeStepType
A specialized memory management object for allocating and destroying contiguous blocks of objects...
Defines iteration of a local N-dimensional neighborhood of pixels across an itk::Image.
Templated n-dimensional image class.
Definition: itkImage.h:75