Orfeo Toolbox  3.16
itkBloxBoundaryPointToCoreAtomImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkBloxBoundaryPointToCoreAtomImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2005-01-14 05:17:41 $
7  Version: $Revision: 1.16 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkBloxBoundaryPointToCoreAtomImageFilter_txx
18 #define __itkBloxBoundaryPointToCoreAtomImageFilter_txx
19 
24 
25 namespace itk
26 {
27 
28 template< unsigned int dim >
31 {
32  itkDebugMacro(<< "BloxBoundaryPointToCoreAtomImageFilter::BloxBoundaryPointToCoreAtomImageFilter() called");
33 
34  m_DistanceMin = 8;
35  m_DistanceMax = 12;
36  m_Epsilon = 0;
37  m_Polarity = 0;
38  m_InverseNumberOfBoundaryPoints = 0;
39  m_BoundaryPointsPerUpdate = 0;
40  m_BoundaryPointsBeforeUpdate = 0;
41  m_CurrentBoundaryPoint = 0;
42 }
43 
44 template< unsigned int dim >
45 void
48 {
49  itkDebugMacro(<< "BloxBoundaryPointToCoreAtomImageFilter::GenerateInputRequestedRegion() called");
50 
51  Superclass::GenerateInputRequestedRegion();
52 }
53 
54 
55 template< unsigned int dim >
56 void
59 {
60  itkDebugMacro(<< "BloxBoundaryPointToCoreAtomImageFilter::GenerateData() called");
61 
62  // Get the input and output pointers
63  m_InputPtr = this->GetInput(0);
64  m_OutputPtr = this->GetOutput(0);
65 
66  // Allocate the output
67  m_OutputPtr->SetBufferedRegion( m_OutputPtr->GetRequestedRegion() );
68  m_OutputPtr->Allocate();
69 
70  // To avoid appending data, empty the output image
71  m_OutputPtr->EmptyImage();
72 
73  //---- Set up the progress update ----
74 
75  float numBoundaryPoints = m_InputPtr->GetNumBoundaryPoints();
76  float numUpdates = 100.0;
77 
78  // Make sure we have at least one pixel.
79  if(numBoundaryPoints < 1)
80  {
81  numBoundaryPoints = 1;
82  }
83 
84  // We cannot update more times than there are BoundaryPoints.
85  if(numUpdates > numBoundaryPoints)
86  {
87  numUpdates = numBoundaryPoints;
88  }
89 
90  // Calculate the interval for updates.
91  m_BoundaryPointsPerUpdate = static_cast<unsigned long>(numBoundaryPoints/numUpdates);
92  m_InverseNumberOfBoundaryPoints = 1.0 / numBoundaryPoints;
93 
94  // Set the progress to 0. The filter is just starting.
95  this->UpdateProgress(0);
96 
97  m_BoundaryPointsBeforeUpdate = m_BoundaryPointsPerUpdate;
98 
99  m_CurrentBoundaryPoint = 0;
100 
101  this->FindCoreAtoms();
102 }
103 
104 template< unsigned int dim >
105 void
108 {
109  // Create an iterator to walk the source image
110  typedef ImageRegionConstIterator<TInputImage> ImageIteratorType;
111 
112  ImageIteratorType imageIt ( m_InputPtr,
113  m_InputPtr->GetRequestedRegion() );
114 
115  // Iterate through the entire image (all pixels) and look for core atoms
116  for ( imageIt.GoToBegin(); !imageIt.IsAtEnd(); ++imageIt)
117  {
118  // The iterator for accessing linked list info
120 
121  // Walk through all of the elements at the pixel
122  for (bpiterator = imageIt.Value().begin(); bpiterator != imageIt.Value().end(); ++bpiterator)
123  {
124  this->FindCoreAtomsAtBoundaryPoint( *bpiterator );
125 
126  if(--m_BoundaryPointsBeforeUpdate == 0)
127  {
128  m_BoundaryPointsBeforeUpdate = m_BoundaryPointsPerUpdate;
129  m_CurrentBoundaryPoint += m_BoundaryPointsPerUpdate;
130  this->UpdateProgress(m_CurrentBoundaryPoint * m_InverseNumberOfBoundaryPoints);
131  }
132  }
133  }
134 
135  // Compute mean core atom diameter
137  itk::ImageRegionIterator<TOutputImage>(m_OutputPtr, m_OutputPtr->GetRequestedRegion() );
138 
139  for(bloxIt.GoToBegin(); !bloxIt.IsAtEnd(); ++bloxIt)
140  {
141  ( &bloxIt.Value() )->CalcMeanCoreAtomDiameter();
142  }
143 }
144 
145 template< unsigned int dim >
146 void
149 {
150 
151  typedef BloxBoundaryPointItem<NDimensions> BPItemType;
152 
153  // When looking for core atoms at a boundary point, we want to examine
154  // all of the boundary points within blox that are part of a conical
155  // region extending out in the direction of the gradient of the boundary
156  // point.
157 
158  //---------Create and initialize a conic shell spatial function-----------
160  typedef typename FunctionType::GradientType FunctionGradientType;
161 
162  typename FunctionType::Pointer spatialFunc = FunctionType::New();
163 
164  // Set the properties of the conic shell
165  spatialFunc->SetDistanceMin(m_DistanceMin);
166  spatialFunc->SetDistanceMax(m_DistanceMax);
167  spatialFunc->SetEpsilon(m_Epsilon);
168  spatialFunc->SetPolarity(m_Polarity);
169 
170  // Set the origin of the conic shell to the current boundary point location
171  PositionType spatialFunctionOrigin = pBPOne->GetPhysicalPosition();
172  spatialFunc->SetOrigin(spatialFunctionOrigin);
173 
174  // Covert the origin position to a vector
175  //VectorType spatialFunctionOriginVector = spatialFunctionOrigin.GetVectorFromOrigin();
176 
177  VectorType spatialFunctionOriginVector;
178  spatialFunctionOriginVector.SetVnlVector( spatialFunctionOrigin.GetVnlVector() );
179 
180  // Set the gradient of the conic shell to the current boundary point gradient
181  FunctionGradientType spatialFunctionGradient = pBPOne->GetGradient();
182  spatialFunc->SetOriginGradient(spatialFunctionGradient);
183 
184  // Create a seed position for the spatial function iterator we'll use shortly
185  typename TInputImage::IndexType seedIndex;
186 
187  // Normalize the origin gradient
188  VectorType seedVector;
189  seedVector.SetVnlVector(spatialFunctionGradient.GetVnlVector());
190  seedVector = seedVector / seedVector.GetNorm();
191 
192  // If the polarity is 1, the seed position is in the direction
193  // opposite the gradient
194  if(m_Polarity == 1)
195  seedVector = seedVector * -1;
196 
197  // A "safe" seed position is the closest point in the conical region
198  // along the axis of the cone
199  PositionType seedPos = spatialFunctionOrigin + (seedVector * m_DistanceMin);
200 
201  // If the seed position is inside the image, go ahead and process it
202  if( m_InputPtr->TransformPhysicalPointToIndex(seedPos, seedIndex) )
203  {
204  // Create and initialize a spatial function iterator
206  ConicItType sfi = ConicItType(m_InputPtr, spatialFunc, seedIndex);
207  sfi.SetIntersectInclusionStrategy();
208 
209  // Walk the spatial function
210  for( sfi.GoToBegin(); !( sfi.IsAtEnd() ); ++sfi)
211  {
212  // The iterator for accessing linked list info
214 
215  // Walk through all of the elements at the pixel
216  for (bpiterator = sfi.Get().begin(); bpiterator != sfi.Get().end(); ++bpiterator)
217  {
218  // Get the pointer of the blox
219  BPItemType* pBPTwo = *bpiterator;
220 
221  // Get the physical positions of the two boundary points
222  PositionType P1 = pBPOne->GetPhysicalPosition();
223  PositionType P2 = pBPTwo->GetPhysicalPosition();
224 
225  // Form the two vectors between them
226  VectorType C12 = P2 - P1;
227 
228  // If we don't meet distance criteria, move on
229  if(!( (C12.GetNorm() > m_DistanceMin) && (C12.GetNorm() < m_DistanceMax) ) )
230  continue;
231 
232  VectorType C21 = P1 - P2;
233 
234  C12 = C12 / C12.GetNorm();
235  C21 = C21 / C21.GetNorm();
236 
237  // Get the gradients of the two boundary points
238  GradientType G1 = pBPOne->GetGradient();
239  GradientType G2 = pBPTwo->GetGradient();
240 
241  G1 = G1 / G1.GetNorm();
242  G2 = G2 / G2.GetNorm();
243 
244  // Calculate face-to-faceness
245  double faceToFaceness = dot_product(G1.GetVnlVector(), C12.GetVnlVector() ) *
246  dot_product(G2.GetVnlVector(), C21.GetVnlVector() );
247 
248  // If face-to-faceness meets threshold criteria
249  if( faceToFaceness > (1.0 - m_Epsilon) )
250  {
251  // Figure out the center of the core atom
252  PositionType coreAtomCenter = P1 + (P2 - P1) / 2;
253 
254  // Figure out the diameter of the core atom
255  double coreAtomDiameter = (P2-P1).GetNorm();
256 
257  // Create a new core atom
259 
260  // Set its boundary points, center, and diameter
261  pCoreAtom->SetBoundaryPointA(pBPOne);
262  pCoreAtom->SetBoundaryPointB(pBPTwo);
263  pCoreAtom->SetCenterPosition(coreAtomCenter);
264  pCoreAtom->SetDiameter(coreAtomDiameter);
265 
266  // Figure out the data space coordinates of the center
267  IndexType coreAtomPos;
268 
269  m_OutputPtr->TransformPhysicalPointToIndex(coreAtomCenter, coreAtomPos);
270 
271  // Store the new core atom in the correct spot
272  m_OutputPtr->GetPixel(coreAtomPos).push_back(pCoreAtom);
273 
274  } // end if face-to-faceness meets criteria
275  } // end iterate through boundary points in pixel
276  } // end iterate through the conic shell
277  } // end if the seed position for the conic shell is in the image
278 }
279 
280 template< unsigned int dim >
281 void
283 ::PrintSelf(std::ostream& os, Indent indent) const
284 {
285  Superclass::PrintSelf(os,indent);
286 
287  os << indent << "Minimum core atom search distance: " << m_DistanceMin << std::endl;
288  os << indent << "Maximum core atom search distance: " << m_DistanceMax << std::endl;
289  os << indent << "Core atom search epsilon: " << m_Epsilon << std::endl;
290  os << indent << "Core atom search polarity: " << m_Polarity << std::endl;
291 
292  os << indent << "Inverse number of boundary points: " << m_InverseNumberOfBoundaryPoints << std::endl;
293  os << indent << "Current boundary point: " << m_CurrentBoundaryPoint << std::endl;
294  os << indent << "Boundary points per update: " << m_BoundaryPointsPerUpdate << std::endl;
295  os << indent << "Boundary points before update: " << m_BoundaryPointsBeforeUpdate << std::endl;
296 }
297 
298 } // end namespace
299 
300 #endif

Generated at Sat May 25 2013 23:31:07 for Orfeo Toolbox with doxygen 1.8.3.1