Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkMaskUtilities.cpp
Go to the documentation of this file.
1 #ifndef MITKMASKUTIL_CPP
2 #define MITKMASKUTIL_CPP
3 
4 #include <mitkMaskUtilities.h>
5 //#include <mitkImageCast.h>
6 #include <mitkImageAccessByItk.h>
7 #include <itkExtractImageFilter.h>
8 #include <itkChangeInformationImageFilter.h>
9 #include <mitkITKImageImport.h>
10 
11 namespace mitk
12 {
13  template <class TPixel, unsigned int VImageDimension>
15  {
16  if (image != m_Image)
17  {
18  m_Image = image;
19  }
20  }
21 
22  template <class TPixel, unsigned int VImageDimension>
24  {
25  if (mask != m_Mask)
26  {
27  m_Mask = mask;
28  }
29  }
30 
31  template <class TPixel, unsigned int VImageDimension>
33  {
34  if (m_Mask==nullptr || m_Image==nullptr)
35  {
36  MITK_ERROR << "Set an image and a mask first";
37  }
38 
39  typedef itk::Image< TPixel, VImageDimension > ImageType;
40  typedef typename ImageType::PointType PointType;
41  typedef typename ImageType::DirectionType DirectionType;
42 
43  bool maskSanity = true;
44 
45 
46  if (m_Mask==nullptr)
47  {
48  MITK_ERROR << "Something went wrong when casting the mitk mask image to an itk mask image. Do the mask and the input image have the same dimension?";
49  // note to self: We could try to convert say a 2d mask to a 3d mask if the image is 3d. (mask and image dimension have to match.)
50  }
51  // check direction
52  DirectionType imageDirection = m_Image->GetDirection();
53  DirectionType maskDirection = m_Mask->GetDirection();
54  for( int i = 0; i < imageDirection.ColumnDimensions; ++i )
55  {
56  for( int j = 0; j < imageDirection.ColumnDimensions; ++j )
57  {
58  double differenceDirection = imageDirection[i][j] - maskDirection[i][j];
59  if ( fabs( differenceDirection ) > mitk::eps )
60  {
61  double differenceDirection = imageDirection[i][j] - maskDirection[i][j];
62  if ( fabs( differenceDirection ) > 0.001 /*mitk::eps*/ ) // TODO: temp fix (bug 17121)
63  {
64  maskSanity = false;
65  MITK_INFO << "Mask needs to have same direction as image! (Image direction: " << imageDirection << "; Mask direction: " << maskDirection << ")";
66  }
67  }
68  }
69  }
70 
71  // check spacing
72  PointType imageSpacing = m_Image->GetSpacing();
73  PointType maskSpacing = m_Mask->GetSpacing();
74  for (unsigned int i = 0; i < VImageDimension; i++)
75  {
76  if ( fabs( maskSpacing[i] - imageSpacing[i] ) > mitk::eps )
77  {
78  maskSanity = false;
79  MITK_INFO << "Spacing of mask and image is not equal. Mask: " << maskSpacing << " image: " << imageSpacing;
80  }
81  }
82 
83  // check alignment
84  // Make sure that the voxels of mask and image are correctly "aligned", i.e., voxel boundaries are the same in both images
85  PointType imageOrigin = m_Image->GetOrigin();
86  PointType maskOrigin = m_Mask->GetOrigin();
87 
88  typedef itk::ContinuousIndex<double, VImageDimension> ContinousIndexType;
89  ContinousIndexType maskOriginContinousIndex, imageOriginContinousIndex;
90 
91  m_Image->TransformPhysicalPointToContinuousIndex(maskOrigin, maskOriginContinousIndex);
92  m_Image->TransformPhysicalPointToContinuousIndex(imageOrigin, imageOriginContinousIndex);
93 
94  for ( unsigned int i = 0; i < ImageType::ImageDimension; ++i )
95  {
96  double misalignment = maskOriginContinousIndex[i] - floor( maskOriginContinousIndex[i] + 0.5 );
97  // misalignment must be a multiple (int) of spacing in that direction
98  if ( fmod(misalignment,imageSpacing[i]) > mitk::eps )
99  {
100  maskSanity = false;
101  MITK_INFO << "Pixels/voxels of mask and image are not sufficiently aligned! (Misalignment: " << fmod(misalignment,imageSpacing[i]) << ")";
102  }
103  }
104 
105  // mask must be completely inside image region
106  // Make sure that mask region is contained within image region
107  if ( m_Mask!=nullptr &&
108  !m_Image->GetLargestPossibleRegion().IsInside( m_Mask->GetLargestPossibleRegion() ) )
109  {
110  maskSanity = false;
111  MITK_INFO << "Mask region needs to be inside of image region! (Image region: "
112  << m_Image->GetLargestPossibleRegion() << "; Mask region: " << m_Mask->GetLargestPossibleRegion() << ")";
113  }
114  return maskSanity;
115  }
116 
117  template <class TPixel, unsigned int VImageDimension>
119  {
120  if (m_Mask==nullptr || m_Image==nullptr)
121  {
122  MITK_ERROR << "Set an image and a mask first";
123  }
124 
125  bool maskSanity = CheckMaskSanity();
126 
127  if (!maskSanity)
128  {
129  MITK_ERROR << "Mask and image are not compatible";
130  }
131 
132  typedef itk::Image< TPixel, VImageDimension > ImageType;
133  typedef itk::Image< unsigned short, VImageDimension > MaskType;
134  typedef itk::ExtractImageFilter< ImageType, ImageType > ExtractImageFilterType;
135 
136  typename ImageType::SizeType imageSize = m_Image->GetBufferedRegion().GetSize();
137  typename ImageType::SizeType maskSize = m_Mask->GetBufferedRegion().GetSize();
138 
140 
141  bool maskSmallerImage = false;
142  for ( unsigned int i = 0; i < ImageType::ImageDimension; ++i )
143  {
144  if ( maskSize[i] < imageSize[i] )
145  {
146  maskSmallerImage = true;
147  }
148  }
149 
150  if ( maskSmallerImage )
151  {
152  typename ExtractImageFilterType::Pointer extractImageFilter = ExtractImageFilterType::New();
153  typename MaskType::PointType maskOrigin = m_Mask->GetOrigin();
154  typename ImageType::PointType imageOrigin = m_Image->GetOrigin();
155  typename MaskType::SpacingType maskSpacing = m_Mask->GetSpacing();
156  typename ImageType::RegionType extractionRegion;
157  typename ImageType::IndexType extractionRegionIndex;
158 
159 
160  for (unsigned int i=0; i < maskOrigin.GetPointDimension(); i++)
161  {
162  extractionRegionIndex[i] = (maskOrigin[i] - imageOrigin[i]) / maskSpacing[i];
163  }
164 
165  extractionRegion.SetIndex(extractionRegionIndex);
166  extractionRegion.SetSize(m_Mask->GetLargestPossibleRegion().GetSize());
167 
168  extractImageFilter->SetInput( m_Image );
169  extractImageFilter->SetExtractionRegion( extractionRegion );
170  extractImageFilter->SetCoordinateTolerance( 0.001 );
171  extractImageFilter->SetDirectionTolerance( 0.001 );
172  extractImageFilter->Update();
173  extractedImg = extractImageFilter->GetOutput();
174  extractedImg->SetOrigin(m_Mask->GetOrigin());
175  extractedImg->SetLargestPossibleRegion(m_Mask->GetLargestPossibleRegion());
176  extractedImg->SetBufferedRegion(m_Mask->GetBufferedRegion());
177 
178  }
179  else
180  {
181  extractedImg = m_Image;
182  }
183 
184  return extractedImg;
185  }
186 
187 }
188 
189 #endif
mitk::Point3D PointType
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
#define MITK_ERROR
Definition: mitkLogMacros.h:24
itk::Image< TPixel, VImageDimension >::Pointer ExtractMaskImageRegion()
Crops the image to the LargestPossibleRegion of the mask.
DataCollection - Class to facilitate loading/accessing structured data.
map::core::discrete::Elements< 3 >::InternalImageType ImageType
bool CheckMaskSanity()
Checks whether mask and image are compatible for joint access (as via iterators). Spacing and directi...
void SetImage(ImageType *image)
Set image.
itk::Image< unsigned short, VImageDimension > MaskType
itk::Image< TPixel, VImageDimension > ImageType
void SetMask(MaskType *mask)
Set mask.
MITKCORE_EXPORT const ScalarType eps
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.