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 #ifndef itkMeasurementVectorTraits_h 19 #define itkMeasurementVectorTraits_h 20 21 #include "itkVariableLengthVector.h" 22 #include "vnl/vnl_vector_fixed.h" 23 #include "itkRGBPixel.h" 24 #include "itkMatrix.h" 25 #include "itkVariableSizeMatrix.h" 26 #include "itkNumericTraits.h" 27 #include "itkNumericTraitsStdVector.h" 28 #include "itkSize.h" 29 #include <vector> 30 31 namespace itk 32 { 33 namespace Statistics 34 { 35 /** \class MeasurementVectorTraits 36 * \brief 37 * \ingroup Statistics 38 * \ingroup ITKStatistics 39 */ 40 41 class MeasurementVectorTraits 42 { 43 public: 44 45 /** In the old framework, the FrequencyType is set to float. The problem is for 46 large histograms the total frequency can be more than 1e+7, than increasing 47 the frequency by one does not change the total frequency (because of lack of 48 precision). Using double type will also ultimately fall into the same problem. 49 Hence in the new statistics framework, InstanceIdentifier/FrequencyTypes are 50 set to the the largest possible integer on the machine */ 51 using InstanceIdentifier = IdentifierType; 52 53 /** Type defined for representing the frequency of measurement vectors */ 54 using AbsoluteFrequencyType = InstanceIdentifier; 55 using RelativeFrequencyType = NumericTraits< AbsoluteFrequencyType >::RealType; 56 using TotalAbsoluteFrequencyType = NumericTraits< AbsoluteFrequencyType >::AccumulateType; 57 using TotalRelativeFrequencyType = NumericTraits< RelativeFrequencyType >::AccumulateType; 58 59 using MeasurementVectorLength = unsigned int; 60 61 template< typename TVectorType > IsResizable(const TVectorType &)62 static bool IsResizable(const TVectorType &) 63 { 64 // Test whether the vector type is resizable or not 65 // 66 // If the default constructor creates a vector of 67 // length zero, we assume that it is resizable, 68 // otherwise that is a pretty useless measurement vector. 69 TVectorType m; 70 MeasurementVectorLength len = NumericTraits<TVectorType>::GetLength(m); 71 72 return ( len == 0 ); 73 } 74 75 template< typename TValue1, unsigned int VLength, typename TValue2, unsigned int VLength2 > 76 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &, 77 const FixedArray< TValue2, VLength2 > &, 78 const char *errMsg = "Length Mismatch") 79 { 80 if ( VLength != VLength2 ) 81 { 82 itkGenericExceptionMacro(<< errMsg); 83 } 84 return 0; 85 } 86 87 template< typename TValue1, unsigned int VLength, typename TValue2, unsigned int VLength2 > 88 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *, 89 const FixedArray< TValue2, VLength2 > *, 90 const char *errMsg = "Length Mismatch") 91 { 92 if ( VLength != VLength2 ) 93 { 94 itkGenericExceptionMacro(<< errMsg); 95 } 96 return 0; 97 } 98 99 template< typename TValue1, typename TValue2 > 100 static MeasurementVectorLength Assert(const Array< TValue1 > & a, 101 const Array< TValue2 > & b, const char *errMsg = "Length Mismatch") 102 { 103 if ( b.Size() != a.Size() ) 104 { 105 itkGenericExceptionMacro(<< errMsg); 106 } 107 return 0; 108 } 109 110 template< typename TValue1, typename TValue2 > 111 static MeasurementVectorLength Assert(const Array< TValue1 > *a, 112 const Array< TValue2 > *b, const char *errMsg = "Length Mismatch") 113 { 114 if ( b->Size() != a->Size() ) 115 { 116 itkGenericExceptionMacro(<< errMsg); 117 } 118 return 0; 119 } 120 121 template< typename TValue1, typename TValue2 > 122 static MeasurementVectorLength Assert(const VariableLengthVector< TValue1 > & a, 123 const VariableLengthVector< TValue2 > & b, 124 const char *errMsg = "Length Mismatch") 125 { 126 if ( b.Size() != a.Size() ) 127 { 128 itkGenericExceptionMacro(<< errMsg); 129 } 130 return 0; 131 } 132 133 template< typename TValue1, typename TValue2 > 134 static MeasurementVectorLength Assert(const VariableLengthVector< TValue1 > *a, 135 const VariableLengthVector< TValue2 > *b, 136 const char *errMsg = "Length Mismatch") 137 { 138 if ( b->Size() != a->Size() ) 139 { 140 itkGenericExceptionMacro(<< errMsg); 141 } 142 return 0; 143 } 144 145 template< typename TValue1, typename TValue2 > 146 static MeasurementVectorLength Assert(const std::vector< TValue1 > & a, 147 const std::vector< TValue2 > & b, const char *errMsg = "Length Mismatch") 148 { 149 if ( b.size() != a.size() ) 150 { 151 itkGenericExceptionMacro(<< errMsg); 152 } 153 return 0; 154 } 155 156 template< typename TValue1, typename TValue2 > 157 static MeasurementVectorLength Assert(const std::vector< TValue1 > *a, 158 const std::vector< TValue2 > *b, const char *errMsg = "Length Mismatch") 159 { 160 if ( b->size() != a->size() ) 161 { 162 itkGenericExceptionMacro(<< errMsg); 163 } 164 return 0; 165 } 166 167 template< typename TValue1, unsigned int VLength, typename TValue2 > 168 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &, 169 const Array< TValue2 > & b, const char *errMsg = "Length Mismatch") 170 { 171 if ( b.Size() == 0 ) 172 { 173 return VLength; 174 } 175 if ( b.Size() != 0 ) 176 { 177 if ( b.Size() != VLength ) 178 { 179 itkGenericExceptionMacro(<< errMsg); 180 } 181 } 182 return 0; 183 } 184 185 template< typename TValue1, unsigned int VLength, typename TValue2 > 186 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *, 187 const Array< TValue2 > *b, const char *errMsg = "Length Mismatch") 188 { 189 if ( b->Size() == 0 ) 190 { 191 return VLength; 192 } 193 else if ( b->Size() != VLength ) 194 { 195 itkGenericExceptionMacro(<< errMsg); 196 } 197 return 0; 198 } 199 200 template< typename TValue1, unsigned int VLength, typename TValue2 > 201 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &, 202 const VariableLengthVector< TValue2 > & b, 203 const char *errMsg = "Length Mismatch") 204 { 205 if ( b.Size() == 0 ) 206 { 207 return VLength; 208 } 209 if ( b.Size() != 0 ) 210 { 211 if ( b.Size() != VLength ) 212 { 213 itkGenericExceptionMacro(<< errMsg); 214 } 215 } 216 return 0; 217 } 218 219 template< typename TValue1, unsigned int VLength, typename TValue2 > 220 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *, 221 const VariableLengthVector< TValue2 > *b, 222 const char *errMsg = "Length Mismatch") 223 { 224 if ( b->Size() == 0 ) 225 { 226 return VLength; 227 } 228 else if ( b->Size() != VLength ) 229 { 230 itkGenericExceptionMacro(<< errMsg); 231 } 232 return 0; 233 } 234 235 template< typename TValue1, unsigned int VLength, typename TValue2 > 236 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &, 237 const std::vector< TValue2 > & b, const char *errMsg = "Length Mismatch") 238 { 239 if ( b.empty() ) 240 { 241 return VLength; 242 } 243 if ( !b.empty() ) 244 { 245 if ( b.size() != VLength ) 246 { 247 itkGenericExceptionMacro(<< errMsg); 248 } 249 } 250 return 0; 251 } 252 253 template< typename TValue1, unsigned int VLength, typename TValue2 > 254 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *, 255 const std::vector< TValue2 > *b, const char *errMsg = "Length Mismatch") 256 { 257 if ( b->size() == 0 ) 258 { 259 return VLength; 260 } 261 else if ( b->size() != VLength ) 262 { 263 itkGenericExceptionMacro(<< errMsg); 264 } 265 return 0; 266 } 267 268 template< typename TValue1, unsigned int VLength > 269 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &, 270 const MeasurementVectorLength l, const char *errMsg = "Length Mismatch") 271 { 272 if ( l == 0 ) 273 { 274 return VLength; 275 } 276 else if ( l != VLength ) 277 { 278 itkGenericExceptionMacro(<< errMsg); 279 } 280 return 0; 281 } 282 283 template< typename TValue1, unsigned int VLength > 284 static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *, 285 const MeasurementVectorLength l, const char *errMsg = "Length Mismatch") 286 { 287 if ( l == 0 ) 288 { 289 return VLength; 290 } 291 else if ( l != VLength ) 292 { 293 itkGenericExceptionMacro(<< errMsg); 294 } 295 return 0; 296 } 297 298 template< typename TValue > 299 static MeasurementVectorLength Assert(const Array< TValue > & a, 300 const MeasurementVectorLength l, const char *errMsg = "Length Mismatch") 301 { 302 if ( ( ( l != 0 ) && ( a.Size() != l ) ) || ( a.Size() == 0 ) ) 303 { 304 itkGenericExceptionMacro(<< errMsg); 305 } 306 else if ( l == 0 ) 307 { 308 return a.Size(); 309 } 310 return 0; 311 } 312 313 template< typename TValue > 314 static MeasurementVectorLength Assert(const Array< TValue > *a, 315 const MeasurementVectorLength l, const char *errMsg = "Length Mismatch") 316 { 317 if ( ( ( l != 0 ) && ( a->Size() != l ) ) || ( a->Size() == 0 ) ) 318 { 319 itkGenericExceptionMacro(<< errMsg); 320 } 321 else if ( l == 0 ) 322 { 323 return a->Size(); 324 } 325 return 0; 326 } 327 328 template< typename TValue > 329 static MeasurementVectorLength Assert(const VariableLengthVector< TValue > & a, 330 const MeasurementVectorLength l, const char *errMsg = "Length Mismatch") 331 { 332 if ( ( ( l != 0 ) && ( a.Size() != l ) ) || ( a.Size() == 0 ) ) 333 { 334 itkGenericExceptionMacro(<< errMsg); 335 } 336 else if ( l == 0 ) 337 { 338 return a.Size(); 339 } 340 return 0; 341 } 342 343 template< typename TValue > 344 static MeasurementVectorLength Assert(const VariableLengthVector< TValue > *a, 345 const MeasurementVectorLength l, const char *errMsg = "Length Mismatch") 346 { 347 if ( ( ( l != 0 ) && ( a->Size() != l ) ) || ( a->Size() == 0 ) ) 348 { 349 itkGenericExceptionMacro(<< errMsg); 350 } 351 else if ( l == 0 ) 352 { 353 return a->Size(); 354 } 355 return 0; 356 } 357 358 template< typename TValue > 359 static MeasurementVectorLength Assert(const std::vector< TValue > & a, 360 const MeasurementVectorLength l, const char *errMsg = "Length Mismatch") 361 { 362 if ( ( ( l != 0 ) && ( a.size() != l ) ) || ( a.empty() ) ) 363 { 364 itkGenericExceptionMacro(<< errMsg); 365 } 366 else if ( l == 0 ) 367 { 368 return static_cast<MeasurementVectorLength>( a.size() ); 369 } 370 return 0; 371 } 372 373 template< typename TValue > 374 static MeasurementVectorLength Assert(const std::vector< TValue > *a, 375 const MeasurementVectorLength l, const char *errMsg = "Length Mismatch") 376 { 377 if ( ( ( l != 0 ) && ( a->size() != l ) ) || ( a->size() == 0 ) ) 378 { 379 itkGenericExceptionMacro(<< errMsg); 380 } 381 else if ( l == 0 ) 382 { 383 return a->size(); 384 } 385 return 0; 386 } 387 388 template< typename TArrayType > Assign(TArrayType & m,const TArrayType & v)389 static void Assign(TArrayType & m, const TArrayType & v) 390 { 391 m = v; 392 } 393 394 template< typename TValue, unsigned int VLength > Assign(FixedArray<TValue,VLength> & m,const TValue & v)395 static void Assign(FixedArray< TValue, VLength > & m, const TValue & v) 396 { 397 m[0] = v; 398 } 399 }; 400 401 /** \class MeasurementVectorTraitsTypes 402 * \brief 403 * \ingroup Statistics 404 * \ingroup ITKStatistics 405 */ 406 407 template< typename TMeasurementVector > 408 class MeasurementVectorTraitsTypes 409 { 410 public: 411 using ValueType = typename TMeasurementVector::ValueType; 412 }; 413 414 template< typename T > 415 class MeasurementVectorTraitsTypes< std::vector< T > > 416 { 417 public: 418 using ValueType = T; 419 }; 420 421 /** Traits for generating the MeasurementVectorType that best matches a 422 * particular pixel type. */ 423 424 template< typename TPixelType > 425 class MeasurementVectorPixelTraits 426 { 427 public: 428 /* type of the vector that matches this pixel type */ 429 using MeasurementVectorType = TPixelType; 430 }; 431 432 /// \cond HIDE_SPECIALIZATION_DOCUMENTATION 433 /** 434 * \class MeasurementVectorPixelTraits 435 * \ingroup ITKStatistics 436 */ 437 template< > 438 class MeasurementVectorPixelTraits< char > 439 { 440 public: 441 using MeasurementVectorType = FixedArray< char, 1 >; 442 }; 443 444 template< > 445 class MeasurementVectorPixelTraits< unsigned char > 446 { 447 public: 448 using MeasurementVectorType = FixedArray< unsigned char, 1 >; 449 }; 450 451 template< > 452 class MeasurementVectorPixelTraits< signed char > 453 { 454 public: 455 using MeasurementVectorType = FixedArray< signed char, 1 >; 456 }; 457 458 template< > 459 class MeasurementVectorPixelTraits< unsigned short > 460 { 461 public: 462 using MeasurementVectorType = FixedArray< unsigned short, 1 >; 463 }; 464 465 template< > 466 class MeasurementVectorPixelTraits< signed short > 467 { 468 public: 469 using MeasurementVectorType = FixedArray< signed short, 1 >; 470 }; 471 472 template< > 473 class MeasurementVectorPixelTraits< unsigned int > 474 { 475 public: 476 using MeasurementVectorType = FixedArray< unsigned int, 1 >; 477 }; 478 479 template< > 480 class MeasurementVectorPixelTraits< signed int > 481 { 482 public: 483 using MeasurementVectorType = FixedArray< signed int, 1 >; 484 }; 485 486 template< > 487 class MeasurementVectorPixelTraits< unsigned long > 488 { 489 public: 490 using MeasurementVectorType = FixedArray< unsigned long, 1 >; 491 }; 492 493 template< > 494 class MeasurementVectorPixelTraits< signed long > 495 { 496 public: 497 using MeasurementVectorType = FixedArray< signed long, 1 >; 498 }; 499 500 template< > 501 class MeasurementVectorPixelTraits< unsigned long long > 502 { 503 public: 504 using MeasurementVectorType = FixedArray< unsigned long long, 1 >; 505 }; 506 507 template< > 508 class MeasurementVectorPixelTraits< signed long long > 509 { 510 public: 511 using MeasurementVectorType = FixedArray< signed long long, 1 >; 512 }; 513 514 template< > 515 class MeasurementVectorPixelTraits< float > 516 { 517 public: 518 using MeasurementVectorType = FixedArray< float, 1 >; 519 }; 520 521 template< > 522 class MeasurementVectorPixelTraits< double > 523 { 524 public: 525 using MeasurementVectorType = FixedArray< double, 1 >; 526 }; 527 528 /// \endcond 529 530 } // namespace Statistics 531 } // namespace itk 532 533 #endif // itkMeasurementVectorTraits_h 534