Medical Imaging Interaction Toolkit  2023.04.00
Medical Imaging Interaction Toolkit
mitkImageAccessByItk.h
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef mitkImageAccessByItk_h
14 #define mitkImageAccessByItk_h
15 
16 #include <itkCastImageFilter.h>
17 #include <mitkImageToItk.h>
18 #include <mitkPPArgCount.h>
19 #include <boost/preprocessor/expand.hpp>
20 #include <boost/preprocessor/seq/for_each.hpp>
21 #include <boost/preprocessor/seq/for_each_product.hpp>
22 #include <boost/preprocessor/seq/to_tuple.hpp>
23 #include <boost/preprocessor/stringize.hpp>
24 #include <boost/preprocessor/tuple/rem.hpp>
25 
26 #include <sstream>
27 
28 namespace mitk
29 {
38  class AccessByItkException : public virtual std::runtime_error
39  {
40  public:
41  AccessByItkException(const std::string &msg) : std::runtime_error(msg) {}
42  ~AccessByItkException() throw() override {}
43  };
44 }
45 
46 #ifndef DOXYGEN_SKIP
47 
48 #define _accessByItkPixelTypeException(pixelType, pixelTypeSeq) \
49  { \
50  std::string msg("Pixel type "); \
51  msg.append(pixelType.GetPixelTypeAsString()); \
52  msg.append(" is not in " BOOST_PP_STRINGIZE(pixelTypeSeq)); \
53  throw mitk::AccessByItkException(msg); \
54  }
55 
56 #define _accessByItkDimensionException(dim, validDims) \
57  { \
58  std::stringstream msg; \
59  msg << "Dimension " << (dim) << " is not in " << validDims; \
60  throw mitk::AccessByItkException(msg.str()); \
61  }
62 
63 #define _checkSpecificDimensionIter(r, mitkImage, dim) \
64  if (mitkImage->GetDimension() == dim) \
65  ; \
66  else
67 
68 #define _checkSpecificDimension(mitkImage, dimSeq) \
69  BOOST_PP_SEQ_FOR_EACH(_checkSpecificDimensionIter, mitkImage, dimSeq) \
70  _accessByItkDimensionException(mitkImage->GetDimension(), BOOST_PP_STRINGIZE(dimSeq))
71 
72 #define _msvc_expand_bug(macro, arg) BOOST_PP_EXPAND(macro arg)
73 
74 //-------------------------------- 0-Arg Versions --------------------------------------
75 
76 #define _accessByItk(itkImageTypeFunctionAndImageSeq, pixeltype, dimension) \
77  if (pixelType == mitk::MakePixelType<pixeltype, dimension>(pixelType.GetNumberOfComponents()) && \
78  BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)->GetDimension() == dimension) \
79  { \
80  BOOST_PP_SEQ_HEAD(itkImageTypeFunctionAndImageSeq) \
81  (mitk::ImageToItkImage<pixeltype, dimension>(BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)).GetPointer()); \
82  } \
83  else
84 
85 #define _accessByItkArgs(itkImageTypeFunction, type) (itkImageTypeFunction, BOOST_PP_TUPLE_REM(2) type)
86 
87 // product will be of the form ((itkImageTypeFunction)(mitkImage))(short)(2) for pixel type short and dimension 2
88 #ifdef _MSC_VER
89 #define _accessByItkProductIter(r, product) \
90  _msvc_expand_bug( \
91  _accessByItk, \
92  _msvc_expand_bug(_accessByItkArgs, (BOOST_PP_SEQ_HEAD(product), BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)))))
93 #else
94 #define _accessByItkProductIter(r, product) \
95  BOOST_PP_EXPAND( \
96  _accessByItk _accessByItkArgs(BOOST_PP_SEQ_HEAD(product), BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product))))
97 #endif
98 
99 #define _accessFixedTypeByItk(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq) \
100  BOOST_PP_SEQ_FOR_EACH_PRODUCT(_accessByItkProductIter, (((itkImageTypeFunction)(mitkImage)))(pixelTypeSeq)(dimSeq))
101 
102 //-------------------------------- n-Arg Versions --------------------------------------
103 
104 #define _accessByItk_n(itkImageTypeFunctionAndImageSeq, pixeltype, dimension, args) \
105  if (pixelType == mitk::MakePixelType<pixeltype, dimension>(pixelType.GetNumberOfComponents()) && \
106  BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)->GetDimension() == dimension) \
107  { \
108  BOOST_PP_SEQ_HEAD(itkImageTypeFunctionAndImageSeq) \
109  (mitk::ImageToItkImage<pixeltype, dimension>(BOOST_PP_SEQ_TAIL(itkImageTypeFunctionAndImageSeq)).GetPointer(), \
110  BOOST_PP_TUPLE_REM(BOOST_PP_SEQ_HEAD(args)) BOOST_PP_SEQ_TAIL(args)); \
111  } \
112  else
113 
114 #define _accessByItkArgs_n(itkImageTypeFunction, type, args) (itkImageTypeFunction, BOOST_PP_TUPLE_REM(2) type, args)
115 
116 // product will be of the form (((itkImageTypeFunction)(mitkImage))(3)(a,b,c))(short)(2)
117 // for the variable argument list a,b,c and for pixel type short and dimension 2
118 #ifdef _MSC_VER
119 #define _accessByItkProductIter_n(r, product) \
120  _msvc_expand_bug(_accessByItk_n, \
121  _msvc_expand_bug(_accessByItkArgs_n, \
122  (BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_HEAD(product)), \
123  BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)), \
124  BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_HEAD(product)))))
125 #else
126 #define _accessByItkProductIter_n(r, product) \
127  BOOST_PP_EXPAND(_accessByItk_n _accessByItkArgs_n(BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_HEAD(product)), \
128  BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)), \
129  BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_HEAD(product))))
130 #endif
131 
132 #define _accessFixedTypeByItk_n(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq, va_tuple) \
133  BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
134  _accessByItkProductIter_n, \
135  ((((itkImageTypeFunction)(mitkImage))(MITK_PP_ARG_COUNT va_tuple)va_tuple))(pixelTypeSeq)(dimSeq))
136 
137 #endif // DOXYGEN_SKIP
138 
188 #define AccessByItk(mitkImage, itkImageTypeFunction) \
189  AccessFixedTypeByItk( \
190  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
191 
213 #define AccessFixedPixelTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq) \
214  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
215 
230 #define AccessIntegralPixelTypeByItk(mitkImage, itkImageTypeFunction) \
231  AccessFixedTypeByItk( \
232  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
233 
248 #define AccessFloatingPixelTypeByItk(mitkImage, itkImageTypeFunction) \
249  AccessFixedTypeByItk( \
250  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
251 
252 #define AccessVectorPixelTypeByItk(mitkImage, itkImageTypeFunction) \
253  AccessFixedTypeByItk( \
254  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
255 
277 #define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension) \
278  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension))
279 
280 #define AccessVectorFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension) \
281  AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, (dimension))
282 
314 #define AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq) \
315  \
316  { \
317  const mitk::PixelType &pixelType = mitkImage->GetPixelType(); \
318  _checkSpecificDimension(mitkImage, dimSeq); \
319  _accessFixedTypeByItk(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq) \
320  _accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
321  }
322 
323 //------------------------------ n-Arg Access Macros -----------------------------------
324 
372 #define AccessByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
373  AccessFixedTypeByItk_n( \
374  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
375 
400 #define AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, va_tuple) \
401  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
402 
420 #define AccessIntegralPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
421  AccessFixedTypeByItk_n(mitkImage, \
422  itkImageTypeFunction, \
423  MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, \
424  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
425  va_tuple)
426 
444 #define AccessFloatingPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
445  AccessFixedTypeByItk_n(mitkImage, \
446  itkImageTypeFunction, \
447  MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, \
448  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
449  va_tuple)
450 
466 #define AccessVectorPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
467  AccessFixedTypeByItk_n(mitkImage, \
468  itkImageTypeFunction, \
469  MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, \
470  MITK_ACCESSBYITK_DIMENSIONS_SEQ, \
471  va_tuple)
472 
497 #define AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple) \
498  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension), va_tuple)
499 
523 #define AccessVectorFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple) \
524  AccessFixedTypeByItk_n( \
525  mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ, (dimension), va_tuple)
526 
554 #define AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, va_tuple) \
555  \
556  { \
557  const mitk::PixelType &pixelType = mitkImage->GetPixelType(); \
558  _checkSpecificDimension(mitkImage, dimSeq); \
559  _accessFixedTypeByItk_n(itkImageTypeFunction, mitkImage, pixelTypeSeq, dimSeq, va_tuple) \
560  _accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
561  }
562 
563 //------------------------- For back-wards compatibility -------------------------------
564 
565 #define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1) AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1))
566 #define AccessFixedPixelTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1) \
567  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1))
568 #define AccessFixedDimensionByItk_1(mitkImage, itkImageTypeFunction, dimension, arg1) \
569  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1))
570 #define AccessFixedTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1) \
571  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1))
572 
573 #define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2) \
574  AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1, arg2))
575 #define AccessFixedPixelTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2) \
576  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1, arg2))
577 #define AccessFixedDimensionByItk_2(mitkImage, itkImageTypeFunction, dimension, arg1, arg2) \
578  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1, arg2))
579 #define AccessFixedTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2) \
580  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1, arg2))
581 
582 #define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3) \
583  AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1, arg2, arg3))
584 #define AccessFixedPixelTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2, arg3) \
585  AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1, arg2, arg3))
586 #define AccessFixedDimensionByItk_3(mitkImage, itkImageTypeFunction, dimension, arg1, arg2, arg3) \
587  AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1, arg2, arg3))
588 #define AccessFixedTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2, arg3) \
589  AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1, arg2, arg3))
590 
591 //----------------------------- Access two MITK Images ---------------------------------
592 
593 #ifndef DOXYGEN_SKIP
594 
595 #define _accessTwoImagesByItk(itkImageTypeFunction, pixeltype1, dim1, pixeltype2, dim2) \
596  if (pixelType1 == mitk::MakePixelType<itk::Image<pixeltype1, dim1>>() && \
597  pixelType2 == mitk::MakePixelType<itk::Image<pixeltype2, dim2>>() && constImage1->GetDimension() == dim1 && \
598  constImage2->GetDimension() == dim2) \
599  { \
600  typedef itk::Image<pixeltype1, dim1> ImageType1; \
601  typedef itk::Image<pixeltype2, dim2> ImageType2; \
602  typedef mitk::ImageToItk<ImageType1> ImageToItkType1; \
603  typedef mitk::ImageToItk<ImageType2> ImageToItkType2; \
604  itk::SmartPointer<ImageToItkType1> imagetoitk1 = ImageToItkType1::New(); \
605  imagetoitk1->SetInput(nonConstImage1); \
606  imagetoitk1->Update(); \
607  itk::SmartPointer<ImageToItkType2> imagetoitk2 = ImageToItkType2::New(); \
608  imagetoitk2->SetInput(nonConstImage2); \
609  imagetoitk2->Update(); \
610  itkImageTypeFunction(imagetoitk1->GetOutput(), imagetoitk2->GetOutput()); \
611  } \
612  else
613 
614 #define _accessTwoImagesByItkArgs2(itkImageTypeFunction, type1, type2) \
615  (itkImageTypeFunction, BOOST_PP_TUPLE_REM(2) type1, BOOST_PP_TUPLE_REM(2) type2)
616 
617 #define _accessTwoImagesByItkArgs(product) \
618  BOOST_PP_EXPAND(_accessTwoImagesByItkArgs2 BOOST_PP_EXPAND( \
619  (BOOST_PP_SEQ_HEAD(product), BOOST_PP_TUPLE_REM(2) BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)))))
620 
621 // product is of the form (itkImageTypeFunction)((short,2))((char,2))
622 #ifdef _MSC_VER
623 #define _accessTwoImagesByItkIter(r, product) \
624  BOOST_PP_EXPAND(_accessTwoImagesByItk _msvc_expand_bug( \
625  _accessTwoImagesByItkArgs2, \
626  (BOOST_PP_SEQ_HEAD(product), \
627  _msvc_expand_bug(BOOST_PP_TUPLE_REM(2), BOOST_PP_EXPAND(BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(product)))))))
628 #else
629 #define _accessTwoImagesByItkIter(r, product) BOOST_PP_EXPAND(_accessTwoImagesByItk _accessTwoImagesByItkArgs(product))
630 #endif
631 
632 #define _accessTwoImagesByItkForEach(itkImageTypeFunction, tseq1, tseq2) \
633  BOOST_PP_SEQ_FOR_EACH_PRODUCT(_accessTwoImagesByItkIter, ((itkImageTypeFunction))(tseq1)(tseq2))
634 
635 #endif // DOXYGEN_SKIP
636 
681 #define AccessTwoImagesFixedDimensionByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension) \
682  \
683  { \
684  const mitk::PixelType &pixelType1 = mitkImage1->GetPixelType(); \
685  const mitk::PixelType &pixelType2 = mitkImage2->GetPixelType(); \
686  const mitk::Image *constImage1 = mitkImage1; \
687  const mitk::Image *constImage2 = mitkImage2; \
688  mitk::Image *nonConstImage1 = const_cast<mitk::Image *>(constImage1); \
689  mitk::Image *nonConstImage2 = const_cast<mitk::Image *>(constImage2); \
690  nonConstImage1->Update(); \
691  nonConstImage2->Update(); \
692  _checkSpecificDimension(mitkImage1, (dimension)); \
693  _checkSpecificDimension(mitkImage2, (dimension)); \
694  _accessTwoImagesByItkForEach( \
695  itkImageTypeFunction, MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension), MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension)) \
696  { \
697  std::string msg("Pixel type "); \
698  msg.append(pixelType1.GetComponentTypeAsString()); \
699  msg.append(" or pixel type "); \
700  msg.append(pixelType2.GetComponentTypeAsString()); \
701  msg.append(" is not in " BOOST_PP_STRINGIZE(MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension))); \
702  throw mitk::AccessByItkException(msg); \
703  } \
704  }
705 
706 #endif
mitkPPArgCount.h
mitk
DataCollection - Class to facilitate loading/accessing structured data.
Definition: RenderingTests.dox:1
mitk::AccessByItkException::~AccessByItkException
~AccessByItkException() override
Definition: mitkImageAccessByItk.h:42
mitkImageToItk.h
mitk::AccessByItkException
Exception class thrown in AccessByItk macros.
Definition: mitkImageAccessByItk.h:38
mitk::AccessByItkException::AccessByItkException
AccessByItkException(const std::string &msg)
Definition: mitkImageAccessByItk.h:41