Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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.