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
19 #ifndef itkLevelSetDomainMapImageFilter_hxx
20 #define itkLevelSetDomainMapImageFilter_hxx
21
22 #include "itkLevelSetDomainMapImageFilter.h"
23
24 namespace itk
25 {
26 template < typename TInputImage, typename TOutputImage >
27 LevelSetDomainMapImageFilter< TInputImage, TOutputImage >
LevelSetDomainMapImageFilter()28 ::LevelSetDomainMapImageFilter()
29 {
30 this->Superclass::SetNumberOfRequiredInputs ( 1 );
31 this->Superclass::SetNumberOfRequiredOutputs ( 1 );
32 this->m_InputImage = nullptr;
33 this->m_OutputImage = nullptr;
34 }
35
36 template < typename TInputImage, typename TOutputImage >
37 const typename LevelSetDomainMapImageFilter< TInputImage, TOutputImage >::DomainMapType &
38 LevelSetDomainMapImageFilter< TInputImage, TOutputImage >
GetDomainMap() const39 ::GetDomainMap() const
40 {
41 return this->m_DomainMap;
42 }
43
44 template < typename TInputImage, typename TOutputImage >
45 typename LevelSetDomainMapImageFilter< TInputImage, TOutputImage >::InputImageRegionType
46 LevelSetDomainMapImageFilter< TInputImage, TOutputImage >
ComputeConsistentRegion(const InputImageRegionType & inputRegion) const47 ::ComputeConsistentRegion( const InputImageRegionType & inputRegion ) const
48 {
49 bool regionWasModified = false;
50
51 InputImageRegionType subRegion = inputRegion;
52
53 do
54 {
55 regionWasModified = false;
56
57 InputConstIteratorType iIt( this->m_InputImage, subRegion );
58 OutputConstIteratorType oIt( this->m_OutputImage, subRegion );
59
60 iIt.GoToBegin();
61 oIt.GoToBegin();
62
63 const InputImagePixelType firstCornerPixelValue = iIt.Get();
64 const InputImageIndexType & firstCornerIndex = iIt.GetIndex();
65
66 while( !iIt.IsAtEnd() )
67 {
68 const OutputImagePixelType segmentPixel = oIt.Get();
69 const InputImagePixelType nextPixel = iIt.Get();
70
71 if ( ( nextPixel != firstCornerPixelValue ) ||
72 ( segmentPixel != NumericTraits< OutputImagePixelType >::ZeroValue() ) )
73 {
74 const InputImageIndexType & stopIdx = iIt.GetIndex();
75 InputImageSizeType sizeOfRegion;
76 for( unsigned int i = 0; i < ImageDimension; i++ )
77 {
78 sizeOfRegion[i] = stopIdx[i] - firstCornerIndex[i] + 1;
79 }
80 subRegion.SetSize(sizeOfRegion);
81
82 regionWasModified = true;
83 break;
84 }
85
86 ++iIt;
87 ++oIt;
88 }
89 }
90 while( regionWasModified );
91
92 return subRegion;
93 }
94
95
96 template < typename TInputImage, typename TOutputImage >
97 void
98 LevelSetDomainMapImageFilter< TInputImage, TOutputImage >::
GenerateData()99 GenerateData()
100 {
101 // Clear any prior contents.
102 this->m_DomainMap.clear();
103
104 this->m_InputImage = this->GetInput();
105 const InputImageRegionType & region = this->m_InputImage->GetLargestPossibleRegion();
106 const InputImageSizeType size = region.GetSize();
107
108 this->m_OutputImage = this->GetOutput();
109 this->m_OutputImage->SetBufferedRegion( region );
110 this->m_OutputImage->Allocate();
111 this->m_OutputImage->FillBuffer( NumericTraits< OutputImagePixelType >::ZeroValue() );
112
113 InputImageIndexType end;
114
115 for( unsigned int i = 0; i < ImageDimension; i++ )
116 {
117 end[i] = size[i] - 1;
118 }
119
120 IdentifierType segmentId = NumericTraits<IdentifierType>::OneValue();
121
122 InputConstIteratorType iIt( this->m_InputImage, region );
123 OutputIndexIteratorType oIt( this->m_OutputImage, region );
124
125 iIt.GoToBegin();
126 oIt.GoToBegin();
127
128 while( !iIt.IsAtEnd() )
129 {
130 const InputImageIndexType & startIdx = iIt.GetIndex();
131 InputImageIndexType stopIdx = startIdx;
132 const InputImagePixelType & inputPixel = iIt.Get();
133 const OutputImagePixelType & outputPixel = oIt.Get();
134
135 // outputPixel is null when it has not been processed yet,
136 // or there is nothing to be processed
137 if ( ( !inputPixel.empty() ) && ( outputPixel == NumericTraits<OutputImagePixelType>::ZeroValue() ) )
138 {
139 InputImageRegionType subRegion;
140 InputImageSizeType sizeOfRegion;
141
142 for( unsigned int i = 0; i < ImageDimension; i++ )
143 {
144 bool sameOverlappingLevelSetIds = true;
145 stopIdx = startIdx;
146 while ( ( sameOverlappingLevelSetIds ) && ( stopIdx[i] <= end[i] ) )
147 {
148 const InputImagePixelType & nextPixel = this->m_InputImage->GetPixel( stopIdx );
149 const OutputImagePixelType & currentOutputPixel = this->m_OutputImage->GetPixel( stopIdx );
150
151 // Check if the input list pixels are different, or
152 // the output image already has been assigned to another region
153 if ( ( nextPixel != inputPixel ) ||
154 ( currentOutputPixel != NumericTraits< OutputImagePixelType >::ZeroValue() ) )
155 {
156 sameOverlappingLevelSetIds = false;
157 }
158 else
159 {
160 ++stopIdx[i];
161 }
162 }
163 sizeOfRegion[i] = stopIdx[i] - startIdx[i];
164 }
165
166 subRegion.SetSize( sizeOfRegion );
167 subRegion.SetIndex( startIdx );
168
169 // Compute the consistent subregion
170 subRegion = this->ComputeConsistentRegion( subRegion );
171
172 this->m_DomainMap[segmentId] = LevelSetDomain( subRegion, inputPixel );
173
174 OutputIndexIteratorType ooIt( this->m_OutputImage, subRegion );
175 ooIt.GoToBegin();
176
177 while( !ooIt.IsAtEnd() )
178 {
179 ooIt.Set( segmentId );
180 ++ooIt;
181 }
182 ++segmentId;
183 }
184 ++iIt;
185 ++oIt;
186 }
187 }
188
189 template < typename TInputImage, typename TOutputImage >
190 void
191 LevelSetDomainMapImageFilter< TInputImage, TOutputImage >::
PrintSelf(std::ostream & os,Indent indent) const192 PrintSelf ( std::ostream& os, Indent indent ) const
193 {
194 Superclass::PrintSelf ( os,indent );
195 os << indent << "DomainMap size: " << this->m_DomainMap.size() << std::endl;
196 }
197
198 } /* end namespace itk */
199
200 #endif
201