ITK  6.0.0
Insight Toolkit
itkParallelSparseFieldLevelSetImageFilter.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
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 * https://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
21#include "itkBooleanStdVector.h"
23#include "itkSparseFieldLayer.h"
24#include "itkObjectStore.h"
27#include <condition_variable>
28#include <vector>
29
30namespace itk
31{
37template <typename TNodeIndexType>
38class ITK_TEMPLATE_EXPORT ParallelSparseFieldLevelSetNode
39{
40public:
41 TNodeIndexType m_Index;
42 float m_Value;
45};
46
75template <typename TNeighborhoodType>
77{
78public:
79 using NeighborhoodType = TNeighborhoodType;
80 using OffsetType = typename NeighborhoodType::OffsetType;
81 using RadiusType = typename NeighborhoodType::RadiusType;
82
83 static constexpr unsigned int Dimension = NeighborhoodType::Dimension;
84
85 const RadiusType &
86 GetRadius() const
87 {
88 return m_Radius;
89 }
90
91 const unsigned int &
92 GetArrayIndex(unsigned int i) const
93 {
94 return m_ArrayIndex[i];
95 }
96
97 const OffsetType &
98 GetNeighborhoodOffset(unsigned int i) const
99 {
100 return m_NeighborhoodOffset[i];
101 }
102
103 const unsigned int &
104 GetSize() const
105 {
106 return m_Size;
107 }
108
109 unsigned int
110 GetStride(unsigned int i)
111 {
112 return m_StrideTable[i];
113 }
114
116
118 {
119 m_ArrayIndex.clear();
120 m_NeighborhoodOffset.clear();
121 }
122
123 void
124 Print(std::ostream & os, Indent indent) const;
125
126private:
127 char m_Pad1[128]{};
128 unsigned int m_Size{ 2 * Dimension };
129 RadiusType m_Radius{};
130 std::vector<unsigned int> m_ArrayIndex{};
131 std::vector<OffsetType> m_NeighborhoodOffset{};
132
135 unsigned int m_StrideTable[Dimension]{};
136 char m_Pad2[128]{};
137};
138
255template <typename TInputImage, typename TOutputImage>
257 : public FiniteDifferenceImageFilter<TInputImage, TOutputImage>
258{
259public:
260 ITK_DISALLOW_COPY_AND_MOVE(ParallelSparseFieldLevelSetImageFilter);
261
267
269 using typename Superclass::TimeStepType;
270 using typename Superclass::FiniteDifferenceFunctionType;
271 using typename Superclass::RadiusType;
272 using typename Superclass::NeighborhoodScalesType;
273
275 itkNewMacro(Self);
276
278 itkOverrideGetNameOfClassMacro(ParallelSparseFieldLevelSetImageFilter);
279
281 using InputImageType = TInputImage;
282 using OutputImageType = TOutputImage;
284
285 static constexpr unsigned int ImageDimension = TOutputImage::ImageDimension;
286
287 using PixelType = typename OutputImageType::PixelType;
288
290
293 using ValueType = typename OutputImageType::ValueType;
294
297
301
303 using LayerListType = std::vector<LayerPointerType>;
304
306 using StatusType = signed char;
307
311
315
317
321 itkSetMacro(NumberOfLayers, StatusType);
322 itkGetConstMacro(NumberOfLayers, StatusType);
326 itkSetMacro(IsoSurfaceValue, ValueType);
327 itkGetConstMacro(IsoSurfaceValue, ValueType);
332 {
333 // get the 'z' value for the index
334 const unsigned int indexZ = index[m_SplitAxis];
335 // get the thread in whose region the index lies
336 const unsigned int ThreadNum = this->GetThreadNumber(indexZ);
337
338 // get the active list for that thread
339 return m_Data[ThreadNum].m_Layers[0];
340 }
341
342#ifdef ITK_USE_CONCEPT_CHECKING
343 // Begin concept checking
344 itkConceptMacro(OutputEqualityComparableCheck, (Concept::EqualityComparable<PixelType>));
345 itkConceptMacro(DoubleConvertibleToOutputCheck, (Concept::Convertible<double, PixelType>));
346 itkConceptMacro(OutputOStreamWritableCheck, (Concept::OStreamWritable<PixelType>));
347 // End concept checking
348#endif
349
350protected:
353 void
354 PrintSelf(std::ostream & os, Indent indent) const override;
355
358
361 double m_ConstantGradientValue{ 1.0 };
362
365
368
372
376
380
384
388
393 typename OutputImageType::Pointer m_ShiftedImage{};
394
399 LayerListType m_Layers{};
400
405 StatusType m_NumberOfLayers{};
406
408 typename StatusImageType::Pointer m_StatusImage{};
409 typename OutputImageType::Pointer m_OutputImage{};
410
413 typename StatusImageType::Pointer m_StatusImageTemp{};
414 typename OutputImageType::Pointer m_OutputImageTemp{};
415
417 typename LayerNodeStorageType::Pointer m_LayerNodeStore{};
418
420 ValueType m_IsoSurfaceValue{};
421
425 // ValueType m_RMSChange;
426
429 void
430 GenerateData() override;
431
436 void
438
440 void
442 {}
443
446 void
447 Initialize() override;
448
453 void
455
457 void
459
463 void
464 ConstructLayer(const StatusType & from, const StatusType & to);
465
467 void
469 const StatusType & ChangeToStatus,
470 const StatusType & SearchForStatus,
471 ThreadIdType ThreadId);
472
477 void
479
487 void
489 const StatusType & to,
490 const StatusType & promote,
491 unsigned int InOrOut);
492
497 virtual void
499
503 void
505
506 void
507 ThreadedInitializeData(ThreadIdType ThreadId, const ThreadRegionType & ThreadRegion);
508
518 void
520
522 unsigned int
523 GetThreadNumber(unsigned int splitAxisValue);
524
526 void
528
531 void
533
538 void
540
545 inline virtual ValueType
546 ThreadedCalculateUpdateValue(const ThreadIdType itkNotUsed(ThreadId),
547 const IndexType itkNotUsed(index),
548 const TimeStepType & dt,
549 const ValueType & value,
550 const ValueType & change)
551 {
552 return (value + static_cast<ValueType>(dt) * change);
553 }
554
555 // This method can be overridden in derived classes.
556 // The pixel at 'index' is entering the active layer for thread 'ThreadId'.
557 // The output image at 'index' will have the value as given by the
558 // 'value' parameter.
559 virtual void
561 const ValueType & itkNotUsed(value),
562 ThreadIdType itkNotUsed(ThreadId));
563
565 void
566 ApplyUpdate(const TimeStepType &) override
567 {}
568
571 virtual void
573
577 {
578 return TimeStepType{};
579 }
580
583 virtual TimeStepType
585
592 void
594 LayerType * UpList,
595 LayerType * DownList,
596 ThreadIdType ThreadId);
597
600 void
602
604 void
606
609 void
611 LayerPointerType List,
612 unsigned int InOrOut,
613 unsigned int BufferLayerNumber);
614
617 void
619 unsigned int InOrOut,
620 unsigned int BufferLayerNumber);
621
629 void
630 ThreadedProcessFirstLayerStatusLists(unsigned int InputLayerNumber,
631 unsigned int OutputLayerNumber,
632 const StatusType & SearchForStatus,
633 unsigned int InOrOut,
634 unsigned int BufferLayerNumber,
635 ThreadIdType ThreadId);
636
642 void
643 ThreadedProcessStatusList(unsigned int InputLayerNumber,
644 unsigned int OutputLayerNumber,
645 const StatusType & ChangeToStatus,
646 const StatusType & SearchForStatus,
647 unsigned int InOrOut,
648 unsigned int BufferLayerNumber,
649 ThreadIdType ThreadId);
650
654 void
655 ThreadedProcessOutsideList(unsigned int InputLayerNumber,
656 const StatusType & ChangeToStatus,
657 unsigned int InOrOut,
658 unsigned int BufferLayerNumber,
659 ThreadIdType ThreadId);
660
662 void
664 const StatusType & to,
665 const StatusType & promote,
666 unsigned int InOrOut,
667 ThreadIdType ThreadId);
668
671 void
673
679 void
681
692 virtual void
694
697 void
699 void
703 void
705
706 void
707 SignalNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId);
708
709 void
710 WaitForNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId);
711
714 virtual void
716
718 std::vector<TimeStepType> m_TimeStepList{};
719 BooleanStdVectorType m_ValidTimeStepList{};
720 TimeStepType m_TimeStep{};
721
723 ThreadIdType m_NumOfWorkUnits{ 0 };
724
726 unsigned int m_SplitAxis{ 0 };
727
729 unsigned int m_ZSize{ 0 };
730
733 bool m_BoundaryChanged{ false };
734
736 unsigned int * m_Boundary{ nullptr };
737
739 int * m_GlobalZHistogram{ nullptr };
740
743 unsigned int * m_MapZToThreadNumber{ nullptr };
744
747 int * m_ZCumulativeFrequency{ nullptr };
748
751 {
755 unsigned int m_Count;
756
759
762
765
767 LayerPointerType DownList[2];
768
771 LayerPointerType ** m_InterNeighborNodeTransferBufferLayers[2];
772
776
779
784 int m_Semaphore[2];
785
786 std::mutex m_Lock[2];
787 std::condition_variable m_Condition[2];
788
792 };
793
794 itkPadStruct(ITK_CACHE_LINE_ALIGNMENT, ThreadDataUnaligned, ThreadDataPadded);
795 itkAlignedTypedef(ITK_CACHE_LINE_ALIGNMENT, ThreadDataPadded, ThreadData);
796
799 ThreadData * m_Data{ nullptr };
800
803 bool m_Stop{ false };
804
809 bool m_InterpolateSurfaceLocation{ true };
810
811private:
814 bool m_BoundsCheckingActive{ false };
815};
816} // end namespace itk
817
818#ifndef ITK_MANUAL_INSTANTIATION
819# include "itkParallelSparseFieldLevelSetImageFilter.hxx"
820#endif
821
822#endif
typename FiniteDifferenceFunctionType::TimeStepType TimeStepType
Base class for all process objects that output image data.
TOutputImage OutputImageType
Templated n-dimensional image class.
Definition: itkImage.h:89
Control indentation during Print() invocation.
Definition: itkIndent.h:50
A specialized memory management object for allocating and destroying contiguous blocks of objects.
A convenience class for storing indices which reference neighbor pixels within a neighborhood.
void Print(std::ostream &os, Indent indent) const
This class implements a finite difference partial differential equation solver for evolving surfaces ...
void ConstructLayer(const StatusType &from, const StatusType &to)
void CopyInsertList(ThreadIdType ThreadId, LayerPointerType FromListPtr, LayerPointerType ToListPtr)
void ThreadedAllocateData(ThreadIdType ThreadId)
void ClearInterNeighborNodeTransferBufferLayers(ThreadIdType ThreadId, unsigned int InOrOut, unsigned int BufferLayerNumber)
virtual void ThreadedApplyUpdate(const TimeStepType &dt, ThreadIdType ThreadId)
void ProcessStatusList(LayerType *InputList, const StatusType &ChangeToStatus, const StatusType &SearchForStatus, ThreadIdType ThreadId)
virtual ValueType ThreadedCalculateUpdateValue(const ThreadIdType, const IndexType, const TimeStepType &dt, const ValueType &value, const ValueType &change)
unsigned int GetThreadNumber(unsigned int splitAxisValue)
void ThreadedProcessFirstLayerStatusLists(unsigned int InputLayerNumber, unsigned int OutputLayerNumber, const StatusType &SearchForStatus, unsigned int InOrOut, unsigned int BufferLayerNumber, ThreadIdType ThreadId)
void ThreadedLoadBalance2(ThreadIdType ThreadId)
virtual TimeStepType ThreadedCalculateChange(ThreadIdType ThreadId)
void GetThreadRegionSplitUniformly(ThreadIdType ThreadId, ThreadRegionType &ThreadRegion)
itkAlignedTypedef(ITK_CACHE_LINE_ALIGNMENT, ThreadDataPadded, ThreadData)
void ThreadedInitializeData(ThreadIdType ThreadId, const ThreadRegionType &ThreadRegion)
void SignalNeighborsAndWait(ThreadIdType ThreadId)
void ThreadedPostProcessOutput(const ThreadRegionType &regionToProcess)
void ClearList(ThreadIdType ThreadId, LayerPointerType ListPtr)
void CopyInsertInterNeighborNodeTransferBufferLayers(ThreadIdType ThreadId, LayerPointerType List, unsigned int InOrOut, unsigned int BufferLayerNumber)
void ThreadedUpdateActiveLayerValues(const TimeStepType &dt, LayerType *UpList, LayerType *DownList, ThreadIdType ThreadId)
void ThreadedProcessOutsideList(unsigned int InputLayerNumber, const StatusType &ChangeToStatus, unsigned int InOrOut, unsigned int BufferLayerNumber, ThreadIdType ThreadId)
itkPadStruct(ITK_CACHE_LINE_ALIGNMENT, ThreadDataUnaligned, ThreadDataPadded)
void ThreadedPropagateLayerValues(const StatusType &from, const StatusType &to, const StatusType &promote, unsigned int InOrOut, ThreadIdType ThreadId)
void SignalNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId)
void PropagateLayerValues(const StatusType &from, const StatusType &to, const StatusType &promote, unsigned int InOrOut)
~ParallelSparseFieldLevelSetImageFilter() override=default
void PrintSelf(std::ostream &os, Indent indent) const override
virtual void ThreadedProcessPixelEnteringActiveLayer(const IndexType &, const ValueType &, ThreadIdType)
void GetThreadRegionSplitByBoundary(ThreadIdType ThreadId, ThreadRegionType &ThreadRegion)
void ThreadedLoadBalance1(ThreadIdType ThreadId)
virtual void ThreadedInitializeIteration(ThreadIdType ThreadId)
void WaitForNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId)
void ThreadedProcessStatusList(unsigned int InputLayerNumber, unsigned int OutputLayerNumber, const StatusType &ChangeToStatus, const StatusType &SearchForStatus, unsigned int InOrOut, unsigned int BufferLayerNumber, ThreadIdType ThreadId)
The base class for all process objects (source, filters, mappers) in the Insight data processing pipe...
A very simple linked list that is used to manage nodes in a layer of a sparse field level-set solver.
SmartPointer< Self > Pointer
#define itkConceptMacro(name, concept)
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
unsigned int ThreadIdType
Definition: itkIntTypes.h:102
std::vector< Boolean > BooleanStdVectorType
Represent a n-dimensional offset between two n-dimensional indexes of n-dimensional image.
Definition: itkOffset.h:67