00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkShapeLabelObject_h
00018 #define __itkShapeLabelObject_h
00019
00020 #include "itkLabelObject.h"
00021 #include "itkLabelMap.h"
00022 #include "itkAffineTransform.h"
00023 #include "itkMatrix.h"
00024
00025 namespace itk
00026 {
00027
00041 template < class TLabel, unsigned int VImageDimension >
00042 class ITK_EXPORT ShapeLabelObject : public LabelObject< TLabel, VImageDimension >
00043 {
00044 public:
00046 typedef ShapeLabelObject Self;
00047 typedef LabelObject< TLabel, VImageDimension > Superclass;
00048 typedef typename Superclass::LabelObjectType LabelObjectType;
00049 typedef SmartPointer<Self> Pointer;
00050 typedef SmartPointer<const Self> ConstPointer;
00051 typedef WeakPointer<const Self> ConstWeakPointer;
00052
00054 itkNewMacro(Self);
00055
00057 itkTypeMacro(ShapeLabelObject, LabelObject);
00058
00059 typedef LabelMap< Self > LabelMapType;
00060
00061 itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension);
00062
00063 typedef typename Superclass::IndexType IndexType;
00064
00065 typedef TLabel LabelType;
00066
00067 typedef typename Superclass::LineType LineType;
00068
00069 typedef typename Superclass::LengthType LengthType;
00070
00071 typedef typename Superclass::LineContainerType LineContainerType;
00072
00073 typedef typename Superclass::AttributeType AttributeType;
00074 itkStaticConstMacro(SIZE, AttributeType, 100);
00075 itkStaticConstMacro(PHYSICAL_SIZE, AttributeType, 101);
00076 itkStaticConstMacro(REGION_ELONGATION, AttributeType, 102);
00077 itkStaticConstMacro(SIZE_REGION_RATIO, AttributeType, 103);
00078 itkStaticConstMacro(CENTROID, AttributeType, 104);
00079 itkStaticConstMacro(REGION, AttributeType, 105);
00080 itkStaticConstMacro(SIZE_ON_BORDER, AttributeType, 106);
00081 itkStaticConstMacro(PHYSICAL_SIZE_ON_BORDER, AttributeType, 107);
00082 itkStaticConstMacro(FERET_DIAMETER, AttributeType, 108);
00083 itkStaticConstMacro(BINARY_PRINCIPAL_MOMENTS, AttributeType, 109);
00084 itkStaticConstMacro(BINARY_PRINCIPAL_AXES, AttributeType, 110);
00085 itkStaticConstMacro(BINARY_ELONGATION, AttributeType, 111);
00086 itkStaticConstMacro(PERIMETER, AttributeType, 112);
00087 itkStaticConstMacro(ROUNDNESS, AttributeType, 113);
00088 itkStaticConstMacro(EQUIVALENT_RADIUS, AttributeType, 114);
00089 itkStaticConstMacro(EQUIVALENT_PERIMETER, AttributeType, 115);
00090 itkStaticConstMacro(EQUIVALENT_ELLIPSOID_RADIUS, AttributeType, 116);
00091 itkStaticConstMacro(BINARY_FLATNESS, AttributeType, 117);
00092
00093 static AttributeType GetAttributeFromName( const std::string & s )
00094 {
00095 if( s == "Size" )
00096 {
00097 return SIZE;
00098 }
00099 else if( s == "PhysicalSize" )
00100 {
00101 return PHYSICAL_SIZE;
00102 }
00103 else if( s == "RegionElongation" )
00104 {
00105 return REGION_ELONGATION;
00106 }
00107 else if( s == "SizeRegionRatio" )
00108 {
00109 return SIZE_REGION_RATIO;
00110 }
00111 else if( s == "Centroid" )
00112 {
00113 return CENTROID;
00114 }
00115 else if( s == "Region" )
00116 {
00117 return REGION;
00118 }
00119 else if( s == "SizeOnBorder" )
00120 {
00121 return SIZE_ON_BORDER;
00122 }
00123 else if( s == "PhysicalSizeOnBorder" )
00124 {
00125 return PHYSICAL_SIZE_ON_BORDER;
00126 }
00127 else if( s == "FeretDiameter" )
00128 {
00129 return FERET_DIAMETER;
00130 }
00131 else if( s == "BinaryPrincipalMoments" )
00132 {
00133 return BINARY_PRINCIPAL_MOMENTS;
00134 }
00135 else if( s == "BinaryPrincipalAxes" )
00136 {
00137 return BINARY_PRINCIPAL_AXES;
00138 }
00139 else if( s == "BinaryElongation" )
00140 {
00141 return BINARY_ELONGATION;
00142 }
00143 else if( s == "Perimeter" )
00144 {
00145 return PERIMETER;
00146 }
00147 else if( s == "Roundness" )
00148 {
00149 return ROUNDNESS;
00150 }
00151 else if( s == "EquivalentRadius" )
00152 {
00153 return EQUIVALENT_RADIUS;
00154 }
00155 else if( s == "EquivalentPerimeter" )
00156 {
00157 return EQUIVALENT_PERIMETER;
00158 }
00159 else if( s == "EquivalentEllipsoidSize" )
00160 {
00161 return EQUIVALENT_ELLIPSOID_RADIUS;
00162 }
00163 else if( s == "BinaryFlatness" )
00164 {
00165 return BINARY_FLATNESS;
00166 }
00167
00168 return Superclass::GetAttributeFromName( s );
00169 }
00170
00171 static std::string GetNameFromAttribute( const AttributeType & a )
00172 {
00173 switch( a )
00174 {
00175 case SIZE:
00176 return "Size";
00177 break;
00178 case PHYSICAL_SIZE:
00179 return "PhysicalSize";
00180 break;
00181 case REGION_ELONGATION:
00182 return "RegionElongation";
00183 break;
00184 case SIZE_REGION_RATIO:
00185 return "SizeRegionRatio";
00186 break;
00187 case CENTROID:
00188 return "Centroid";
00189 case REGION:
00190 return "Region";
00191 break;
00192 case SIZE_ON_BORDER:
00193 return "SizeOnBorder";
00194 break;
00195 case PHYSICAL_SIZE_ON_BORDER:
00196 return "PhysicalSizeOnBorder";
00197 break;
00198 case FERET_DIAMETER:
00199 return "FeretDiameter";
00200 break;
00201 case BINARY_PRINCIPAL_MOMENTS:
00202 return "BinaryPrincipalMoments";
00203 break;
00204 case BINARY_PRINCIPAL_AXES:
00205 return "BinaryPrincipalAxes";
00206 break;
00207 case BINARY_ELONGATION:
00208 return "BinaryElongation";
00209 break;
00210 case PERIMETER:
00211 return "Perimeter";
00212 break;
00213 case ROUNDNESS:
00214 return "Roundness";
00215 break;
00216 case EQUIVALENT_RADIUS:
00217 return "EquivalentRadius";
00218 break;
00219 case EQUIVALENT_PERIMETER:
00220 return "EquivalentPerimeter";
00221 break;
00222 case EQUIVALENT_ELLIPSOID_RADIUS:
00223 return "EquivalentEllipsoidSize";
00224 break;
00225 case BINARY_FLATNESS:
00226 return "BinaryFlatness";
00227 break;
00228 }
00229
00230 return Superclass::GetNameFromAttribute( a );
00231 }
00232
00233 typedef ImageRegion< VImageDimension > RegionType;
00234
00235 typedef Point<double, VImageDimension> CentroidType;
00236
00237 typedef Matrix< double, VImageDimension, VImageDimension > MatrixType;
00238
00239 typedef Vector< double, VImageDimension > VectorType;
00240
00241 const RegionType & GetRegion() const
00242 {
00243 return m_Region;
00244 }
00245
00246 void SetRegion( const RegionType & v )
00247 {
00248 m_Region = v;
00249 }
00250
00251 const double & GetPhysicalSize() const
00252 {
00253 return m_PhysicalSize;
00254 }
00255
00256 void SetPhysicalSize( const double & v )
00257 {
00258 m_PhysicalSize = v;
00259 }
00260
00261 const unsigned long & GetSize() const
00262 {
00263 return m_Size;
00264 }
00265
00266 void SetSize( const unsigned long & v )
00267 {
00268 m_Size = v;
00269 }
00270
00271 const CentroidType & GetCentroid() const
00272 {
00273 return m_Centroid;
00274 }
00275
00276 void SetCentroid( const CentroidType & centroid )
00277 {
00278 m_Centroid = centroid;
00279 }
00280
00281 const double & GetRegionElongation() const
00282 {
00283 return m_RegionElongation;
00284 }
00285
00286 void SetRegionElongation( const double & v )
00287 {
00288 m_RegionElongation = v;
00289 }
00290
00291 const double & GetSizeRegionRatio() const
00292 {
00293 return m_SizeRegionRatio;
00294 }
00295
00296 void SetSizeRegionRatio( const double & v )
00297 {
00298 m_SizeRegionRatio = v;
00299 }
00300
00301 const unsigned long & GetSizeOnBorder() const
00302 {
00303 return m_SizeOnBorder;
00304 }
00305
00306 void SetSizeOnBorder( const unsigned long & v )
00307 {
00308 m_SizeOnBorder = v;
00309 }
00310
00311 const double & GetPhysicalSizeOnBorder() const
00312 {
00313 return m_PhysicalSizeOnBorder;
00314 }
00315
00316 void SetPhysicalSizeOnBorder( const double & v )
00317 {
00318 m_PhysicalSizeOnBorder = v;
00319 }
00320
00321 const double & GetFeretDiameter() const
00322 {
00323 return m_FeretDiameter;
00324 }
00325
00326 void SetFeretDiameter( const double & v )
00327 {
00328 m_FeretDiameter = v;
00329 }
00330
00331 const VectorType & GetBinaryPrincipalMoments() const
00332 {
00333 return m_BinaryPrincipalMoments;
00334 }
00335
00336 void SetBinaryPrincipalMoments( const VectorType & v )
00337 {
00338 m_BinaryPrincipalMoments = v;
00339 }
00340
00341 const MatrixType & GetBinaryPrincipalAxes() const
00342 {
00343 return m_BinaryPrincipalAxes;
00344 }
00345
00346 void SetBinaryPrincipalAxes( const MatrixType & v )
00347 {
00348 m_BinaryPrincipalAxes = v;
00349 }
00350
00351 const double & GetBinaryElongation() const
00352 {
00353 return m_BinaryElongation;
00354 }
00355
00356 void SetBinaryElongation( const double & v )
00357 {
00358 m_BinaryElongation = v;
00359 }
00360
00361 const double & GetPerimeter() const
00362 {
00363 return m_Perimeter;
00364 }
00365
00366 void SetPerimeter( const double & v )
00367 {
00368 m_Perimeter = v;
00369 }
00370
00371 const double & GetRoundness() const
00372 {
00373 return m_Roundness;
00374 }
00375
00376 void SetRoundness( const double & v )
00377 {
00378 m_Roundness = v;
00379 }
00380
00381 const double & GetEquivalentRadius() const
00382 {
00383 return m_EquivalentRadius;
00384 }
00385
00386 void SetEquivalentRadius( const double & v )
00387 {
00388 m_EquivalentRadius = v;
00389 }
00390
00391 const double & GetEquivalentPerimeter() const
00392 {
00393 return m_EquivalentPerimeter;
00394 }
00395
00396 void SetEquivalentPerimeter( const double & v )
00397 {
00398 m_EquivalentPerimeter = v;
00399 }
00400
00401 const VectorType & GetEquivalentEllipsoidSize() const
00402 {
00403 return m_EquivalentEllipsoidSize;
00404 }
00405
00406 void SetEquivalentEllipsoidSize( const VectorType & v )
00407 {
00408 m_EquivalentEllipsoidSize = v;
00409 }
00410
00411 const double & GetBinaryFlatness() const
00412 {
00413 return m_BinaryFlatness;
00414 }
00415
00416 void SetBinaryFlatness( const double & v )
00417 {
00418 m_BinaryFlatness = v;
00419 }
00420
00421
00422
00423
00425 typedef AffineTransform<double,VImageDimension> AffineTransformType;
00426 typedef typename AffineTransformType::Pointer AffineTransformPointer;
00427
00431 AffineTransformPointer GetBinaryPrincipalAxesToPhysicalAxesTransform() const
00432 {
00433 typename AffineTransformType::MatrixType matrix;
00434 typename AffineTransformType::OffsetType offset;
00435 for (unsigned int i = 0; i < VImageDimension; i++)
00436 {
00437 offset[i] = m_Centroid[i];
00438 for (unsigned int j = 0; j < VImageDimension; j++)
00439 {
00440 matrix[j][i] = m_BinaryPrincipalAxes[i][j];
00441 }
00442 }
00444
00445 AffineTransformPointer result = AffineTransformType::New();
00446
00447 result->SetMatrix(matrix);
00448 result->SetOffset(offset);
00449
00450 return result;
00451 }
00452
00457 AffineTransformPointer GetPhysicalAxesToBinaryPrincipalAxesTransform(void) const
00458 {
00459 typename AffineTransformType::MatrixType matrix;
00460 typename AffineTransformType::OffsetType offset;
00461 for (unsigned int i = 0; i < VImageDimension; i++)
00462 {
00463 offset[i] = m_Centroid[i];
00464 for (unsigned int j = 0; j < VImageDimension; j++)
00465 {
00466 matrix[j][i] = m_BinaryPrincipalAxes[i][j];
00467 }
00468 }
00470
00471 AffineTransformPointer result = AffineTransformType::New();
00472 result->SetMatrix(matrix);
00473 result->SetOffset(offset);
00474
00475 AffineTransformPointer inverse = AffineTransformType::New();
00476 result->GetInverse(inverse);
00477
00478 return inverse;
00479 }
00480
00481
00482 virtual void CopyAttributesFrom( const LabelObjectType * lo )
00483 {
00484 Superclass::CopyAttributesFrom( lo );
00485
00486
00487 const Self * src = dynamic_cast<const Self *>( lo );
00488 if( src == NULL )
00489 {
00490 return;
00491 }
00492 m_Region = src->m_Region;
00493 m_Size = src->m_Size;
00494 m_PhysicalSize = src->m_PhysicalSize;
00495 m_Centroid = src->m_Centroid;
00496 m_RegionElongation = src->m_RegionElongation;
00497 m_SizeRegionRatio = src->m_SizeRegionRatio;
00498 m_SizeOnBorder = src->m_SizeOnBorder;
00499 m_PhysicalSizeOnBorder = src->m_PhysicalSizeOnBorder;
00500 m_FeretDiameter = src->m_FeretDiameter;
00501 m_BinaryPrincipalMoments = src->m_BinaryPrincipalMoments;
00502 m_BinaryPrincipalAxes = src->m_BinaryPrincipalAxes;
00503 m_BinaryElongation = src->m_BinaryElongation;
00504 m_Perimeter = src->m_Perimeter;
00505 m_Roundness = src->m_Roundness;
00506 m_EquivalentRadius = src->m_EquivalentRadius;
00507 m_EquivalentPerimeter = src->m_EquivalentPerimeter;
00508 m_EquivalentEllipsoidSize = src->m_EquivalentEllipsoidSize;
00509 m_BinaryFlatness = src->m_BinaryFlatness;
00510 }
00511
00512 protected:
00513 ShapeLabelObject()
00514 {
00515 m_Size = 0;
00516 m_PhysicalSize = 0;
00517 m_Centroid.Fill(0);
00518 m_RegionElongation = 0;
00519 m_SizeRegionRatio = 0;
00520 m_SizeOnBorder = false;
00521 m_PhysicalSizeOnBorder = 0;
00522 m_FeretDiameter = false;
00523 m_BinaryPrincipalMoments.Fill(0);
00524 m_BinaryPrincipalAxes.Fill(0);
00525 m_BinaryElongation = 0;
00526 m_Perimeter = 0;
00527 m_Roundness = 0;
00528 m_EquivalentRadius = 0;
00529 m_EquivalentPerimeter = 0;
00530 m_EquivalentEllipsoidSize.Fill(0);
00531 m_BinaryFlatness = 0;
00532 }
00533
00534 void PrintSelf(std::ostream& os, Indent indent) const
00535 {
00536 Superclass::PrintSelf( os, indent );
00537
00538 os << indent << "Centroid: " << m_Centroid << std::endl;
00539 os << indent << "Region: ";
00540 m_Region.Print( os, indent );
00541 os << indent << "PhysicalSize: " << m_PhysicalSize << std::endl;
00542 os << indent << "Size: " << m_Size << std::endl;
00543 os << indent << "RegionElongation: " << m_RegionElongation << std::endl;
00544 os << indent << "SizeRegionRatio: " << m_SizeRegionRatio << std::endl;
00545 os << indent << "SizeOnBorder: " << m_SizeOnBorder << std::endl;
00546 os << indent << "PhysicalSizeOnBorder: " << m_PhysicalSizeOnBorder << std::endl;
00547 os << indent << "FeretDiameter: " << m_FeretDiameter << std::endl;
00548 os << indent << "BinaryPrincipalMoments: " << m_BinaryPrincipalMoments << std::endl;
00549 os << indent << "BinaryPrincipalAxes: " << std::endl << m_BinaryPrincipalAxes;
00550 os << indent << "BinaryElongation: " << m_BinaryElongation << std::endl;
00551 os << indent << "Perimeter: " << m_Perimeter << std::endl;
00552 os << indent << "Roundness: " << m_Roundness << std::endl;
00553 os << indent << "EquivalentRadius: " << m_EquivalentRadius << std::endl;
00554 os << indent << "EquivalentPerimeter: " << m_EquivalentPerimeter << std::endl;
00555 os << indent << "EquivalentEllipsoidSize: " << m_EquivalentEllipsoidSize << std::endl;
00556 os << indent << "BinaryFlatness: " << m_BinaryElongation << std::endl;
00557 }
00558
00559 private:
00560 ShapeLabelObject(const Self&);
00561 void operator=(const Self&);
00562
00563 RegionType m_Region;
00564 unsigned long m_Size;
00565 double m_PhysicalSize;
00566 CentroidType m_Centroid;
00567 double m_RegionElongation;
00568 double m_SizeRegionRatio;
00569 unsigned long m_SizeOnBorder;
00570 double m_PhysicalSizeOnBorder;
00571 double m_FeretDiameter;
00572 VectorType m_BinaryPrincipalMoments;
00573 MatrixType m_BinaryPrincipalAxes;
00574 double m_BinaryElongation;
00575 double m_Perimeter;
00576 double m_Roundness;
00577 double m_EquivalentRadius;
00578 double m_EquivalentPerimeter;
00579 VectorType m_EquivalentEllipsoidSize;
00580 double m_BinaryFlatness;
00581
00582 };
00583
00584 }
00585
00586 #endif
00587