23 #include <itkMinimumMaximumImageCalculator.h> 24 #include <itkImageRegionIteratorWithIndex.h> 25 #include <itkBinaryCrossStructuringElement.h> 26 #include <itkBinaryErodeImageFilter.h> 27 #include <itkAddImageFilter.h> 30 struct GreyLevelDistanceZoneMatrixHolder
35 int IntensityToIndex(
double intensity);
40 Eigen::MatrixXd m_Matrix;
54 m_NumberOfBins(number),
55 m_MaximumSize(maxSize),
57 m_Quantifier(quantifier)
59 m_Matrix.resize(number, maxSize);
63 int mitk::GreyLevelDistanceZoneMatrixHolder::IntensityToIndex(
double intensity)
65 return m_Quantifier->IntensityToIndex(intensity);
69 template<
typename TPixel,
unsigned int VImageDimension>
72 itk::Image<unsigned short, VImageDimension>*
mask,
73 itk::Image<unsigned short, VImageDimension>* distanceImage,
74 std::vector<itk::Offset<VImageDimension> > offsets,
75 bool estimateLargestRegion,
76 mitk::GreyLevelDistanceZoneMatrixHolder &holder)
78 typedef itk::Image<TPixel, VImageDimension>
ImageType;
79 typedef itk::Image<unsigned short, VImageDimension>
MaskImageType;
80 typedef typename ImageType::IndexType IndexType;
82 typedef itk::ImageRegionIteratorWithIndex<ImageType> ConstIterType;
83 typedef itk::ImageRegionIteratorWithIndex<MaskImageType> ConstMaskIterType;
85 auto region = mask->GetLargestPossibleRegion();
86 typename MaskImageType::RegionType newRegion;
87 newRegion.SetSize(region.GetSize());
88 newRegion.SetIndex(region.GetIndex());
90 ConstIterType imageIter(itkImage, itkImage->GetLargestPossibleRegion());
91 ConstMaskIterType maskIter(mask, mask->GetLargestPossibleRegion());
93 typename MaskImageType::Pointer visitedImage = MaskImageType::New();
94 visitedImage->SetRegions(newRegion);
95 visitedImage->Allocate();
96 visitedImage->FillBuffer(0);
98 int largestRegion = 0;
99 holder.m_NumberOfBins = 0;
101 while (!maskIter.IsAtEnd())
103 if (maskIter.Value() > 0 )
105 auto startIntensityIndex = holder.IntensityToIndex(imageIter.Value());
106 std::vector<IndexType> indices;
107 indices.push_back(maskIter.GetIndex());
108 unsigned int steps = 0;
109 int smallestDistance = 500;
111 while (indices.size() > 0)
113 auto currentIndex = indices.back();
116 if (!region.IsInside(currentIndex))
121 auto wasVisited = visitedImage->GetPixel(currentIndex);
122 auto newIntensityIndex = holder.IntensityToIndex(itkImage->GetPixel(currentIndex));
123 auto isInMask = mask->GetPixel(currentIndex);
125 if ((isInMask > 0) &&
126 (newIntensityIndex == startIntensityIndex) &&
129 ++(holder.m_NumerOfVoxels);
130 smallestDistance = (smallestDistance > distanceImage->GetPixel(currentIndex)) ? distanceImage->GetPixel(currentIndex) : smallestDistance;
132 visitedImage->SetPixel(currentIndex, 1);
133 for (
auto offset : offsets)
135 auto newIndex = currentIndex +
offset;
136 indices.push_back(newIndex);
137 newIndex = currentIndex -
offset;
138 indices.push_back(newIndex);
145 largestRegion = std::max<int>(steps, largestRegion);
146 steps = std::min<unsigned int>(steps, holder.m_MaximumSize);
147 if (!estimateLargestRegion)
149 holder.m_Matrix(startIntensityIndex, smallestDistance-1) += 1;
156 return largestRegion;
159 template <
typename TPixel,
unsigned int VDimension>
161 itk::Image<TPixel, VDimension> *sourceImage,
165 typedef itk::Image<TPixel, VDimension>
ImageType;
166 typedef unsigned short MaskType;
169 typename MaskImageType::Pointer distanceImage = MaskImageType::New();
170 distanceImage->SetRegions(sourceImage->GetLargestPossibleRegion());
171 distanceImage->SetOrigin(sourceImage->GetOrigin());
172 distanceImage->SetSpacing(sourceImage->GetSpacing());
173 distanceImage->SetDirection(sourceImage->GetDirection());
174 distanceImage->Allocate();
177 typename ImageType::SizeType radius;
179 itk::NeighborhoodIterator<ImageType> neighbourIter(radius, sourceImage, sourceImage->GetLargestPossibleRegion());
180 itk::NeighborhoodIterator<MaskImageType> distanceIter(radius, distanceImage, distanceImage->GetLargestPossibleRegion());
182 bool imageChanged =
true;
185 imageChanged =
false;
187 neighbourIter.GoToBegin();
188 distanceIter.GoToBegin();
189 while (!neighbourIter.IsAtEnd())
191 MaskType oldDistance = distanceIter.GetCenterPixel();
192 maxDistance = std::max<MaskType>(maxDistance, oldDistance);
193 if (neighbourIter.GetCenterPixel() < 1)
197 distanceIter.SetCenterPixel(0);
201 else if (oldDistance>0) {
202 MaskType minimumDistance = oldDistance;
203 for (
unsigned int i = 0; i < distanceIter.Size(); ++i)
205 minimumDistance = std::min<MaskType>(minimumDistance, 1+distanceIter.GetPixel(i));
207 if (minimumDistance != oldDistance)
209 distanceIter.SetCenterPixel(minimumDistance);
231 erode(input, finalOutput, maxDistance);
236 mitk::GreyLevelDistanceZoneMatrixHolder &holder,
240 auto SgzMatrix = holder.m_Matrix;
241 auto pgzMatrix = holder.m_Matrix;
242 auto pgMatrix = holder.m_Matrix;
243 auto pzMatrix = holder.m_Matrix;
245 double Ns = pgzMatrix.sum();
247 pgMatrix.rowwise().normalize();
248 pzMatrix.colwise().normalize();
250 for (
int i = 0; i < pgzMatrix.rows(); ++i)
251 for (
int j = 0; j < pgzMatrix.cols(); ++j)
253 if (pgzMatrix(i, j) != pgzMatrix(i, j))
255 if (pgMatrix(i, j) != pgMatrix(i, j))
257 if (pzMatrix(i, j) != pzMatrix(i, j))
261 Eigen::VectorXd SgVector = SgzMatrix.rowwise().sum();
262 Eigen::VectorXd SzVector = SgzMatrix.colwise().sum();
264 for (
int j = 0; j < SzVector.size(); ++j)
271 for (
int i = 0; i < SgVector.size(); ++i)
279 for (
int i = 0; i < SgzMatrix.rows(); ++i)
281 for (
int j = 0; j < SgzMatrix.cols(); ++j)
291 if (pgzMatrix(i, j) > 0)
296 for (
int i = 0; i < SgzMatrix.rows(); ++i)
298 for (
int j = 0; j < SgzMatrix.cols(); ++j)
322 template<
typename TPixel,
unsigned int VImageDimension>
326 typedef itk::Image<unsigned short, VImageDimension> MaskType;
327 typedef itk::Neighborhood<TPixel, VImageDimension > NeighborhoodType;
328 typedef itk::Offset<VImageDimension> OffsetType;
331 int maximumDistance = 0;
334 typename MaskType::Pointer distanceImage = MaskType::New();
337 typename MaskType::Pointer maskImage = MaskType::New();
341 std::vector < itk::Offset<VImageDimension> > offsetVector;
342 NeighborhoodType hood;
344 unsigned int centerIndex = hood.GetCenterNeighborhoodIndex();
346 for (
unsigned int d = 0; d < centerIndex; d++)
348 offset = hood.GetOffset(d);
349 bool useOffset =
true;
350 for (
unsigned int i = 0; i < VImageDimension; ++i)
352 if ((config.
direction == i + 2) && offset[i] != 0)
359 offsetVector.push_back(offset);
364 offsetVector.clear();
368 offsetVector.push_back(offset);
371 MITK_INFO <<
"Maximum Distance: " << maximumDistance;
372 std::vector<mitk::GreyLevelDistanceZoneFeatures> resultVector;
373 mitk::GreyLevelDistanceZoneMatrixHolder holderOverall(config.
Quantifier, config.
Bins, maximumDistance + 1);
375 CalculateGlSZMatrix<TPixel, VImageDimension>(itkImage, maskImage, distanceImage, offsetVector,
false, holderOverall);
387 featureList.push_back(std::make_pair(prefix +
"Small Distance Emphasis", features.
SmallDistanceEmphasis));
388 featureList.push_back(std::make_pair(prefix +
"Large Distance Emphasis", features.
LargeDistanceEmphasis));
389 featureList.push_back(std::make_pair(prefix +
"Low Grey Level Emphasis", features.
LowGreyLevelEmphasis));
390 featureList.push_back(std::make_pair(prefix +
"High Grey Level Emphasis", features.
HighGreyLevelEmphasis));
395 featureList.push_back(std::make_pair(prefix +
"Grey Level Non-Uniformity", features.
GreyLevelNonUniformity));
399 featureList.push_back(std::make_pair(prefix +
"Zone Percentage", features.
ZonePercentage));
400 featureList.push_back(std::make_pair(prefix +
"Grey Level Mean", features.
GreyLevelMean));
401 featureList.push_back(std::make_pair(prefix +
"Grey Level Variance", features.
GreyLevelVariance));
402 featureList.push_back(std::make_pair(prefix +
"Zone Distance Mean", features.
ZoneDistanceMean));
403 featureList.push_back(std::make_pair(prefix +
"Zone Distance Variance", features.
ZoneDistanceVariance));
404 featureList.push_back(std::make_pair(prefix +
"Zone Distance Entropy", features.
ZoneDistanceEntropy));
405 featureList.push_back(std::make_pair(prefix +
"Grey Level Entropy", features.
ZoneDistanceEntropy));
470 MITK_INFO <<
"Start calculating Grey Level Distance Zone ....";
472 featureList.insert(featureList.end(), localResults.begin(), localResults.end());
473 MITK_INFO <<
"Finished calculating Grey Level Distance Zone.";
#define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3)
std::vector< std::string > FeatureNameListType
double ZoneDistanceNonUniformity
itk::Image< unsigned char, 3 > ImageType
virtual void SetLongName(std::string _arg)
void erodeAndAdd(mitk::Image::Pointer input, mitk::Image::Pointer &finalOutput, int &maxDistance)
void erode(mitk::Image::Pointer input, mitk::Image::Pointer &output, int &maxDistance)
static void MatrixFeaturesTo(mitk::GreyLevelDistanceZoneFeatures features, std::string prefix, mitk::GIFGreyLevelDistanceZone::FeatureListType &featureList)
DataCollection - Class to facilitate loading/accessing structured data.
double HighGreyLevelEmphasis
FeatureNameListType GetFeatureNames() override
Returns a list of the names of all features that are calculated from this class.
void addArgument(const std::string &longarg, const std::string &shortarg, Type type, const std::string &argLabel, const std::string &argHelp=std::string(), const us::Any &defaultValue=us::Any(), bool optional=true, bool ignoreRest=false, bool deprecated=false, mitkCommandLineParser::Channel channel=mitkCommandLineParser::Channel::None)
virtual void SetShortName(std::string _arg)
double LargeDistanceEmphasis
void CalculateFeaturesUsingParameters(const Image::Pointer &feature, const Image::Pointer &mask, const Image::Pointer &maskNoNAN, FeatureListType &featureList) override
Calculates the feature of this abstact interface. Does not necessarily considers the parameter settin...
double GreyLevelNonUniformity
std::vector< std::pair< std::string, double > > FeatureListType
int CalculateGlSZMatrix(itk::Image< TPixel, VImageDimension > *itkImage, itk::Image< unsigned short, VImageDimension > *mask, itk::Image< unsigned short, VImageDimension > *distanceImage, std::vector< itk::Offset< VImageDimension > > offsets, bool estimateLargestRegion, mitk::GreyLevelDistanceZoneMatrixHolder &holder)
double ZoneDistanceVariance
double SmallDistanceLowGreyLevelEmphasis
std::string QuantifierParameterString()
double LowGreyLevelEmphasis
std::string FeatureDescriptionPrefix()
Returns a string that encodes the feature class name.
double ZoneDistanceEntropy
virtual mitk::Image::Pointer GetMorphMask() const
void itkErode2(itk::Image< TPixel, VDimension > *sourceImage, mitk::Image::Pointer &resultImage, int &maxDistance)
virtual std::string GetLongName() const
std::string GetOptionPrefix() const
itk::Image< unsigned char, 3 > MaskImageType
virtual int GetDirection() const
double SmallDistanceEmphasis
mitk::Image::Pointer distanceMask
FeatureListType CalculateFeatures(const Image::Pointer &image, const Image::Pointer &feature) override
Calculates the First Order Features based on a binned version of the image.
double LargeDistanceHighGreyLevelEmphasis
double GreyLevelNonUniformityNormalized
mitk::Image::Pointer image
void AddQuantifierArguments(mitkCommandLineParser &parser)
GIFGreyLevelDistanceZone()
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
virtual void SetFeatureClassName(std::string _arg)
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
mitk::Image::Pointer mask
FeatureListType CalculateFeatures(const Image::Pointer &image, const Image::Pointer &feature) override
Calculates the Cooccurence-Matrix based features for this class.
#define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2)
double SmallDistanceHighGreyLevelEmphasis
virtual IntensityQuantifier::Pointer GetQuantifier()
double ZoneDistanceNoneUniformityNormalized
void InitializeQuantifierFromParameters(const Image::Pointer &feature, const Image::Pointer &mask, unsigned int defaultBins=256)
double LargeDistanceLowGreyLevelEmphasis
mitk::IntensityQuantifier::Pointer Quantifier
static void CalculateGreyLevelDistanceZoneFeatures(itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer mask, mitk::GIFGreyLevelDistanceZone::FeatureListType &featureList, mitk::GIFGreyLevelDistanceZone::GIFGreyLevelDistanceZoneConfiguration config)
void AddArguments(mitkCommandLineParser &parser) override
void InitializeQuantifier(const Image::Pointer &feature, const Image::Pointer &mask, unsigned int defaultBins=256)
virtual ParameterTypes GetParameter() const
std::string GetCurrentFeatureEncoding() override
Adds an additional Separator to the name of the feature, which encodes the used parameters.