ITK
4.1.0
Insight Segmentation and Registration Toolkit
|
00001 /*========================================================================= 00002 * 00003 * Copyright Insight Software Consortium 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0.txt 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 *=========================================================================*/ 00018 #ifndef __itkLabelGeometryImageFilter_h 00019 #define __itkLabelGeometryImageFilter_h 00020 00021 #include "itkImageToImageFilter.h" 00022 #include "itkNumericTraits.h" 00023 #include "itkArray.h" 00024 #include "itkSimpleDataObjectDecorator.h" 00025 #include "itksys/hash_map.hxx" 00026 #include "itkFastMutexLock.h" 00027 #include <vector> 00028 #include "vnl/algo/vnl_symmetric_eigensystem.h" 00029 #include "vnl/vnl_det.h" 00030 #include "vnl/vnl_math.h" 00031 #include "vcl_cmath.h" 00032 00033 namespace itk 00034 { 00078 template< class TLabelImage, class TIntensityImage = TLabelImage > 00079 class ITK_EXPORT LabelGeometryImageFilter: 00080 public ImageToImageFilter< TLabelImage, TIntensityImage > 00081 { 00082 public: 00084 typedef LabelGeometryImageFilter Self; 00085 typedef ImageToImageFilter< TLabelImage, TIntensityImage > Superclass; 00086 typedef SmartPointer< Self > Pointer; 00087 typedef SmartPointer< const Self > ConstPointer; 00088 00090 itkNewMacro(Self); 00091 00093 itkTypeMacro(LabelGeometryImageFilter, ImageToImageFilter); 00094 00096 typedef TIntensityImage IntensityImageType; 00097 typedef typename TIntensityImage::Pointer InputImagePointer; 00098 typedef typename TIntensityImage::RegionType RegionType; 00099 typedef typename TIntensityImage::SizeType SizeType; 00100 typedef typename TIntensityImage::IndexType IndexType; 00101 typedef typename TIntensityImage::PixelType PixelType; 00102 00104 typedef TLabelImage LabelImageType; 00105 typedef typename TLabelImage::Pointer LabelImagePointer; 00106 typedef typename TLabelImage::RegionType LabelRegionType; 00107 typedef typename TLabelImage::SizeType LabelSizeType; 00108 typedef typename TLabelImage::IndexType LabelIndexType; 00109 typedef typename TLabelImage::PixelType LabelPixelType; 00110 typedef typename TLabelImage::PointType LabelPointType; 00111 00113 itkStaticConstMacro(ImageDimension, unsigned int, 00114 TLabelImage::ImageDimension); 00115 00117 typedef typename NumericTraits< PixelType >::RealType RealType; 00118 00120 typedef typename DataObject::Pointer DataObjectPointer; 00121 00123 typedef SimpleDataObjectDecorator< RealType > RealObjectType; 00124 00126 typedef itk::FixedArray< typename LabelIndexType::IndexValueType, 00127 itkGetStaticConstMacro(ImageDimension) *2 > BoundingBoxType; 00128 typedef itk::FixedArray< float, 00129 itkGetStaticConstMacro(ImageDimension) *2 > BoundingBoxFloatType; 00131 00132 //typedef itk::FixedArray< 00133 // LabelPointType,vcl_pow(2.0,itkGetStaticConstMacro(ImageDimension))> 00134 // BoundingBoxVerticesType; 00135 typedef std::vector< LabelPointType > BoundingBoxVerticesType; 00136 00138 typedef itk::FixedArray< RealType, itkGetStaticConstMacro(ImageDimension) > AxesLengthType; 00139 00141 typedef itk::FixedArray< typename LabelIndexType::IndexValueType, 00142 itkGetStaticConstMacro(ImageDimension) > IndexArrayType; 00143 00145 typedef std::vector< LabelPixelType > LabelsType; 00146 00148 typedef std::vector< LabelIndexType > LabelIndicesType; 00149 00151 typedef std::vector< double > VectorType; 00152 00154 typedef vnl_matrix< double > MatrixType; 00155 00160 class LabelGeometry 00161 { 00162 public: 00163 // default constructor 00164 LabelGeometry() 00165 { 00166 // initialized to the default values 00167 this->m_Label = 0; 00168 this->m_Sum = NumericTraits< RealType >::Zero; 00169 00170 const unsigned int imageDimension = itkGetStaticConstMacro(ImageDimension); 00171 00172 //m_BoundingBox.resize(imageDimension*2); 00173 for ( unsigned int i = 0; i < imageDimension * 2; i += 2 ) 00174 { 00175 m_BoundingBox[i] = NumericTraits< typename IndexType::IndexValueType >::max(); 00176 m_BoundingBox[i + 1] = NumericTraits< typename IndexType::IndexValueType >::NonpositiveMin(); 00177 } 00178 00179 m_BoundingBoxVolume = 0; 00180 m_BoundingBoxSize.Fill(0); 00181 m_PixelIndices.clear(); 00182 m_Centroid.Fill(0); 00183 m_WeightedCentroid.Fill(0); 00184 m_ZeroOrderMoment = 0; 00185 m_FirstOrderRawMoments.Fill(0); 00186 m_FirstOrderWeightedRawMoments.Fill(0); 00187 m_Eigenvalues.resize(ImageDimension); 00188 m_Eigenvalues.clear(); 00189 m_Eigenvectors.set_size(ImageDimension, ImageDimension); 00190 m_Eigenvectors.fill(0); 00191 m_AxesLength.Fill(0); 00192 m_Eccentricity = 1; 00193 m_Elongation = 1; 00194 m_Orientation = 0; 00195 LabelPointType emptyPoint; 00196 emptyPoint.Fill(0); 00197 unsigned int numberOfVertices = (unsigned int)vcl_pow( (double)2, (int)ImageDimension ); 00198 m_OrientedBoundingBoxVertices.resize(numberOfVertices, emptyPoint); 00199 m_OrientedBoundingBoxVolume = 0; 00200 m_OrientedBoundingBoxSize.Fill(0); 00201 m_OrientedLabelImage = LabelImageType::New(); 00202 m_OrientedIntensityImage = IntensityImageType::New(); 00203 m_OrientedBoundingBoxOrigin.Fill(0); 00204 m_RotationMatrix.set_size(ImageDimension, ImageDimension); 00205 m_RotationMatrix.fill(0.0); 00206 00207 m_SecondOrderRawMoments.set_size(ImageDimension, ImageDimension); 00208 m_SecondOrderCentralMoments.set_size(ImageDimension, ImageDimension); 00209 for ( unsigned int i = 0; i < ImageDimension; i++ ) 00210 { 00211 for ( unsigned int j = 0; j < ImageDimension; j++ ) 00212 { 00213 m_SecondOrderRawMoments(i, j) = 0; 00214 m_SecondOrderCentralMoments(i, j) = 0; 00215 } 00216 } 00217 } 00218 00219 LabelPixelType m_Label; 00220 RealType m_Sum; 00221 LabelPointType m_Centroid; 00222 LabelPointType m_WeightedCentroid; 00223 SizeValueType m_ZeroOrderMoment; 00224 IndexArrayType m_FirstOrderRawMoments; 00225 IndexArrayType m_FirstOrderWeightedRawMoments; 00226 SizeValueType m_FirstOrderRawCrossMoment; 00227 RealType m_FirstOrderCentralCrossMoment; 00228 MatrixType m_SecondOrderRawMoments; 00229 MatrixType m_SecondOrderCentralMoments; 00230 VectorType m_Eigenvalues; 00231 MatrixType m_Eigenvectors; 00232 FixedArray< float, itkGetStaticConstMacro(ImageDimension) > m_AxesLength; 00233 RealType m_Eccentricity; 00234 RealType m_Elongation; 00235 RealType m_Orientation; 00236 BoundingBoxType m_BoundingBox; 00237 LabelSizeType m_BoundingBoxSize; 00238 RealType m_BoundingBoxVolume; 00239 LabelIndicesType m_PixelIndices; 00240 BoundingBoxVerticesType m_OrientedBoundingBoxVertices; 00241 RealType m_OrientedBoundingBoxVolume; 00242 LabelPointType m_OrientedBoundingBoxSize; 00243 typename LabelImageType::Pointer m_OrientedLabelImage; 00244 typename IntensityImageType::Pointer m_OrientedIntensityImage; 00245 MatrixType m_RotationMatrix; 00246 LabelPointType m_OrientedBoundingBoxOrigin; 00247 }; 00248 00250 // Map from the label to the class storing all of the geometry information. 00251 typedef itksys::hash_map< LabelPixelType, LabelGeometry > MapType; 00252 typedef typename itksys::hash_map< LabelPixelType, LabelGeometry >::iterator MapIterator; 00253 typedef typename itksys::hash_map< LabelPixelType, LabelGeometry >::const_iterator MapConstIterator; 00254 00255 // Macros for enabling the calculation of additional features. 00256 itkGetMacro(CalculatePixelIndices, bool); 00257 itkBooleanMacro(CalculatePixelIndices); 00258 void SetCalculatePixelIndices(const bool value) 00259 { 00260 // CalculateOrientedBoundingBox, CalculateOrientedLabelImage, and 00261 // CalculateOrientedIntensityImage all need CalculatePixelIndices to be 00262 // turned 00263 // on if they are turned on. So, CalculatePixelIndices cannot be 00264 // turned off if any of these flags are turned on. 00265 if ( value == false ) 00266 { 00267 if ( ( this->m_CalculateOrientedBoundingBox == true ) 00268 || ( this->m_CalculateOrientedLabelRegions == true ) 00269 || ( this->m_CalculateOrientedIntensityRegions == true ) ) 00270 { 00271 // We cannot change the value, so return. 00272 return; 00273 } 00274 } 00275 00276 if ( this->m_CalculatePixelIndices != value ) 00277 { 00278 this->m_CalculatePixelIndices = value; 00279 this->Modified(); 00280 } 00281 } 00282 00283 itkGetMacro(CalculateOrientedBoundingBox, bool); 00284 itkBooleanMacro(CalculateOrientedBoundingBox); 00285 void SetCalculateOrientedBoundingBox(const bool value) 00286 { 00287 if ( this->m_CalculateOrientedBoundingBox != value ) 00288 { 00289 this->m_CalculateOrientedBoundingBox = value; 00290 this->Modified(); 00291 } 00292 00293 // CalculateOrientedBoundingBox needs 00294 // CalculatePixelIndices to be turned on. 00295 if ( value == true ) 00296 { 00297 this->SetCalculatePixelIndices(true); 00298 } 00299 } 00300 00301 itkGetMacro(CalculateOrientedLabelRegions, bool); 00302 itkBooleanMacro(CalculateOrientedLabelRegions); 00303 void SetCalculateOrientedLabelRegions(const bool value) 00304 { 00305 if ( this->m_CalculateOrientedLabelRegions != value ) 00306 { 00307 this->m_CalculateOrientedLabelRegions = value; 00308 this->Modified(); 00309 00310 // CalculateOrientedLabelImage needs 00311 // CalculateOrientedBoundingBox to be turned on. 00312 if ( value == true ) 00313 { 00314 SetCalculateOrientedBoundingBox(true); 00315 } 00316 } 00317 } 00318 00319 itkGetMacro(CalculateOrientedIntensityRegions, bool); 00320 itkBooleanMacro(CalculateOrientedIntensityRegions); 00321 void SetCalculateOrientedIntensityRegions(const bool value) 00322 { 00323 if ( this->m_CalculateOrientedIntensityRegions != value ) 00324 { 00325 this->m_CalculateOrientedIntensityRegions = value; 00326 this->Modified(); 00327 00328 // CalculateOrientedIntensityImage needs 00329 // CalculateOrientedBoundingBox to be turned on. 00330 if ( value == true ) 00331 { 00332 this->SetCalculateOrientedBoundingBox(true); 00333 } 00334 } 00335 } 00336 00338 void SetIntensityInput(const TIntensityImage *input) 00339 { 00340 // Process object is not const-correct so the const casting is required. 00341 this->SetNthInput( 1, const_cast< TIntensityImage * >( input ) ); 00342 } 00343 00345 const TIntensityImage * GetIntensityInput() const 00346 { 00347 return static_cast< TIntensityImage * >( const_cast< DataObject * >( this->ProcessObject::GetInput(1) ) ); 00348 } 00349 00352 bool HasLabel(LabelPixelType label) const 00353 { 00354 return m_LabelGeometryMapper.find(label) != m_LabelGeometryMapper.end(); 00355 } 00356 00358 SizeValueType GetNumberOfObjects() const 00359 { 00360 return m_LabelGeometryMapper.size(); 00361 } 00362 00363 SizeValueType GetNumberOfLabels() const 00364 { 00365 return this->GetNumberOfObjects(); 00366 } 00367 00369 std::vector< LabelPixelType > GetLabels() const 00370 { 00371 return m_AllLabels; 00372 } 00373 00375 LabelIndicesType GetPixelIndices(LabelPixelType label) const; 00376 00379 SizeValueType GetVolume(LabelPixelType label) const; 00380 00382 //std::vector< SizeValueType > GetAllCounts() const; 00383 00385 RealType GetIntegratedIntensity(LabelPixelType label) const; 00386 00388 LabelPointType GetCentroid(LabelPixelType label) const; 00389 00391 LabelPointType GetWeightedCentroid(LabelPixelType label) const; 00392 00394 VectorType GetEigenvalues(LabelPixelType label) const; 00395 00397 MatrixType GetEigenvectors(LabelPixelType label) const; 00398 00400 AxesLengthType GetAxesLength(LabelPixelType label) const; 00401 00404 RealType GetMinorAxisLength(LabelPixelType label) const; 00405 00408 RealType GetMajorAxisLength(LabelPixelType label) const; 00409 00411 RealType GetEccentricity(LabelPixelType label) const; 00412 00415 RealType GetElongation(LabelPixelType label) const; 00416 00418 RealType GetOrientation(LabelPixelType label) const; 00419 00423 BoundingBoxType GetBoundingBox(LabelPixelType label) const; 00424 00426 RealType GetBoundingBoxVolume(LabelPixelType label) const; 00427 00429 LabelSizeType GetBoundingBoxSize(LabelPixelType label) const; 00430 00437 BoundingBoxVerticesType GetOrientedBoundingBoxVertices(LabelPixelType label) const; 00438 00440 RealType GetOrientedBoundingBoxVolume(LabelPixelType label) const; 00441 00443 LabelPointType GetOrientedBoundingBoxSize(LabelPixelType label) const; 00444 00446 LabelPointType GetOrientedBoundingBoxOrigin(LabelPixelType label) const; 00447 00450 MatrixType GetRotationMatrix(LabelPixelType label) const; 00451 00453 RegionType GetRegion(LabelPixelType label) const; 00454 00456 TLabelImage * GetOrientedLabelImage(LabelPixelType label) const; 00457 00460 TIntensityImage * GetOrientedIntensityImage(LabelPixelType label) const; 00461 00462 #ifdef ITK_USE_CONCEPT_CHECKING 00463 00464 itkConceptMacro( InputHasNumericTraitsCheck, 00465 ( Concept::HasNumericTraits< PixelType > ) ); 00466 00468 #endif 00469 protected: 00470 LabelGeometryImageFilter(); 00471 ~LabelGeometryImageFilter(){} 00472 void PrintSelf(std::ostream & os, Indent indent) const; 00474 00475 void GenerateData(); 00476 00477 private: 00478 LabelGeometryImageFilter(const Self &); //purposely not implemented 00479 void operator=(const Self &); //purposely not implemented 00480 00481 bool CalculateOrientedBoundingBoxVertices(vnl_symmetric_eigensystem< double > eig, LabelGeometry & m_LabelGeometry); 00482 00483 bool m_CalculatePixelIndices; 00484 bool m_CalculateOrientedBoundingBox; 00485 bool m_CalculateOrientedLabelRegions; 00486 bool m_CalculateOrientedIntensityRegions; 00487 00488 MapType m_LabelGeometryMapper; 00489 LabelGeometry m_LabelGeometry; 00490 LabelsType m_AllLabels; 00491 00492 SimpleFastMutexLock m_Mutex; 00493 }; // end of class 00494 00495 template< class TLabelImage, class TIntensityImage > 00496 typename LabelGeometryImageFilter< TLabelImage, TIntensityImage >::MatrixType CalculateRotationMatrix( 00497 vnl_symmetric_eigensystem< double > eig); 00498 00499 template< class TLabelImage, class TIntensityImage, class TGenericImage > 00500 bool CalculateOrientedImage( 00501 LabelGeometryImageFilter< TLabelImage, TIntensityImage > *filter, 00502 vnl_symmetric_eigensystem< double > eig, 00503 typename LabelGeometryImageFilter< TLabelImage, TIntensityImage >::LabelGeometry & labelGeometry, 00504 bool useLabelImage = true); 00505 } // end namespace itk 00506 00507 #ifndef ITK_MANUAL_INSTANTIATION 00508 #include "itkLabelGeometryImageFilter.hxx" 00509 #endif 00510 00511 #endif 00512