diff --git a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.h b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.h index 44d67da15c..621ab6fd48 100644 --- a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.h +++ b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.h @@ -1,231 +1,241 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ /*========================================================================= * * Copyright Insight Software Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef __itkEnhancedHistogramToRunLengthFeaturesFilter_h #define __itkEnhancedHistogramToRunLengthFeaturesFilter_h #include "itkHistogram.h" #include "itkMacro.h" #include "itkProcessObject.h" #include "itkSimpleDataObjectDecorator.h" namespace itk { namespace Statistics { /** \class EnhancedHistogramToRunLengthFeaturesFilter * \brief This class computes texture feature coefficients from a grey level * run-length matrix. * * By default, run length features are computed for each spatial * direction and then averaged afterward, so it is possible to access the * standard deviations of the texture features. These values give a clue as * to texture anisotropy. However, doing this is much more work, because it * involved computing one for each offset given. To compute a single matrix * using the first offset, call FastCalculationsOn(). If this is called, * then the texture standard deviations will not be computed (and will be set * to zero), but texture computation will be much faster. * * This class is templated over the input histogram type. * * Print references: * M. M. Galloway. Texture analysis using gray level run lengths. Computer * Graphics and Image Processing, 4:172-179, 1975. * * A. Chu, C. M. Sehgal, and J. F. Greenleaf. Use of gray value distribution of * run lengths for texture analysis. Pattern Recognition Letters, 11:415-420, * 1990. * * B. R. Dasarathy and E. B. Holder. Image characterizations based on joint * gray-level run-length distributions. Pattern Recognition Letters, 12:490-502, * 1991. * * IJ article: http://hdl.handle.net/1926/1374 * * \sa ScalarImageToRunLengthFeaturesFilter * \sa ScalarImageToRunLengthMatrixFilter * \sa EnhancedHistogramToRunLengthFeaturesFilter * * \author: Nick Tustison * \ingroup ITKStatistics */ template< typename THistogram > class EnhancedHistogramToRunLengthFeaturesFilter : public ProcessObject { public: /** Standard typedefs */ typedef EnhancedHistogramToRunLengthFeaturesFilter Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( EnhancedHistogramToRunLengthFeaturesFilter, ProcessObject ); /** standard New() method support */ itkNewMacro( Self ); typedef THistogram HistogramType; typedef typename HistogramType::Pointer HistogramPointer; typedef typename HistogramType::ConstPointer HistogramConstPointer; typedef typename HistogramType::MeasurementType MeasurementType; typedef typename HistogramType::MeasurementVectorType MeasurementVectorType; typedef typename HistogramType::IndexType IndexType; typedef typename HistogramType:: TotalAbsoluteFrequencyType FrequencyType; /** Method to Set/Get the input Histogram */ using Superclass::SetInput; void SetInput ( const HistogramType * histogram ); const HistogramType * GetInput() const; /** Smart Pointer type to a DataObject. */ typedef DataObject::Pointer DataObjectPointer; /** Type of DataObjects used for scalar outputs */ typedef SimpleDataObjectDecorator MeasurementObjectType; /** Methods to return the short run emphasis. */ MeasurementType GetShortRunEmphasis() const; const MeasurementObjectType* GetShortRunEmphasisOutput() const; /** Methods to return the long run emphasis. */ MeasurementType GetLongRunEmphasis() const; const MeasurementObjectType* GetLongRunEmphasisOutput() const; /** Methods to return the grey level nonuniformity. */ MeasurementType GetGreyLevelNonuniformity() const; const MeasurementObjectType* GetGreyLevelNonuniformityOutput() const; + /** Methods to return the grey level nonuniformity. */ + MeasurementType GetGreyLevelNonuniformityNormalized() const; + const MeasurementObjectType* GetGreyLevelNonuniformityNormalizedOutput() const; + /** Methods to return the run length nonuniformity. */ MeasurementType GetRunLengthNonuniformity() const; const MeasurementObjectType* GetRunLengthNonuniformityOutput() const; + /** Methods to return the run length nonuniformity. */ + MeasurementType GetRunLengthNonuniformityNormalized() const; + const MeasurementObjectType* GetRunLengthNonuniformityNormalizedOutput() const; + /** Methods to return the low grey level run emphasis. */ MeasurementType GetLowGreyLevelRunEmphasis() const; const MeasurementObjectType* GetLowGreyLevelRunEmphasisOutput() const; /** Methods to return the high grey level run emphasis. */ MeasurementType GetHighGreyLevelRunEmphasis() const; const MeasurementObjectType* GetHighGreyLevelRunEmphasisOutput() const; /** Methods to return the short run low grey level run emphasis. */ MeasurementType GetShortRunLowGreyLevelEmphasis() const; const MeasurementObjectType* GetShortRunLowGreyLevelEmphasisOutput() const; /** Methods to return the short run high grey level run emphasis. */ MeasurementType GetShortRunHighGreyLevelEmphasis() const; const MeasurementObjectType* GetShortRunHighGreyLevelEmphasisOutput() const; /** Methods to return the long run low grey level run emphasis. */ MeasurementType GetLongRunLowGreyLevelEmphasis() const; const MeasurementObjectType* GetLongRunLowGreyLevelEmphasisOutput() const; /** Methods to return the long run high grey level run emphasis. */ MeasurementType GetLongRunHighGreyLevelEmphasis() const; const MeasurementObjectType* GetLongRunHighGreyLevelEmphasisOutput() const; /** Methods to return the long run high grey level run emphasis. */ MeasurementType GetRunPercentage() const; const MeasurementObjectType* GetRunPercentageOutput() const; /** Methods to return the long run high grey level run emphasis. */ MeasurementType GetNumberOfRuns() const; const MeasurementObjectType* GetNumberOfRunsOutput() const; /** Methods to return the grey level variance. */ MeasurementType GetGreyLevelVariance() const; const MeasurementObjectType* GetGreyLevelVarianceOutput() const; /** Methods to return the run length variance. */ MeasurementType GetRunLengthVariance() const; const MeasurementObjectType* GetRunLengthVarianceOutput() const; /** Methods to return the run entropy. */ MeasurementType GetRunEntropy() const; const MeasurementObjectType* GetRunEntropyOutput() const; itkGetMacro( TotalNumberOfRuns, unsigned long ); itkGetConstMacro(NumberOfVoxels, unsigned long); itkSetMacro(NumberOfVoxels, unsigned long); /** Run-length feature types */ typedef enum { ShortRunEmphasis, LongRunEmphasis, GreyLevelNonuniformity, + GreyLevelNonuniformityNormalized, RunLengthNonuniformity, + RunLengthNonuniformityNormalized, LowGreyLevelRunEmphasis, HighGreyLevelRunEmphasis, ShortRunLowGreyLevelEmphasis, ShortRunHighGreyLevelEmphasis, LongRunLowGreyLevelEmphasis, LongRunHighGreyLevelEmphasis, RunPercentage, NumberOfRuns, GreyLevelVariance, RunLengthVariance, RunEntropy } RunLengthFeatureName; /** convenience method to access the run length values */ MeasurementType GetFeature( RunLengthFeatureName name ); protected: EnhancedHistogramToRunLengthFeaturesFilter(); ~EnhancedHistogramToRunLengthFeaturesFilter() {}; virtual void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; /** Make a DataObject to be used for output output. */ typedef ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType; using Superclass::MakeOutput; virtual DataObjectPointer MakeOutput( DataObjectPointerArraySizeType ) ITK_OVERRIDE; virtual void GenerateData() ITK_OVERRIDE; private: EnhancedHistogramToRunLengthFeaturesFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented unsigned long m_TotalNumberOfRuns; unsigned long m_NumberOfVoxels; }; } // end of namespace Statistics } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkEnhancedHistogramToRunLengthFeaturesFilter.hxx" #endif #endif diff --git a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.hxx b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.hxx index 67d0cc5703..53a7f2095e 100644 --- a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.hxx +++ b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToRunLengthFeaturesFilter.hxx @@ -1,602 +1,658 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ /*========================================================================= * * Copyright Insight Software Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef __itkEnhancedHistogramToRunLengthFeaturesFilter_hxx #define __itkEnhancedHistogramToRunLengthFeaturesFilter_hxx #include "itkEnhancedHistogramToRunLengthFeaturesFilter.h" #include "itkNumericTraits.h" #include "vnl/vnl_math.h" namespace itk { namespace Statistics { //constructor template EnhancedHistogramToRunLengthFeaturesFilter ::EnhancedHistogramToRunLengthFeaturesFilter() : m_NumberOfVoxels(1) { this->ProcessObject::SetNumberOfRequiredInputs( 1 ); // allocate the data objects for the outputs which are // just decorators real types for( unsigned int i = 0; i < 15; i++ ) { this->ProcessObject::SetNthOutput( i, this->MakeOutput( i ) ); } } template void EnhancedHistogramToRunLengthFeaturesFilter< THistogram> ::SetInput( const HistogramType *histogram ) { this->ProcessObject::SetNthInput( 0, const_cast( histogram ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::HistogramType * EnhancedHistogramToRunLengthFeaturesFilter< THistogram> ::GetInput() const { if ( this->GetNumberOfInputs() < 1 ) { return ITK_NULLPTR; } return itkDynamicCastInDebugMode(this->ProcessObject::GetInput( 0 ) ); } template typename EnhancedHistogramToRunLengthFeaturesFilter::DataObjectPointer EnhancedHistogramToRunLengthFeaturesFilter ::MakeOutput( DataObjectPointerArraySizeType itkNotUsed( idx ) ) { return MeasurementObjectType::New().GetPointer(); } template void EnhancedHistogramToRunLengthFeaturesFilter< THistogram>:: GenerateData( void ) { const HistogramType * inputHistogram = this->GetInput(); this->m_TotalNumberOfRuns = static_cast ( inputHistogram->GetTotalFrequency() ); MeasurementType shortRunEmphasis = NumericTraits::ZeroValue(); MeasurementType longRunEmphasis = NumericTraits::ZeroValue(); MeasurementType greyLevelNonuniformity = NumericTraits::ZeroValue(); MeasurementType runLengthNonuniformity = NumericTraits::ZeroValue(); MeasurementType lowGreyLevelRunEmphasis = NumericTraits::ZeroValue(); MeasurementType highGreyLevelRunEmphasis = NumericTraits::ZeroValue(); MeasurementType shortRunLowGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType shortRunHighGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType longRunLowGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType longRunHighGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType runPercentage = NumericTraits::ZeroValue(); MeasurementType numberOfRuns = NumericTraits::ZeroValue(); //Added 15.07.2016 MeasurementType greyLevelVariance = NumericTraits::ZeroValue(); MeasurementType runLengthVariance = NumericTraits::ZeroValue(); MeasurementType runEntropy = NumericTraits::ZeroValue(); + //Added 09.09.2016 + MeasurementType greyLevelNonuniformityNormalized = NumericTraits::ZeroValue(); + MeasurementType runLengthNonuniformityNormalized = NumericTraits::ZeroValue(); + vnl_vector greyLevelNonuniformityVector( inputHistogram->GetSize()[0], 0.0 ); vnl_vector runLengthNonuniformityVector( inputHistogram->GetSize()[1], 0.0 ); typedef typename HistogramType::ConstIterator HistogramIterator; double mu_i = 0.0; double mu_j = 0.0; //Calculate the means. for ( HistogramIterator hit = inputHistogram->Begin(); hit != inputHistogram->End(); ++hit ) { MeasurementType frequency = hit.GetFrequency(); if ( frequency == 0 ) { continue; } MeasurementVectorType measurement = hit.GetMeasurementVector(); IndexType index = hit.GetIndex(); double i = index[0] + 1; double j = index[1] + 1; double p_ij = frequency / m_TotalNumberOfRuns; mu_i += i * p_ij; mu_j += j * p_ij; } //Calculate the other features. const double log2 = std::log(2.0); for ( HistogramIterator hit = inputHistogram->Begin(); hit != inputHistogram->End(); ++hit ) { MeasurementType frequency = hit.GetFrequency(); if ( frequency == 0 ) { continue; } MeasurementVectorType measurement = hit.GetMeasurementVector(); IndexType index = hit.GetIndex(); // inputHistogram->GetIndex( hit.GetInstanceIdentifier() ); double i2 = static_cast( ( index[0] + 1 ) * ( index[0] + 1 ) ); double j2 = static_cast( ( index[1] + 1 ) * ( index[1] + 1 ) ); double i = index[0] + 1; double j = index[1] + 1; double p_ij = frequency / m_TotalNumberOfRuns; greyLevelVariance += ((i - mu_i) * (i - mu_i) * p_ij); runLengthVariance += ((j - mu_j) * (j - mu_j) * p_ij); runEntropy -= ( p_ij > 0.0001 ) ? p_ij *std::log(p_ij) / log2 : 0; // Traditional measures shortRunEmphasis += ( frequency / j2 ); longRunEmphasis += ( frequency * j2 ); greyLevelNonuniformityVector[index[0]] += frequency; runLengthNonuniformityVector[index[1]] += frequency; // measures from Chu et al. - lowGreyLevelZoneEmphasis += (i2 > 0.0001) ? ( frequency / i2 ) : 0; - highGreyLevelZoneEmphasis += ( frequency * i2 ); + lowGreyLevelRunEmphasis += (i2 > 0.0001) ? ( frequency / i2 ) : 0; + highGreyLevelRunEmphasis += ( frequency * i2 ); // measures from Dasarathy and Holder - SmallZoneLowGreyLevelEmphasis += ((i2 * j2) > 0.0001) ? ( frequency / ( i2 * j2 ) ) : 0; - SmallZoneHighGreyLevelEmphasis += (j2 > 0.0001) ? ( frequency * i2 / j2 ) : 0; - LargeZoneLowGreyLevelEmphasis += (i2 = 0.0001) ? ( frequency * j2 / i2 ) : 0; - LargeZoneHighGreyLevelEmphasis += ( frequency * i2 * j2 ); + shortRunLowGreyLevelEmphasis += ((i2 * j2) > 0.0001) ? ( frequency / ( i2 * j2 ) ) : 0; + shortRunHighGreyLevelEmphasis += (j2 > 0.0001) ? ( frequency * i2 / j2 ) : 0; + longRunLowGreyLevelEmphasis += (i2 = 0.0001) ? ( frequency * j2 / i2 ) : 0; + longRunHighGreyLevelEmphasis += ( frequency * i2 * j2 ); } greyLevelNonuniformity = greyLevelNonuniformityVector.squared_magnitude(); runLengthNonuniformity = runLengthNonuniformityVector.squared_magnitude(); // Normalize all measures by the total number of runs if (this->m_TotalNumberOfRuns > 0) { shortRunEmphasis /= static_cast( this->m_TotalNumberOfRuns ); longRunEmphasis /= static_cast( this->m_TotalNumberOfRuns ); greyLevelNonuniformity /= static_cast( this->m_TotalNumberOfRuns ); runLengthNonuniformity /= static_cast( this->m_TotalNumberOfRuns ); lowGreyLevelRunEmphasis /= static_cast( this->m_TotalNumberOfRuns ); highGreyLevelRunEmphasis /= static_cast( this->m_TotalNumberOfRuns ); shortRunLowGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfRuns ); shortRunHighGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfRuns ); longRunLowGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfRuns ); longRunHighGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfRuns ); runPercentage = static_cast( this->m_TotalNumberOfRuns ) / static_cast( this->m_NumberOfVoxels ); numberOfRuns = static_cast( this->m_TotalNumberOfRuns ) ; + + greyLevelNonuniformityNormalized = greyLevelNonuniformity / static_cast(this->m_TotalNumberOfRuns); + runLengthNonuniformityNormalized = runLengthNonuniformity / static_cast(this->m_TotalNumberOfRuns); + } else { shortRunEmphasis = 0; longRunEmphasis = 0; greyLevelNonuniformity = 0; runLengthNonuniformity= 0; lowGreyLevelRunEmphasis = 0; highGreyLevelRunEmphasis = 0; shortRunLowGreyLevelEmphasis = 0; shortRunHighGreyLevelEmphasis= 0; longRunLowGreyLevelEmphasis = 0; longRunHighGreyLevelEmphasis = 0; runPercentage = 0; + + greyLevelNonuniformityNormalized = 0; + runLengthNonuniformityNormalized = 0; + numberOfRuns = static_cast( this->m_TotalNumberOfRuns ) ; } MeasurementObjectType* shortRunEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 0 ) ); shortRunEmphasisOutputObject->Set( shortRunEmphasis ); MeasurementObjectType* longRunEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 1 ) ); longRunEmphasisOutputObject->Set( longRunEmphasis ); MeasurementObjectType* greyLevelNonuniformityOutputObject = static_cast( this->ProcessObject::GetOutput( 2 ) ); greyLevelNonuniformityOutputObject->Set( greyLevelNonuniformity ); + MeasurementObjectType* greyLevelNonuniformityNormalizedOutputObject = + static_cast( this->ProcessObject::GetOutput( 15 ) ); + greyLevelNonuniformityNormalizedOutputObject->Set( greyLevelNonuniformityNormalized ); + + MeasurementObjectType* runLengthNonuniformityNormalizedOutputObject = + static_cast( this->ProcessObject::GetOutput( 16 ) ); + runLengthNonuniformityNormalizedOutputObject->Set( runLengthNonuniformityNormalized ); + MeasurementObjectType* runLengthNonuniformityOutputObject = static_cast( this->ProcessObject::GetOutput( 3 ) ); runLengthNonuniformityOutputObject->Set( runLengthNonuniformity ); MeasurementObjectType* lowGreyLevelRunEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 4 ) ); lowGreyLevelRunEmphasisOutputObject->Set( lowGreyLevelRunEmphasis ); MeasurementObjectType* highGreyLevelRunEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 5 ) ); highGreyLevelRunEmphasisOutputObject->Set( highGreyLevelRunEmphasis ); MeasurementObjectType* shortRunLowGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 6 ) ); shortRunLowGreyLevelEmphasisOutputObject->Set( shortRunLowGreyLevelEmphasis ); MeasurementObjectType* shortRunHighGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 7 ) ); shortRunHighGreyLevelEmphasisOutputObject->Set( shortRunHighGreyLevelEmphasis ); MeasurementObjectType* longRunLowGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 8 ) ); longRunLowGreyLevelEmphasisOutputObject->Set( longRunLowGreyLevelEmphasis ); MeasurementObjectType* longRunHighGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 9 ) ); longRunHighGreyLevelEmphasisOutputObject->Set( longRunHighGreyLevelEmphasis ); MeasurementObjectType* runPercentagesOutputObject = static_cast( this->ProcessObject::GetOutput( 10 ) ); runPercentagesOutputObject->Set( runPercentage ); MeasurementObjectType* numberOfRunsOutputObject = static_cast( this->ProcessObject::GetOutput( 11 ) ); numberOfRunsOutputObject->Set( numberOfRuns ); MeasurementObjectType* greyLevelVarianceOutputObject = static_cast( this->ProcessObject::GetOutput( 12 ) ); greyLevelVarianceOutputObject->Set( greyLevelVariance ); MeasurementObjectType* runLengthVarianceOutputObject = static_cast( this->ProcessObject::GetOutput( 13 ) ); runLengthVarianceOutputObject->Set( runLengthVariance ); MeasurementObjectType* runEntropyOutputObject = static_cast( this->ProcessObject::GetOutput( 14 ) ); runEntropyOutputObject->Set( runEntropy ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunEmphasisOutput() const { return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 0 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 1 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelNonuniformityOutput() const { return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 2 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthNonuniformityOutput() const { return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 3 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetLowGreyLevelRunEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 4 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetHighGreyLevelRunEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 5 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunLowGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 6 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunHighGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 7 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunLowGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 8 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunHighGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 9 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetRunPercentageOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 10 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetNumberOfRunsOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 11 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelVarianceOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 12 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthVarianceOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 13 ) ); } template const typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* EnhancedHistogramToRunLengthFeaturesFilter ::GetRunEntropyOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 14 ) ); } + template + const + typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* + EnhancedHistogramToRunLengthFeaturesFilter + ::GetGreyLevelNonuniformityNormalizedOutput() const + { + return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 15 ) ); + } + + template + const + typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementObjectType* + EnhancedHistogramToRunLengthFeaturesFilter + ::GetRunLengthNonuniformityNormalizedOutput() const + { + return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 16 ) ); + } + template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunEmphasis() const { return this->GetShortRunEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunEmphasis() const { return this->GetLongRunEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelNonuniformity() const { return this->GetGreyLevelNonuniformityOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthNonuniformity() const { return this->GetRunLengthNonuniformityOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetLowGreyLevelRunEmphasis() const { return this->GetLowGreyLevelRunEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetHighGreyLevelRunEmphasis() const { return this->GetHighGreyLevelRunEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunLowGreyLevelEmphasis() const { return this->GetShortRunLowGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetShortRunHighGreyLevelEmphasis() const { return this->GetShortRunHighGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunLowGreyLevelEmphasis() const { return this->GetLongRunLowGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetLongRunHighGreyLevelEmphasis() const { return this->GetLongRunHighGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetRunPercentage() const { return this->GetRunPercentageOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetNumberOfRuns() const { return this->GetNumberOfRunsOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetGreyLevelVariance() const { return this->GetGreyLevelVarianceOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetRunLengthVariance() const { return this->GetRunLengthVarianceOutput()->Get(); } template typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetRunEntropy() const { return this->GetRunEntropyOutput()->Get(); } + template + typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType + EnhancedHistogramToRunLengthFeaturesFilter + ::GetGreyLevelNonuniformityNormalized() const + { + return this->GetGreyLevelNonuniformityNormalizedOutput()->Get(); + } + template + typename EnhancedHistogramToRunLengthFeaturesFilter::MeasurementType + EnhancedHistogramToRunLengthFeaturesFilter + ::GetRunLengthNonuniformityNormalized() const + { + return this->GetRunLengthNonuniformityNormalizedOutput()->Get(); + } template typename EnhancedHistogramToRunLengthFeaturesFilter< THistogram>::MeasurementType EnhancedHistogramToRunLengthFeaturesFilter ::GetFeature( RunLengthFeatureName feature ) { switch( feature ) { case ShortRunEmphasis: return this->GetShortRunEmphasis(); case LongRunEmphasis: return this->GetLongRunEmphasis(); case GreyLevelNonuniformity: return this->GetGreyLevelNonuniformity(); + case GreyLevelNonuniformityNormalized: + return this->GetGreyLevelNonuniformityNormalized(); case RunLengthNonuniformity: return this->GetRunLengthNonuniformity(); + case RunLengthNonuniformityNormalized: + return this->GetRunLengthNonuniformityNormalized(); case LowGreyLevelRunEmphasis: return this->GetLowGreyLevelRunEmphasis(); case HighGreyLevelRunEmphasis: return this->GetHighGreyLevelRunEmphasis(); case ShortRunLowGreyLevelEmphasis: return this->GetShortRunLowGreyLevelEmphasis(); case ShortRunHighGreyLevelEmphasis: return this->GetShortRunHighGreyLevelEmphasis(); case LongRunLowGreyLevelEmphasis: return this->GetLongRunLowGreyLevelEmphasis(); case LongRunHighGreyLevelEmphasis: return this->GetLongRunHighGreyLevelEmphasis(); case RunPercentage: return this->GetRunPercentage(); case NumberOfRuns: return this->GetNumberOfRuns(); case GreyLevelVariance: return this->GetGreyLevelVariance(); case RunLengthVariance: return this->GetRunLengthVariance(); case RunEntropy: return this->GetRunEntropy(); default: return 0; } } template< typename THistogram> void EnhancedHistogramToRunLengthFeaturesFilter< THistogram>:: PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf( os,indent ); } } // end of namespace Statistics } // end of namespace itk #endif diff --git a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToSizeZoneFeaturesFilter.h b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToSizeZoneFeaturesFilter.h index a0fb584a3f..211ec6b406 100644 --- a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToSizeZoneFeaturesFilter.h +++ b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToSizeZoneFeaturesFilter.h @@ -1,230 +1,240 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ /*========================================================================= * * Copyright Insight Software Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef __itkEnhancedHistogramToSizeZoneFeaturesFilter_h #define __itkEnhancedHistogramToSizeZoneFeaturesFilter_h #include "itkHistogram.h" #include "itkMacro.h" #include "itkProcessObject.h" #include "itkSimpleDataObjectDecorator.h" namespace itk { namespace Statistics { /** \class EnhancedHistogramToSizeZoneFeaturesFilter * \brief This class computes texture feature coefficients from a grey level * Zone-length matrix. * * By default, Zone length features are computed for each spatial * direction and then averaged afterward, so it is possible to access the * standard deviations of the texture features. These values give a clue as * to texture anisotropy. However, doing this is much more work, because it * involved computing one for each offset given. To compute a single matrix * using the first offset, call FastCalculationsOn(). If this is called, * then the texture standard deviations will not be computed (and will be set * to zero), but texture computation will be much faster. * * This class is templated over the input histogram type. * * Print references: * M. M. Galloway. Texture analysis using gray level Zone lengths. Computer * Graphics and Image Processing, 4:172-179, 1975. * * A. Chu, C. M. Sehgal, and J. F. Greenleaf. Use of gray value distribution of * Zone lengths for texture analysis. Pattern Recognition Letters, 11:415-420, * 1990. * * B. R. Dasarathy and E. B. Holder. Image characterizations based on joint * gray-level Zone-length distributions. Pattern Recognition Letters, 12:490-502, * 1991. * * IJ article: http://hdl.handle.net/1926/1374 * * \sa ScalarImageToSizeZoneFeaturesFilter * \sa ScalarImageToSizeZoneMatrixFilter * \sa EnhancedHistogramToSizeZoneFeaturesFilter * * \author: Nick Tustison * \ingroup ITKStatistics */ template< typename THistogram > class EnhancedHistogramToSizeZoneFeaturesFilter : public ProcessObject { public: /** Standard typedefs */ typedef EnhancedHistogramToSizeZoneFeaturesFilter Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Zone-time type information (and related methods). */ itkTypeMacro( EnhancedHistogramToSizeZoneFeaturesFilter, ProcessObject ); /** standard New() method support */ itkNewMacro( Self ); typedef THistogram HistogramType; typedef typename HistogramType::Pointer HistogramPointer; typedef typename HistogramType::ConstPointer HistogramConstPointer; typedef typename HistogramType::MeasurementType MeasurementType; typedef typename HistogramType::MeasurementVectorType MeasurementVectorType; typedef typename HistogramType::IndexType IndexType; typedef typename HistogramType:: TotalAbsoluteFrequencyType FrequencyType; /** Method to Set/Get the input Histogram */ using Superclass::SetInput; void SetInput ( const HistogramType * histogram ); const HistogramType * GetInput() const; /** Smart Pointer type to a DataObject. */ typedef DataObject::Pointer DataObjectPointer; /** Type of DataObjects used for scalar outputs */ typedef SimpleDataObjectDecorator MeasurementObjectType; /** Methods to return the short Zone emphasis. */ MeasurementType GetSmallZoneEmphasis() const; const MeasurementObjectType* GetSmallZoneEmphasisOutput() const; /** Methods to return the long Zone emphasis. */ MeasurementType GetLargeZoneEmphasis() const; const MeasurementObjectType* GetLargeZoneEmphasisOutput() const; /** Methods to return the grey level nonuniformity. */ MeasurementType GetGreyLevelNonuniformity() const; const MeasurementObjectType* GetGreyLevelNonuniformityOutput() const; + /** Methods to return the grey level nonuniformity normalized. */ + MeasurementType GetGreyLevelNonuniformityNormalized() const; + const MeasurementObjectType* GetGreyLevelNonuniformityNormalizedOutput() const; + /** Methods to return the Zone length nonuniformity. */ MeasurementType GetSizeZoneNonuniformity() const; const MeasurementObjectType* GetSizeZoneNonuniformityOutput() const; + /** Methods to return the Zone length nonuniformity normalized. */ + MeasurementType GetSizeZoneNonuniformityNormalized() const; + const MeasurementObjectType* GetSizeZoneNonuniformityNormalizedOutput() const; + /** Methods to return the low grey level Zone emphasis. */ MeasurementType GetLowGreyLevelZoneEmphasis() const; const MeasurementObjectType* GetLowGreyLevelZoneEmphasisOutput() const; /** Methods to return the high grey level Zone emphasis. */ MeasurementType GetHighGreyLevelZoneEmphasis() const; const MeasurementObjectType* GetHighGreyLevelZoneEmphasisOutput() const; /** Methods to return the short Zone low grey level Zone emphasis. */ MeasurementType GetSmallZoneLowGreyLevelEmphasis() const; const MeasurementObjectType* GetSmallZoneLowGreyLevelEmphasisOutput() const; /** Methods to return the short Zone high grey level Zone emphasis. */ MeasurementType GetSmallZoneHighGreyLevelEmphasis() const; const MeasurementObjectType* GetSmallZoneHighGreyLevelEmphasisOutput() const; /** Methods to return the long Zone low grey level Zone emphasis. */ MeasurementType GetLargeZoneLowGreyLevelEmphasis() const; const MeasurementObjectType* GetLargeZoneLowGreyLevelEmphasisOutput() const; /** Methods to return the long Zone high grey level Zone emphasis. */ MeasurementType GetLargeZoneHighGreyLevelEmphasis() const; const MeasurementObjectType* GetLargeZoneHighGreyLevelEmphasisOutput() const; /** Methods to return the long Zone high grey level Zone emphasis. */ MeasurementType GetZonePercentage() const; const MeasurementObjectType* GetZonePercentageOutput() const; /** Methods to return the long Zone high grey level Zone emphasis. */ MeasurementType GetNumberOfZones() const; const MeasurementObjectType* GetNumberOfZonesOutput() const; /** Methods to return the grey level variance. */ MeasurementType GetGreyLevelVariance() const; const MeasurementObjectType* GetGreyLevelVarianceOutput() const; /** Methods to return the Zone length variance. */ MeasurementType GetSizeZoneVariance() const; const MeasurementObjectType* GetSizeZoneVarianceOutput() const; /** Methods to return the Zone entropy. */ MeasurementType GetZoneEntropy() const; const MeasurementObjectType* GetZoneEntropyOutput() const; itkGetMacro( TotalNumberOfZones, unsigned long ); itkGetConstMacro(NumberOfVoxels, unsigned long); itkSetMacro(NumberOfVoxels, unsigned long); /** Zone-length feature types */ typedef enum { SmallZoneEmphasis, LargeZoneEmphasis, GreyLevelNonuniformity, + GreyLevelNonuniformityNormalized, SizeZoneNonuniformity, + SizeZoneNonuniformityNormalized, LowGreyLevelZoneEmphasis, HighGreyLevelZoneEmphasis, SmallZoneLowGreyLevelEmphasis, SmallZoneHighGreyLevelEmphasis, LargeZoneLowGreyLevelEmphasis, LargeZoneHighGreyLevelEmphasis, ZonePercentage, GreyLevelVariance, SizeZoneVariance, ZoneEntropy } SizeZoneFeatureName; /** convenience method to access the Zone length values */ MeasurementType GetFeature( SizeZoneFeatureName name ); protected: EnhancedHistogramToSizeZoneFeaturesFilter(); ~EnhancedHistogramToSizeZoneFeaturesFilter() {}; virtual void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; /** Make a DataObject to be used for output output. */ typedef ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType; using Superclass::MakeOutput; virtual DataObjectPointer MakeOutput( DataObjectPointerArraySizeType ) ITK_OVERRIDE; virtual void GenerateData() ITK_OVERRIDE; private: EnhancedHistogramToSizeZoneFeaturesFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented unsigned long m_TotalNumberOfZones; unsigned long m_NumberOfVoxels; }; } // end of namespace Statistics } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkEnhancedHistogramToSizeZoneFeaturesFilter.hxx" #endif #endif diff --git a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToSizeZoneFeaturesFilter.hxx b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToSizeZoneFeaturesFilter.hxx index e9dca786c2..07629da8a2 100644 --- a/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToSizeZoneFeaturesFilter.hxx +++ b/Modules/Classification/CLUtilities/include/itkEnhancedHistogramToSizeZoneFeaturesFilter.hxx @@ -1,611 +1,669 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ /*========================================================================= * * Copyright Insight Software Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef __itkEnhancedHistogramToSizeZoneFeaturesFilter_hxx #define __itkEnhancedHistogramToSizeZoneFeaturesFilter_hxx #include "itkEnhancedHistogramToSizeZoneFeaturesFilter.h" #include "itkNumericTraits.h" #include "vnl/vnl_math.h" namespace itk { namespace Statistics { //constructor template EnhancedHistogramToSizeZoneFeaturesFilter ::EnhancedHistogramToSizeZoneFeaturesFilter() : m_NumberOfVoxels(1) { this->ProcessObject::SetNumberOfRequiredInputs( 1 ); // allocate the data objects for the outputs which are // just decorators real types for( unsigned int i = 0; i < 15; i++ ) { this->ProcessObject::SetNthOutput( i, this->MakeOutput( i ) ); } } template void EnhancedHistogramToSizeZoneFeaturesFilter< THistogram> ::SetInput( const HistogramType *histogram ) { this->ProcessObject::SetNthInput( 0, const_cast( histogram ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::HistogramType * EnhancedHistogramToSizeZoneFeaturesFilter< THistogram> ::GetInput() const { if ( this->GetNumberOfInputs() < 1 ) { return ITK_NULLPTR; } return itkDynamicCastInDebugMode(this->ProcessObject::GetInput( 0 ) ); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::DataObjectPointer EnhancedHistogramToSizeZoneFeaturesFilter ::MakeOutput( DataObjectPointerArraySizeType itkNotUsed( idx ) ) { return MeasurementObjectType::New().GetPointer(); } template void EnhancedHistogramToSizeZoneFeaturesFilter< THistogram>:: GenerateData( void ) { const HistogramType * inputHistogram = this->GetInput(); this->m_TotalNumberOfZones = static_cast ( inputHistogram->GetTotalFrequency() ); MeasurementType SmallZoneEmphasis = NumericTraits::ZeroValue(); MeasurementType LargeZoneEmphasis = NumericTraits::ZeroValue(); MeasurementType greyLevelNonuniformity = NumericTraits::ZeroValue(); MeasurementType SizeZoneNonuniformity = NumericTraits::ZeroValue(); MeasurementType lowGreyLevelZoneEmphasis = NumericTraits::ZeroValue(); MeasurementType highGreyLevelZoneEmphasis = NumericTraits::ZeroValue(); MeasurementType SmallZoneLowGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType SmallZoneHighGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType LargeZoneLowGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType LargeZoneHighGreyLevelEmphasis = NumericTraits::ZeroValue(); MeasurementType ZonePercentage = NumericTraits::ZeroValue(); MeasurementType numberOfZones = NumericTraits::ZeroValue(); //Added 15.07.2016 MeasurementType greyLevelVariance = NumericTraits::ZeroValue(); MeasurementType SizeZoneVariance = NumericTraits::ZeroValue(); MeasurementType ZoneEntropy = NumericTraits::ZeroValue(); + //Added 09.09.2016 + MeasurementType greyLevelNonuniformityNormalized = NumericTraits::ZeroValue(); + MeasurementType SizeZoneNonuniformityNormalized = NumericTraits::ZeroValue(); + + vnl_vector greyLevelNonuniformityVector( inputHistogram->GetSize()[0], 0.0 ); vnl_vector SizeZoneNonuniformityVector( inputHistogram->GetSize()[1], 0.0 ); typedef typename HistogramType::ConstIterator HistogramIterator; double mu_i = 0.0; double mu_j = 0.0; //Calculate the means. for ( HistogramIterator hit = inputHistogram->Begin(); hit != inputHistogram->End(); ++hit ) { MeasurementType frequency = hit.GetFrequency(); if ( frequency == 0 ) { continue; } MeasurementVectorType measurement = hit.GetMeasurementVector(); IndexType index = hit.GetIndex(); int value = floor(measurement[0] + 0.5); int count = measurement[1]; double i = value; double j = count; double p_ij = frequency / m_TotalNumberOfZones; mu_i += i * p_ij; mu_j += j * p_ij; } //Calculate the other features. const double log2 = std::log(2.0); int totNumOfVoxelsUsed = 0; for ( HistogramIterator hit = inputHistogram->Begin(); hit != inputHistogram->End(); ++hit ) { MeasurementType frequency = hit.GetFrequency(); if ( frequency == 0 ) { continue; } MeasurementVectorType measurement = hit.GetMeasurementVector(); IndexType index = hit.GetIndex(); // inputHistogram->GetIndex( hit.GetInstanceIdentifier() ); int value = floor(measurement[0] + 0.5); int count = measurement[1]; double i = value; double j = count; double i2 = static_cast( i*i ); double j2 = static_cast( j*j ); double p_ij = frequency / m_TotalNumberOfZones; greyLevelVariance += ((i - mu_i) * (i - mu_i) * p_ij); SizeZoneVariance += ((j - mu_j) * (j - mu_j) * p_ij); ZoneEntropy -= ( p_ij > 0.0001 ) ? p_ij *std::log(p_ij) / log2 : 0; // Traditional measures SmallZoneEmphasis += ( frequency / j2 ); LargeZoneEmphasis += ( frequency * j2 ); greyLevelNonuniformityVector[index[0]] += frequency; SizeZoneNonuniformityVector[index[1]] += frequency; // measures from Chu et al. - lowGreyLevelZoneEmphasis += ( frequency / i2 ); + lowGreyLevelZoneEmphasis += (i2 > 0.0001) ? ( frequency / i2 ) : 0; highGreyLevelZoneEmphasis += ( frequency * i2 ); // measures from Dasarathy and Holder - SmallZoneLowGreyLevelEmphasis += ( frequency / ( i2 * j2 ) ); - SmallZoneHighGreyLevelEmphasis += ( frequency * i2 / j2 ); - LargeZoneLowGreyLevelEmphasis += ( frequency * j2 / i2 ); + SmallZoneLowGreyLevelEmphasis += ((i2 * j2) > 0.0001) ? ( frequency / ( i2 * j2 ) ) : 0; + SmallZoneHighGreyLevelEmphasis += (j2 > 0.0001) ? ( frequency * i2 / j2 ) : 0; + LargeZoneLowGreyLevelEmphasis += (i2 = 0.0001) ? ( frequency * j2 / i2 ) : 0; LargeZoneHighGreyLevelEmphasis += ( frequency * i2 * j2 ); totNumOfVoxelsUsed += (count * frequency); } greyLevelNonuniformity = greyLevelNonuniformityVector.squared_magnitude(); SizeZoneNonuniformity = SizeZoneNonuniformityVector.squared_magnitude(); // Normalize all measures by the total number of Zones m_TotalNumberOfZones = totNumOfVoxelsUsed; if (this->m_TotalNumberOfZones > 0) { SmallZoneEmphasis /= static_cast( this->m_TotalNumberOfZones ); LargeZoneEmphasis /= static_cast( this->m_TotalNumberOfZones ); greyLevelNonuniformity /= static_cast( this->m_TotalNumberOfZones ); SizeZoneNonuniformity /= static_cast( this->m_TotalNumberOfZones ); lowGreyLevelZoneEmphasis /= static_cast( this->m_TotalNumberOfZones ); highGreyLevelZoneEmphasis /= static_cast( this->m_TotalNumberOfZones ); SmallZoneLowGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfZones ); SmallZoneHighGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfZones ); LargeZoneLowGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfZones ); LargeZoneHighGreyLevelEmphasis /= static_cast( this->m_TotalNumberOfZones ); ZonePercentage = static_cast( this->m_TotalNumberOfZones ) / static_cast( this->m_NumberOfVoxels ); numberOfZones = static_cast( this->m_TotalNumberOfZones ) ; + + greyLevelNonuniformityNormalized = greyLevelNonuniformity / static_cast(this->m_TotalNumberOfZones); + SizeZoneNonuniformityNormalized = SizeZoneNonuniformity / static_cast(this->m_TotalNumberOfZones); + } else { - SmallZoneEmphasis = 0; - LargeZoneEmphasis = 0; - greyLevelNonuniformity = 0; - SizeZoneNonuniformity= 0; + SmallZoneEmphasis = 0; + LargeZoneEmphasis = 0; + greyLevelNonuniformity = 0; + SizeZoneNonuniformity = 0; + greyLevelNonuniformityNormalized = 0; + SizeZoneNonuniformityNormalized = 0; lowGreyLevelZoneEmphasis = 0; highGreyLevelZoneEmphasis = 0; SmallZoneLowGreyLevelEmphasis = 0; SmallZoneHighGreyLevelEmphasis= 0; - LargeZoneLowGreyLevelEmphasis = 0; - LargeZoneHighGreyLevelEmphasis = 0; + LargeZoneLowGreyLevelEmphasis = 0; + LargeZoneHighGreyLevelEmphasis= 0; ZonePercentage = 0; numberOfZones = static_cast( this->m_TotalNumberOfZones ) ; } MeasurementObjectType* SmallZoneEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 0 ) ); SmallZoneEmphasisOutputObject->Set( SmallZoneEmphasis ); MeasurementObjectType* LargeZoneEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 1 ) ); LargeZoneEmphasisOutputObject->Set( LargeZoneEmphasis ); MeasurementObjectType* greyLevelNonuniformityOutputObject = static_cast( this->ProcessObject::GetOutput( 2 ) ); greyLevelNonuniformityOutputObject->Set( greyLevelNonuniformity ); MeasurementObjectType* SizeZoneNonuniformityOutputObject = static_cast( this->ProcessObject::GetOutput( 3 ) ); SizeZoneNonuniformityOutputObject->Set( SizeZoneNonuniformity ); MeasurementObjectType* lowGreyLevelZoneEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 4 ) ); lowGreyLevelZoneEmphasisOutputObject->Set( lowGreyLevelZoneEmphasis ); MeasurementObjectType* highGreyLevelZoneEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 5 ) ); highGreyLevelZoneEmphasisOutputObject->Set( highGreyLevelZoneEmphasis ); MeasurementObjectType* SmallZoneLowGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 6 ) ); SmallZoneLowGreyLevelEmphasisOutputObject->Set( SmallZoneLowGreyLevelEmphasis ); MeasurementObjectType* SmallZoneHighGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 7 ) ); SmallZoneHighGreyLevelEmphasisOutputObject->Set( SmallZoneHighGreyLevelEmphasis ); MeasurementObjectType* LargeZoneLowGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 8 ) ); LargeZoneLowGreyLevelEmphasisOutputObject->Set( LargeZoneLowGreyLevelEmphasis ); MeasurementObjectType* LargeZoneHighGreyLevelEmphasisOutputObject = static_cast( this->ProcessObject::GetOutput( 9 ) ); LargeZoneHighGreyLevelEmphasisOutputObject->Set( LargeZoneHighGreyLevelEmphasis ); MeasurementObjectType* ZonePercentagesOutputObject = static_cast( this->ProcessObject::GetOutput( 10 ) ); ZonePercentagesOutputObject->Set( ZonePercentage ); MeasurementObjectType* numberOfZonesOutputObject = static_cast( this->ProcessObject::GetOutput( 11 ) ); numberOfZonesOutputObject->Set( numberOfZones ); MeasurementObjectType* greyLevelVarianceOutputObject = static_cast( this->ProcessObject::GetOutput( 12 ) ); greyLevelVarianceOutputObject->Set( greyLevelVariance ); MeasurementObjectType* SizeZoneVarianceOutputObject = static_cast( this->ProcessObject::GetOutput( 13 ) ); SizeZoneVarianceOutputObject->Set( SizeZoneVariance ); MeasurementObjectType* ZoneEntropyOutputObject = static_cast( this->ProcessObject::GetOutput( 14 ) ); ZoneEntropyOutputObject->Set( ZoneEntropy ); + + MeasurementObjectType* greyLevelNonuniformityNormalizedOutputObject = + static_cast( this->ProcessObject::GetOutput( 15 ) ); + greyLevelNonuniformityNormalizedOutputObject->Set( greyLevelNonuniformityNormalized ); + + MeasurementObjectType* SizeZoneNonuniformityNormalizedOutputObject = + static_cast( this->ProcessObject::GetOutput( 16 ) ); + SizeZoneNonuniformityNormalizedOutputObject->Set( SizeZoneNonuniformityNormalized ); + } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetSmallZoneEmphasisOutput() const { return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 0 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetLargeZoneEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 1 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetGreyLevelNonuniformityOutput() const { return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 2 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetSizeZoneNonuniformityOutput() const { return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 3 ) ); } + template + const + typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* + EnhancedHistogramToSizeZoneFeaturesFilter + ::GetGreyLevelNonuniformityNormalizedOutput() const + { + return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 15 ) ); + } + + template + const + typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* + EnhancedHistogramToSizeZoneFeaturesFilter + ::GetSizeZoneNonuniformityNormalizedOutput() const + { + return itkDynamicCastInDebugMode(this->ProcessObject::GetOutput( 16 ) ); + } + template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetLowGreyLevelZoneEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 4 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetHighGreyLevelZoneEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 5 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetSmallZoneLowGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 6 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetSmallZoneHighGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 7 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetLargeZoneLowGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 8 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetLargeZoneHighGreyLevelEmphasisOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 9 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetZonePercentageOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 10 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetNumberOfZonesOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 11 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetGreyLevelVarianceOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 12 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetSizeZoneVarianceOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 13 ) ); } template const typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementObjectType* EnhancedHistogramToSizeZoneFeaturesFilter ::GetZoneEntropyOutput() const { return itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 14 ) ); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetSmallZoneEmphasis() const { return this->GetSmallZoneEmphasisOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetLargeZoneEmphasis() const { return this->GetLargeZoneEmphasisOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetGreyLevelNonuniformity() const { return this->GetGreyLevelNonuniformityOutput()->Get(); } + template + typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType + EnhancedHistogramToSizeZoneFeaturesFilter + ::GetGreyLevelNonuniformityNormalized() const + { + return this->GetGreyLevelNonuniformityNormalizedOutput()->Get(); + } + template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetSizeZoneNonuniformity() const { return this->GetSizeZoneNonuniformityOutput()->Get(); } + template + typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType + EnhancedHistogramToSizeZoneFeaturesFilter + ::GetSizeZoneNonuniformityNormalized() const + { + return this->GetSizeZoneNonuniformityNormalizedOutput()->Get(); + } + template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetLowGreyLevelZoneEmphasis() const { return this->GetLowGreyLevelZoneEmphasisOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetHighGreyLevelZoneEmphasis() const { return this->GetHighGreyLevelZoneEmphasisOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetSmallZoneLowGreyLevelEmphasis() const { return this->GetSmallZoneLowGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetSmallZoneHighGreyLevelEmphasis() const { return this->GetSmallZoneHighGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetLargeZoneLowGreyLevelEmphasis() const { return this->GetLargeZoneLowGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetLargeZoneHighGreyLevelEmphasis() const { return this->GetLargeZoneHighGreyLevelEmphasisOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetZonePercentage() const { return this->GetZonePercentageOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetNumberOfZones() const { return this->GetNumberOfZonesOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetGreyLevelVariance() const { return this->GetGreyLevelVarianceOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetSizeZoneVariance() const { return this->GetSizeZoneVarianceOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetZoneEntropy() const { return this->GetZoneEntropyOutput()->Get(); } template typename EnhancedHistogramToSizeZoneFeaturesFilter< THistogram>::MeasurementType EnhancedHistogramToSizeZoneFeaturesFilter ::GetFeature( SizeZoneFeatureName feature ) { switch( feature ) { case SmallZoneEmphasis: return this->GetSmallZoneEmphasis(); case LargeZoneEmphasis: return this->GetLargeZoneEmphasis(); case GreyLevelNonuniformity: return this->GetGreyLevelNonuniformity(); + case GreyLevelNonuniformityNormalized: + return this->GetGreyLevelNonuniformityNormalized(); case SizeZoneNonuniformity: return this->GetSizeZoneNonuniformity(); + case SizeZoneNonuniformityNormalized: + return this->GetSizeZoneNonuniformityNormalized(); case LowGreyLevelZoneEmphasis: return this->GetLowGreyLevelZoneEmphasis(); case HighGreyLevelZoneEmphasis: return this->GetHighGreyLevelZoneEmphasis(); case SmallZoneLowGreyLevelEmphasis: return this->GetSmallZoneLowGreyLevelEmphasis(); case SmallZoneHighGreyLevelEmphasis: return this->GetSmallZoneHighGreyLevelEmphasis(); case LargeZoneLowGreyLevelEmphasis: return this->GetLargeZoneLowGreyLevelEmphasis(); case LargeZoneHighGreyLevelEmphasis: return this->GetLargeZoneHighGreyLevelEmphasis(); case ZonePercentage: return this->GetZonePercentage(); case GreyLevelVariance: return this->GetGreyLevelVariance(); case SizeZoneVariance: return this->GetSizeZoneVariance(); case ZoneEntropy: return this->GetZoneEntropy(); default: return 0; } } template< typename THistogram> void EnhancedHistogramToSizeZoneFeaturesFilter< THistogram>:: PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf( os,indent ); } } // end of namespace Statistics } // end of namespace itk #endif diff --git a/Modules/Classification/CLUtilities/include/itkEnhancedScalarImageToRunLengthFeaturesFilter.hxx b/Modules/Classification/CLUtilities/include/itkEnhancedScalarImageToRunLengthFeaturesFilter.hxx index bda0fccfc2..b4de6e656c 100644 --- a/Modules/Classification/CLUtilities/include/itkEnhancedScalarImageToRunLengthFeaturesFilter.hxx +++ b/Modules/Classification/CLUtilities/include/itkEnhancedScalarImageToRunLengthFeaturesFilter.hxx @@ -1,410 +1,412 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ /*========================================================================= * * Copyright Insight Software Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef __itkEnhancedScalarImageToRunLengthFeaturesFilter_hxx #define __itkEnhancedScalarImageToRunLengthFeaturesFilter_hxx #include "itkEnhancedScalarImageToRunLengthFeaturesFilter.h" #include "itkNeighborhood.h" #include #include "vnl/vnl_math.h" namespace itk { namespace Statistics { template EnhancedScalarImageToRunLengthFeaturesFilter ::EnhancedScalarImageToRunLengthFeaturesFilter() { this->SetNumberOfRequiredInputs( 1 ); this->SetNumberOfRequiredOutputs( 1 ); for( int i = 0; i < 2; ++i ) { this->ProcessObject::SetNthOutput( i, this->MakeOutput( i ) ); } this->m_RunLengthMatrixGenerator = RunLengthMatrixFilterType::New(); this->m_FeatureMeans = FeatureValueVector::New(); this->m_FeatureStandardDeviations = FeatureValueVector::New(); // Set the requested features to the default value: // {Energy, Entropy, InverseDifferenceMoment, Inertia, ClusterShade, // ClusterProminence} FeatureNameVectorPointer requestedFeatures = FeatureNameVector::New(); // can't directly set this->m_RequestedFeatures since it is const! requestedFeatures->push_back( RunLengthFeaturesFilterType::ShortRunEmphasis ); requestedFeatures->push_back( RunLengthFeaturesFilterType::LongRunEmphasis ); requestedFeatures->push_back( RunLengthFeaturesFilterType::GreyLevelNonuniformity ); + requestedFeatures->push_back( RunLengthFeaturesFilterType::GreyLevelNonuniformityNormalized ); requestedFeatures->push_back( RunLengthFeaturesFilterType::RunLengthNonuniformity ); + requestedFeatures->push_back( RunLengthFeaturesFilterType::RunLengthNonuniformityNormalized ); requestedFeatures->push_back( RunLengthFeaturesFilterType::LowGreyLevelRunEmphasis ); requestedFeatures->push_back( RunLengthFeaturesFilterType::HighGreyLevelRunEmphasis ); requestedFeatures->push_back( RunLengthFeaturesFilterType::ShortRunLowGreyLevelEmphasis ); requestedFeatures->push_back( RunLengthFeaturesFilterType::ShortRunHighGreyLevelEmphasis ); requestedFeatures->push_back( RunLengthFeaturesFilterType::LongRunLowGreyLevelEmphasis ); requestedFeatures->push_back( RunLengthFeaturesFilterType::LongRunHighGreyLevelEmphasis ); requestedFeatures->push_back( 20 ); this->SetRequestedFeatures( requestedFeatures ); // Set the offset directions to their defaults: half of all the possible // directions 1 pixel away. (The other half is included by symmetry.) // We use a neighborhood iterator to calculate the appropriate offsets. typedef Neighborhood NeighborhoodType; NeighborhoodType hood; hood.SetRadius( 1 ); // select all "previous" neighbors that are face+edge+vertex // connected to the current pixel. do not include the center pixel. unsigned int centerIndex = hood.GetCenterNeighborhoodIndex(); OffsetVectorPointer offsets = OffsetVector::New(); for( unsigned int d = 0; d < centerIndex; d++ ) { OffsetType offset = hood.GetOffset( d ); offsets->push_back( offset ); } this->SetOffsets( offsets ); this->m_FastCalculations = false; } template typename EnhancedScalarImageToRunLengthFeaturesFilter ::DataObjectPointer EnhancedScalarImageToRunLengthFeaturesFilter ::MakeOutput( DataObjectPointerArraySizeType itkNotUsed(idx) ) { return FeatureValueVectorDataObjectType::New().GetPointer(); } template void EnhancedScalarImageToRunLengthFeaturesFilter ::GenerateData(void) { if ( this->m_FastCalculations ) { this->FastCompute(); } else { this->FullCompute(); } } template void EnhancedScalarImageToRunLengthFeaturesFilter ::FullCompute() { int numOffsets = this->m_Offsets->size(); int numFeatures = this->m_RequestedFeatures->size(); double **features; features = new double *[numOffsets]; for( int i = 0; i < numOffsets; i++ ) { features[i] = new double[numFeatures]; } unsigned long numberOfVoxels = 0; ImageRegionConstIterator voxelCountIter(this->GetMaskImage(),this->GetMaskImage()->GetLargestPossibleRegion()); while ( ! voxelCountIter.IsAtEnd() ) { if (voxelCountIter.Get() > 0) ++numberOfVoxels; ++voxelCountIter; } // For each offset, calculate each feature typename OffsetVector::ConstIterator offsetIt; int offsetNum, featureNum; typedef typename RunLengthFeaturesFilterType::RunLengthFeatureName InternalRunLengthFeatureName; for( offsetIt = this->m_Offsets->Begin(), offsetNum = 0; offsetIt != this->m_Offsets->End(); offsetIt++, offsetNum++ ) { this->m_RunLengthMatrixGenerator->SetOffset( offsetIt.Value() ); this->m_RunLengthMatrixGenerator->Update(); typename RunLengthFeaturesFilterType::Pointer runLengthMatrixCalculator = RunLengthFeaturesFilterType::New(); runLengthMatrixCalculator->SetInput( this->m_RunLengthMatrixGenerator->GetOutput() ); runLengthMatrixCalculator->SetNumberOfVoxels(numberOfVoxels); runLengthMatrixCalculator->Update(); typename FeatureNameVector::ConstIterator fnameIt; for( fnameIt = this->m_RequestedFeatures->Begin(), featureNum = 0; fnameIt != this->m_RequestedFeatures->End(); fnameIt++, featureNum++ ) { features[offsetNum][featureNum] = runLengthMatrixCalculator->GetFeature( ( InternalRunLengthFeatureName )fnameIt.Value() ); } } // Now get the mean and deviaton of each feature across the offsets. this->m_FeatureMeans->clear(); this->m_FeatureStandardDeviations->clear(); double *tempFeatureMeans = new double[numFeatures]; double *tempFeatureDevs = new double[numFeatures]; /*Compute incremental mean and SD, a la Knuth, "The Art of Computer Programming, Volume 2: Seminumerical Algorithms", section 4.2.2. Compute mean and standard deviation using the recurrence relation: M(1) = x(1), M(k) = M(k-1) + (x(k) - M(k-1) ) / k S(1) = 0, S(k) = S(k-1) + (x(k) - M(k-1)) * (x(k) - M(k)) for 2 <= k <= n, then sigma = std::sqrt(S(n) / n) (or divide by n-1 for sample SD instead of population SD). */ // Set up the initial conditions (k = 1) for( featureNum = 0; featureNum < numFeatures; featureNum++ ) { tempFeatureMeans[featureNum] = features[0][featureNum]; tempFeatureDevs[featureNum] = 0; } // Run through the recurrence (k = 2 ... N) for( offsetNum = 1; offsetNum < numOffsets; offsetNum++ ) { int k = offsetNum + 1; for( featureNum = 0; featureNum < numFeatures; featureNum++ ) { double M_k_minus_1 = tempFeatureMeans[featureNum]; double S_k_minus_1 = tempFeatureDevs[featureNum]; double x_k = features[offsetNum][featureNum]; double M_k = M_k_minus_1 + ( x_k - M_k_minus_1 ) / k; double S_k = S_k_minus_1 + ( x_k - M_k_minus_1 ) * ( x_k - M_k ); tempFeatureMeans[featureNum] = M_k; tempFeatureDevs[featureNum] = S_k; } } for( featureNum = 0; featureNum < numFeatures; featureNum++ ) { tempFeatureDevs[featureNum] = std::sqrt( tempFeatureDevs[featureNum] / numOffsets ); this->m_FeatureMeans->push_back( tempFeatureMeans[featureNum] ); this->m_FeatureStandardDeviations->push_back( tempFeatureDevs[featureNum] ); } FeatureValueVectorDataObjectType *meanOutputObject = itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 0 ) ); meanOutputObject->Set( this->m_FeatureMeans ); FeatureValueVectorDataObjectType *standardDeviationOutputObject = itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 1 ) ); standardDeviationOutputObject->Set( this->m_FeatureStandardDeviations ); delete[] tempFeatureMeans; delete[] tempFeatureDevs; for( int i = 0; i < numOffsets; i++ ) { delete[] features[i]; } delete[] features; } template void EnhancedScalarImageToRunLengthFeaturesFilter ::FastCompute() { // Compute the feature for the first offset typename OffsetVector::ConstIterator offsetIt = this->m_Offsets->Begin(); this->m_RunLengthMatrixGenerator->SetOffset( offsetIt.Value() ); this->m_RunLengthMatrixGenerator->Update(); typename RunLengthFeaturesFilterType::Pointer runLengthMatrixCalculator = RunLengthFeaturesFilterType::New(); runLengthMatrixCalculator->SetInput( this->m_RunLengthMatrixGenerator->GetOutput() ); runLengthMatrixCalculator->Update(); typedef typename RunLengthFeaturesFilterType::RunLengthFeatureName InternalRunLengthFeatureName; this->m_FeatureMeans->clear(); this->m_FeatureStandardDeviations->clear(); typename FeatureNameVector::ConstIterator fnameIt; for( fnameIt = this->m_RequestedFeatures->Begin(); fnameIt != this->m_RequestedFeatures->End(); fnameIt++ ) { this->m_FeatureMeans->push_back( runLengthMatrixCalculator->GetFeature( ( InternalRunLengthFeatureName )fnameIt.Value() ) ); this->m_FeatureStandardDeviations->push_back( 0.0 ); } FeatureValueVectorDataObjectType *meanOutputObject = itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 0 ) ); meanOutputObject->Set( this->m_FeatureMeans ); FeatureValueVectorDataObjectType *standardDeviationOutputObject = itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 1 ) ); standardDeviationOutputObject->Set( this->m_FeatureStandardDeviations ); } template void EnhancedScalarImageToRunLengthFeaturesFilter ::SetInput( const ImageType *image ) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput( 0, const_cast( image ) ); this->m_RunLengthMatrixGenerator->SetInput( image ); } template void EnhancedScalarImageToRunLengthFeaturesFilter ::SetNumberOfBinsPerAxis( unsigned int numberOfBins ) { itkDebugMacro( "setting NumberOfBinsPerAxis to " << numberOfBins ); this->m_RunLengthMatrixGenerator->SetNumberOfBinsPerAxis( numberOfBins ); this->Modified(); } template void EnhancedScalarImageToRunLengthFeaturesFilter ::SetPixelValueMinMax( PixelType min, PixelType max ) { itkDebugMacro( "setting Min to " << min << "and Max to " << max ); this->m_RunLengthMatrixGenerator->SetPixelValueMinMax( min, max ); this->Modified(); } template void EnhancedScalarImageToRunLengthFeaturesFilter ::SetDistanceValueMinMax( double min, double max ) { itkDebugMacro( "setting Min to " << min << "and Max to " << max ); this->m_RunLengthMatrixGenerator->SetDistanceValueMinMax( min, max ); this->Modified(); } template void EnhancedScalarImageToRunLengthFeaturesFilter ::SetMaskImage( const ImageType *image ) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput( 1, const_cast< ImageType * >( image ) ); this->m_RunLengthMatrixGenerator->SetMaskImage( image ); } template const TImage * EnhancedScalarImageToRunLengthFeaturesFilter ::GetInput() const { if ( this->GetNumberOfInputs() < 1 ) { return ITK_NULLPTR; } return static_cast( this->ProcessObject::GetInput( 0 ) ); } template const typename EnhancedScalarImageToRunLengthFeaturesFilter ::FeatureValueVectorDataObjectType * EnhancedScalarImageToRunLengthFeaturesFilter ::GetFeatureMeansOutput() const { return itkDynamicCastInDebugMode (this->ProcessObject::GetOutput( 0 ) ); } template const typename EnhancedScalarImageToRunLengthFeaturesFilter ::FeatureValueVectorDataObjectType * EnhancedScalarImageToRunLengthFeaturesFilter ::GetFeatureStandardDeviationsOutput() const { return itkDynamicCastInDebugMode< const FeatureValueVectorDataObjectType * > ( this->ProcessObject::GetOutput( 1 ) ); } template const TImage * EnhancedScalarImageToRunLengthFeaturesFilter ::GetMaskImage() const { if ( this->GetNumberOfInputs() < 2 ) { return ITK_NULLPTR; } return static_cast< const ImageType *>( this->ProcessObject::GetInput( 1 ) ); } template void EnhancedScalarImageToRunLengthFeaturesFilter ::SetInsidePixelValue( PixelType insidePixelValue ) { itkDebugMacro( "setting InsidePixelValue to " << insidePixelValue ); this->m_RunLengthMatrixGenerator->SetInsidePixelValue( insidePixelValue ); this->Modified(); } template void EnhancedScalarImageToRunLengthFeaturesFilter ::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "RequestedFeatures: " << this->GetRequestedFeatures() << std::endl; os << indent << "FeatureStandardDeviations: " << this->GetFeatureStandardDeviations() << std::endl; os << indent << "FastCalculations: " << this->GetFastCalculations() << std::endl; os << indent << "Offsets: " << this->GetOffsets() << std::endl; os << indent << "FeatureMeans: " << this->GetFeatureMeans() << std::endl; } } // end of namespace Statistics } // end of namespace itk -#endif \ No newline at end of file +#endif diff --git a/Modules/Classification/CLUtilities/include/itkEnhancedScalarImageToSizeZoneFeaturesFilter.hxx b/Modules/Classification/CLUtilities/include/itkEnhancedScalarImageToSizeZoneFeaturesFilter.hxx index c5fb14b406..13a0a2e58f 100644 --- a/Modules/Classification/CLUtilities/include/itkEnhancedScalarImageToSizeZoneFeaturesFilter.hxx +++ b/Modules/Classification/CLUtilities/include/itkEnhancedScalarImageToSizeZoneFeaturesFilter.hxx @@ -1,410 +1,412 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ /*========================================================================= * * Copyright Insight Software Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef __itkEnhancedScalarImageToSizeZoneFeaturesFilter_hxx #define __itkEnhancedScalarImageToSizeZoneFeaturesFilter_hxx #include "itkEnhancedScalarImageToSizeZoneFeaturesFilter.h" #include "itkNeighborhood.h" #include #include "vnl/vnl_math.h" namespace itk { namespace Statistics { template EnhancedScalarImageToSizeZoneFeaturesFilter ::EnhancedScalarImageToSizeZoneFeaturesFilter() { this->SetNumberOfRequiredInputs( 1 ); this->SetNumberOfRequiredOutputs( 1 ); for( int i = 0; i < 2; ++i ) { this->ProcessObject::SetNthOutput( i, this->MakeOutput( i ) ); } this->m_SizeZoneMatrixGenerator = SizeZoneMatrixFilterType::New(); this->m_FeatureMeans = FeatureValueVector::New(); this->m_FeatureStandardDeviations = FeatureValueVector::New(); // Set the requested features to the default value: // {Energy, Entropy, InverseDifferenceMoment, Inertia, ClusterShade, // ClusterProminence} FeatureNameVectorPointer requestedFeatures = FeatureNameVector::New(); // can't directly set this->m_RequestedFeatures since it is const! requestedFeatures->push_back( SizeZoneFeaturesFilterType::SmallZoneEmphasis ); requestedFeatures->push_back( SizeZoneFeaturesFilterType::LargeZoneEmphasis ); requestedFeatures->push_back( SizeZoneFeaturesFilterType::GreyLevelNonuniformity ); + requestedFeatures->push_back( SizeZoneFeaturesFilterType::GreyLevelNonuniformityNormalized ); requestedFeatures->push_back( SizeZoneFeaturesFilterType::SizeZoneNonuniformity ); + requestedFeatures->push_back( SizeZoneFeaturesFilterType::SizeZoneNonuniformityNormalized ); requestedFeatures->push_back( SizeZoneFeaturesFilterType::LowGreyLevelZoneEmphasis ); requestedFeatures->push_back( SizeZoneFeaturesFilterType::HighGreyLevelZoneEmphasis ); requestedFeatures->push_back( SizeZoneFeaturesFilterType::SmallZoneLowGreyLevelEmphasis ); requestedFeatures->push_back( SizeZoneFeaturesFilterType::SmallZoneHighGreyLevelEmphasis ); requestedFeatures->push_back( SizeZoneFeaturesFilterType::LargeZoneLowGreyLevelEmphasis ); requestedFeatures->push_back( SizeZoneFeaturesFilterType::LargeZoneHighGreyLevelEmphasis ); requestedFeatures->push_back( 20 ); this->SetRequestedFeatures( requestedFeatures ); // Set the offset directions to their defaults: half of all the possible // directions 1 pixel away. (The other half is included by symmetry.) // We use a neighborhood iterator to calculate the appropriate offsets. typedef Neighborhood NeighborhoodType; NeighborhoodType hood; hood.SetRadius( 1 ); // select all "previous" neighbors that are face+edge+vertex // connected to the current pixel. do not include the center pixel. unsigned int centerIndex = hood.GetCenterNeighborhoodIndex(); OffsetVectorPointer offsets = OffsetVector::New(); for( unsigned int d = 0; d < centerIndex; d++ ) { OffsetType offset = hood.GetOffset( d ); offsets->push_back( offset ); } this->SetOffsets( offsets ); this->m_FastCalculations = false; } template typename EnhancedScalarImageToSizeZoneFeaturesFilter ::DataObjectPointer EnhancedScalarImageToSizeZoneFeaturesFilter ::MakeOutput( DataObjectPointerArraySizeType itkNotUsed(idx) ) { return FeatureValueVectorDataObjectType::New().GetPointer(); } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::GenerateData(void) { if ( this->m_FastCalculations ) { this->FastCompute(); } else { this->FullCompute(); } } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::FullCompute() { int numOffsets = this->m_Offsets->size(); int numFeatures = this->m_RequestedFeatures->size(); double **features; features = new double *[numOffsets]; for( int i = 0; i < numOffsets; i++ ) { features[i] = new double[numFeatures]; } unsigned long numberOfVoxels = 0; ImageRegionConstIterator voxelCountIter(this->GetMaskImage(),this->GetMaskImage()->GetLargestPossibleRegion()); while ( ! voxelCountIter.IsAtEnd() ) { if (voxelCountIter.Get() > 0) ++numberOfVoxels; ++voxelCountIter; } // For each offset, calculate each feature typename OffsetVector::ConstIterator offsetIt; int offsetNum, featureNum; typedef typename SizeZoneFeaturesFilterType::SizeZoneFeatureName InternalSizeZoneFeatureName; for( offsetIt = this->m_Offsets->Begin(), offsetNum = 0; offsetIt != this->m_Offsets->End(); offsetIt++, offsetNum++ ) { this->m_SizeZoneMatrixGenerator->SetOffset( offsetIt.Value() ); this->m_SizeZoneMatrixGenerator->Update(); typename SizeZoneFeaturesFilterType::Pointer SizeZoneMatrixCalculator = SizeZoneFeaturesFilterType::New(); SizeZoneMatrixCalculator->SetInput( this->m_SizeZoneMatrixGenerator->GetOutput() ); SizeZoneMatrixCalculator->SetNumberOfVoxels(numberOfVoxels); SizeZoneMatrixCalculator->Update(); typename FeatureNameVector::ConstIterator fnameIt; for( fnameIt = this->m_RequestedFeatures->Begin(), featureNum = 0; fnameIt != this->m_RequestedFeatures->End(); fnameIt++, featureNum++ ) { features[offsetNum][featureNum] = SizeZoneMatrixCalculator->GetFeature( ( InternalSizeZoneFeatureName )fnameIt.Value() ); } } // Now get the mean and deviaton of each feature across the offsets. this->m_FeatureMeans->clear(); this->m_FeatureStandardDeviations->clear(); double *tempFeatureMeans = new double[numFeatures]; double *tempFeatureDevs = new double[numFeatures]; /*Compute incremental mean and SD, a la Knuth, "The Art of Computer Programming, Volume 2: Seminumerical Algorithms", section 4.2.2. Compute mean and standard deviation using the recurrence relation: M(1) = x(1), M(k) = M(k-1) + (x(k) - M(k-1) ) / k S(1) = 0, S(k) = S(k-1) + (x(k) - M(k-1)) * (x(k) - M(k)) for 2 <= k <= n, then sigma = std::sqrt(S(n) / n) (or divide by n-1 for sample SD instead of population SD). */ // Set up the initial conditions (k = 1) for( featureNum = 0; featureNum < numFeatures; featureNum++ ) { tempFeatureMeans[featureNum] = features[0][featureNum]; tempFeatureDevs[featureNum] = 0; } // Zone through the recurrence (k = 2 ... N) for( offsetNum = 1; offsetNum < numOffsets; offsetNum++ ) { int k = offsetNum + 1; for( featureNum = 0; featureNum < numFeatures; featureNum++ ) { double M_k_minus_1 = tempFeatureMeans[featureNum]; double S_k_minus_1 = tempFeatureDevs[featureNum]; double x_k = features[offsetNum][featureNum]; double M_k = M_k_minus_1 + ( x_k - M_k_minus_1 ) / k; double S_k = S_k_minus_1 + ( x_k - M_k_minus_1 ) * ( x_k - M_k ); tempFeatureMeans[featureNum] = M_k; tempFeatureDevs[featureNum] = S_k; } } for( featureNum = 0; featureNum < numFeatures; featureNum++ ) { tempFeatureDevs[featureNum] = std::sqrt( tempFeatureDevs[featureNum] / numOffsets ); this->m_FeatureMeans->push_back( tempFeatureMeans[featureNum] ); this->m_FeatureStandardDeviations->push_back( tempFeatureDevs[featureNum] ); } FeatureValueVectorDataObjectType *meanOutputObject = itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 0 ) ); meanOutputObject->Set( this->m_FeatureMeans ); FeatureValueVectorDataObjectType *standardDeviationOutputObject = itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 1 ) ); standardDeviationOutputObject->Set( this->m_FeatureStandardDeviations ); delete[] tempFeatureMeans; delete[] tempFeatureDevs; for( int i = 0; i < numOffsets; i++ ) { delete[] features[i]; } delete[] features; } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::FastCompute() { // Compute the feature for the first offset typename OffsetVector::ConstIterator offsetIt = this->m_Offsets->Begin(); this->m_SizeZoneMatrixGenerator->SetOffset( offsetIt.Value() ); this->m_SizeZoneMatrixGenerator->Update(); typename SizeZoneFeaturesFilterType::Pointer SizeZoneMatrixCalculator = SizeZoneFeaturesFilterType::New(); SizeZoneMatrixCalculator->SetInput( this->m_SizeZoneMatrixGenerator->GetOutput() ); SizeZoneMatrixCalculator->Update(); typedef typename SizeZoneFeaturesFilterType::SizeZoneFeatureName InternalSizeZoneFeatureName; this->m_FeatureMeans->clear(); this->m_FeatureStandardDeviations->clear(); typename FeatureNameVector::ConstIterator fnameIt; for( fnameIt = this->m_RequestedFeatures->Begin(); fnameIt != this->m_RequestedFeatures->End(); fnameIt++ ) { this->m_FeatureMeans->push_back( SizeZoneMatrixCalculator->GetFeature( ( InternalSizeZoneFeatureName )fnameIt.Value() ) ); this->m_FeatureStandardDeviations->push_back( 0.0 ); } FeatureValueVectorDataObjectType *meanOutputObject = itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 0 ) ); meanOutputObject->Set( this->m_FeatureMeans ); FeatureValueVectorDataObjectType *standardDeviationOutputObject = itkDynamicCastInDebugMode( this->ProcessObject::GetOutput( 1 ) ); standardDeviationOutputObject->Set( this->m_FeatureStandardDeviations ); } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::SetInput( const ImageType *image ) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput( 0, const_cast( image ) ); this->m_SizeZoneMatrixGenerator->SetInput( image ); } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::SetNumberOfBinsPerAxis( unsigned int numberOfBins ) { itkDebugMacro( "setting NumberOfBinsPerAxis to " << numberOfBins ); this->m_SizeZoneMatrixGenerator->SetNumberOfBinsPerAxis( numberOfBins ); this->Modified(); } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::SetPixelValueMinMax( PixelType min, PixelType max ) { itkDebugMacro( "setting Min to " << min << "and Max to " << max ); this->m_SizeZoneMatrixGenerator->SetPixelValueMinMax( min, max ); this->Modified(); } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::SetDistanceValueMinMax( double min, double max ) { itkDebugMacro( "setting Min to " << min << "and Max to " << max ); this->m_SizeZoneMatrixGenerator->SetDistanceValueMinMax( min, max ); this->Modified(); } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::SetMaskImage( const ImageType *image ) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput( 1, const_cast< ImageType * >( image ) ); this->m_SizeZoneMatrixGenerator->SetMaskImage( image ); } template const TImage * EnhancedScalarImageToSizeZoneFeaturesFilter ::GetInput() const { if ( this->GetNumberOfInputs() < 1 ) { return ITK_NULLPTR; } return static_cast( this->ProcessObject::GetInput( 0 ) ); } template const typename EnhancedScalarImageToSizeZoneFeaturesFilter ::FeatureValueVectorDataObjectType * EnhancedScalarImageToSizeZoneFeaturesFilter ::GetFeatureMeansOutput() const { return itkDynamicCastInDebugMode (this->ProcessObject::GetOutput( 0 ) ); } template const typename EnhancedScalarImageToSizeZoneFeaturesFilter ::FeatureValueVectorDataObjectType * EnhancedScalarImageToSizeZoneFeaturesFilter ::GetFeatureStandardDeviationsOutput() const { return itkDynamicCastInDebugMode< const FeatureValueVectorDataObjectType * > ( this->ProcessObject::GetOutput( 1 ) ); } template const TImage * EnhancedScalarImageToSizeZoneFeaturesFilter ::GetMaskImage() const { if ( this->GetNumberOfInputs() < 2 ) { return ITK_NULLPTR; } return static_cast< const ImageType *>( this->ProcessObject::GetInput( 1 ) ); } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::SetInsidePixelValue( PixelType insidePixelValue ) { itkDebugMacro( "setting InsidePixelValue to " << insidePixelValue ); this->m_SizeZoneMatrixGenerator->SetInsidePixelValue( insidePixelValue ); this->Modified(); } template void EnhancedScalarImageToSizeZoneFeaturesFilter ::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "RequestedFeatures: " << this->GetRequestedFeatures() << std::endl; os << indent << "FeatureStandardDeviations: " << this->GetFeatureStandardDeviations() << std::endl; os << indent << "FastCalculations: " << this->GetFastCalculations() << std::endl; os << indent << "Offsets: " << this->GetOffsets() << std::endl; os << indent << "FeatureMeans: " << this->GetFeatureMeans() << std::endl; } } // end of namespace Statistics } // end of namespace itk #endif diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGrayLevelRunLength.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGrayLevelRunLength.cpp index 2dcf34b024..ba1e7ea78c 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGrayLevelRunLength.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGrayLevelRunLength.cpp @@ -1,237 +1,247 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include // MITK #include #include #include // ITK #include #include // STL #include template void CalculateGrayLevelRunLengthFeatures(itk::Image* itkImage, mitk::Image::Pointer mask, mitk::GIFGrayLevelRunLength::FeatureListType & featureList, mitk::GIFGrayLevelRunLength::ParameterStruct params) { typedef itk::Image ImageType; typedef itk::Image MaskType; typedef itk::Statistics::EnhancedScalarImageToRunLengthFeaturesFilter FilterType; typedef itk::MinimumMaximumImageCalculator MinMaxComputerType; typedef typename FilterType::RunLengthFeaturesFilterType TextureFilterType; typename MaskType::Pointer maskImage = MaskType::New(); mitk::CastToItkImage(mask, maskImage); typename FilterType::Pointer filter = FilterType::New(); typename FilterType::OffsetVector::Pointer newOffset = FilterType::OffsetVector::New(); auto oldOffsets = filter->GetOffsets(); auto oldOffsetsIterator = oldOffsets->Begin(); while (oldOffsetsIterator != oldOffsets->End()) { bool continueOuterLoop = false; typename FilterType::OffsetType offset = oldOffsetsIterator->Value(); for (unsigned int i = 0; i < VImageDimension; ++i) { if (params.m_Direction == i + 2 && offset[i] != 0) { continueOuterLoop = true; } } if (params.m_Direction == 1) { offset[0] = 0; offset[1] = 0; offset[2] = 1; newOffset->push_back(offset); break; } oldOffsetsIterator++; if (continueOuterLoop) continue; newOffset->push_back(offset); } filter->SetOffsets(newOffset); // All features are required typename FilterType::FeatureNameVectorPointer requestedFeatures = FilterType::FeatureNameVector::New(); requestedFeatures->push_back(TextureFilterType::ShortRunEmphasis); requestedFeatures->push_back(TextureFilterType::LongRunEmphasis); requestedFeatures->push_back(TextureFilterType::GreyLevelNonuniformity); + requestedFeatures->push_back(TextureFilterType::GreyLevelNonuniformityNormalized); requestedFeatures->push_back(TextureFilterType::RunLengthNonuniformity); + requestedFeatures->push_back(TextureFilterType::RunLengthNonuniformityNormalized); requestedFeatures->push_back(TextureFilterType::LowGreyLevelRunEmphasis); requestedFeatures->push_back(TextureFilterType::HighGreyLevelRunEmphasis); requestedFeatures->push_back(TextureFilterType::ShortRunLowGreyLevelEmphasis); requestedFeatures->push_back(TextureFilterType::ShortRunHighGreyLevelEmphasis); requestedFeatures->push_back(TextureFilterType::LongRunLowGreyLevelEmphasis); requestedFeatures->push_back(TextureFilterType::LongRunHighGreyLevelEmphasis); requestedFeatures->push_back(TextureFilterType::RunPercentage); requestedFeatures->push_back(TextureFilterType::NumberOfRuns); requestedFeatures->push_back(TextureFilterType::GreyLevelVariance); requestedFeatures->push_back(TextureFilterType::RunLengthVariance); requestedFeatures->push_back(TextureFilterType::RunEntropy); typename MinMaxComputerType::Pointer minMaxComputer = MinMaxComputerType::New(); minMaxComputer->SetImage(itkImage); minMaxComputer->Compute(); filter->SetInput(itkImage); filter->SetMaskImage(maskImage); filter->SetRequestedFeatures(requestedFeatures); int rangeOfPixels = params.m_Range; if (rangeOfPixels < 2) rangeOfPixels = 256; if (params.m_UseCtRange) { filter->SetPixelValueMinMax((TPixel)(-1024.5),(TPixel)(3096.5)); filter->SetNumberOfBinsPerAxis(3096.5+1024.5); } else { filter->SetPixelValueMinMax(minMaxComputer->GetMinimum(),minMaxComputer->GetMaximum()); filter->SetNumberOfBinsPerAxis(rangeOfPixels); } filter->SetDistanceValueMinMax(0,rangeOfPixels); filter->Update(); auto featureMeans = filter->GetFeatureMeans (); auto featureStd = filter->GetFeatureStandardDeviations(); std::ostringstream ss; ss << rangeOfPixels; std::string strRange = ss.str(); for (std::size_t i = 0; i < featureMeans->size(); ++i) { switch (i) { case TextureFilterType::ShortRunEmphasis : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") ShortRunEmphasis Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") ShortRunEmphasis Std.",featureStd->ElementAt(i))); break; case TextureFilterType::LongRunEmphasis : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") LongRunEmphasis Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") LongRunEmphasis Std.",featureStd->ElementAt(i))); break; case TextureFilterType::GreyLevelNonuniformity : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") GreyLevelNonuniformity Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") GreyLevelNonuniformity Std.",featureStd->ElementAt(i))); break; + case TextureFilterType::GreyLevelNonuniformityNormalized : + featureList.push_back(std::make_pair("RunLength. ("+ strRange+") GreyLevelNonuniformityNormalized Means",featureMeans->ElementAt(i))); + featureList.push_back(std::make_pair("RunLength. ("+ strRange+") GreyLevelNonuniformityNormalized Std.",featureStd->ElementAt(i))); + break; case TextureFilterType::RunLengthNonuniformity : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunLengthNonuniformity Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunLengthNonuniformity Std.",featureStd->ElementAt(i))); break; + case TextureFilterType::RunLengthNonuniformityNormalized : + featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunLengthNonuniformityNormalized Means",featureMeans->ElementAt(i))); + featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunLengthNonuniformityNormalized Std.",featureStd->ElementAt(i))); + break; case TextureFilterType::LowGreyLevelRunEmphasis : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") LowGreyLevelRunEmphasis Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") LowGreyLevelRunEmphasis Std.",featureStd->ElementAt(i))); break; case TextureFilterType::HighGreyLevelRunEmphasis : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") HighGreyLevelRunEmphasis Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") HighGreyLevelRunEmphasis Std.",featureStd->ElementAt(i))); break; case TextureFilterType::ShortRunLowGreyLevelEmphasis : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") ShortRunLowGreyLevelEmphasis Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") ShortRunLowGreyLevelEmphasis Std.",featureStd->ElementAt(i))); break; case TextureFilterType::ShortRunHighGreyLevelEmphasis : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") ShortRunHighGreyLevelEmphasis Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") ShortRunHighGreyLevelEmphasis Std.",featureStd->ElementAt(i))); break; case TextureFilterType::LongRunLowGreyLevelEmphasis : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") LongRunLowGreyLevelEmphasis Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") LongRunLowGreyLevelEmphasis Std.",featureStd->ElementAt(i))); break; case TextureFilterType::LongRunHighGreyLevelEmphasis : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") LongRunHighGreyLevelEmphasis Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") LongRunHighGreyLevelEmphasis Std.",featureStd->ElementAt(i))); break; case TextureFilterType::RunPercentage : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunPercentage Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunPercentage Std.",featureStd->ElementAt(i))); break; case TextureFilterType::NumberOfRuns : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") NumberOfRuns Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") NumberOfRuns Std.",featureStd->ElementAt(i))); break; case TextureFilterType::GreyLevelVariance : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") GreyLevelVariance Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") GreyLevelVariance Std.",featureStd->ElementAt(i))); break; case TextureFilterType::RunLengthVariance : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunLengthVariance Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunLengthVariance Std.",featureStd->ElementAt(i))); break; case TextureFilterType::RunEntropy : featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunEntropy Means",featureMeans->ElementAt(i))); featureList.push_back(std::make_pair("RunLength. ("+ strRange+") RunEntropy Std.",featureStd->ElementAt(i))); break; default: break; } } } mitk::GIFGrayLevelRunLength::GIFGrayLevelRunLength(): m_Range(1.0), m_UseCtRange(false), m_Direction(0) { } mitk::GIFGrayLevelRunLength::FeatureListType mitk::GIFGrayLevelRunLength::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { FeatureListType featureList; ParameterStruct params; params.m_UseCtRange=m_UseCtRange; params.m_Range = m_Range; params.m_Direction = m_Direction; AccessByItk_3(image, CalculateGrayLevelRunLengthFeatures, mask, featureList,params); return featureList; } mitk::GIFGrayLevelRunLength::FeatureNameListType mitk::GIFGrayLevelRunLength::GetFeatureNames() { FeatureNameListType featureList; featureList.push_back("RunLength. ShortRunEmphasis Means"); featureList.push_back("RunLength. ShortRunEmphasis Std."); featureList.push_back("RunLength. LongRunEmphasis Means"); featureList.push_back("RunLength. LongRunEmphasis Std."); featureList.push_back("RunLength. GreyLevelNonuniformity Means"); featureList.push_back("RunLength. GreyLevelNonuniformity Std."); featureList.push_back("RunLength. RunLengthNonuniformity Means"); featureList.push_back("RunLength. RunLengthNonuniformity Std."); featureList.push_back("RunLength. LowGreyLevelRunEmphasis Means"); featureList.push_back("RunLength. LowGreyLevelRunEmphasis Std."); featureList.push_back("RunLength. HighGreyLevelRunEmphasis Means"); featureList.push_back("RunLength. HighGreyLevelRunEmphasis Std."); featureList.push_back("RunLength. ShortRunLowGreyLevelEmphasis Means"); featureList.push_back("RunLength. ShortRunLowGreyLevelEmphasis Std."); featureList.push_back("RunLength. ShortRunHighGreyLevelEmphasis Means"); featureList.push_back("RunLength. ShortRunHighGreyLevelEmphasis Std."); featureList.push_back("RunLength. LongRunHighGreyLevelEmphasis Means"); featureList.push_back("RunLength. LongRunHighGreyLevelEmphasis Std."); return featureList; } diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGrayLevelSizeZone.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGrayLevelSizeZone.cpp index 10a7592630..8319aadb6b 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGrayLevelSizeZone.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFGrayLevelSizeZone.cpp @@ -1,218 +1,226 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include // MITK #include #include #include // ITK #include #include // STL #include template void CalculateGrayLevelSizeZoneFeatures(itk::Image* itkImage, mitk::Image::Pointer mask, mitk::GIFGrayLevelSizeZone::FeatureListType & featureList, mitk::GIFGrayLevelSizeZone::ParameterStruct params) { typedef itk::Image ImageType; typedef itk::Image MaskType; typedef itk::Statistics::EnhancedScalarImageToSizeZoneFeaturesFilter FilterType; typedef itk::MinimumMaximumImageCalculator MinMaxComputerType; typedef typename FilterType::SizeZoneFeaturesFilterType TextureFilterType; typename MaskType::Pointer maskImage = MaskType::New(); mitk::CastToItkImage(mask, maskImage); typename FilterType::Pointer filter = FilterType::New(); typename FilterType::OffsetVector::Pointer newOffset = FilterType::OffsetVector::New(); auto oldOffsets = filter->GetOffsets(); auto oldOffsetsIterator = oldOffsets->Begin(); while (oldOffsetsIterator != oldOffsets->End()) { bool continueOuterLoop = false; typename FilterType::OffsetType offset = oldOffsetsIterator->Value(); for (unsigned int i = 0; i < VImageDimension; ++i) { if (params.m_Direction == i + 2 && offset[i] != 0) { continueOuterLoop = true; } } if (params.m_Direction == 1) { offset[0] = 0; offset[1] = 0; offset[2] = 1; newOffset->push_back(offset); break; } oldOffsetsIterator++; if (continueOuterLoop) continue; newOffset->push_back(offset); } filter->SetOffsets(newOffset); // All features are required typename FilterType::FeatureNameVectorPointer requestedFeatures = FilterType::FeatureNameVector::New(); requestedFeatures->push_back(TextureFilterType::SmallZoneEmphasis); requestedFeatures->push_back(TextureFilterType::LargeZoneEmphasis); requestedFeatures->push_back(TextureFilterType::GreyLevelNonuniformity); + requestedFeatures->push_back(TextureFilterType::GreyLevelNonuniformityNormalized); requestedFeatures->push_back(TextureFilterType::SizeZoneNonuniformity); + requestedFeatures->push_back(TextureFilterType::SizeZoneNonuniformityNormalized); requestedFeatures->push_back(TextureFilterType::LowGreyLevelZoneEmphasis); requestedFeatures->push_back(TextureFilterType::HighGreyLevelZoneEmphasis); requestedFeatures->push_back(TextureFilterType::SmallZoneLowGreyLevelEmphasis); requestedFeatures->push_back(TextureFilterType::SmallZoneHighGreyLevelEmphasis); requestedFeatures->push_back(TextureFilterType::LargeZoneLowGreyLevelEmphasis); requestedFeatures->push_back(TextureFilterType::LargeZoneHighGreyLevelEmphasis); requestedFeatures->push_back(TextureFilterType::ZonePercentage); requestedFeatures->push_back(TextureFilterType::GreyLevelVariance); requestedFeatures->push_back(TextureFilterType::SizeZoneVariance); requestedFeatures->push_back(TextureFilterType::ZoneEntropy); typename MinMaxComputerType::Pointer minMaxComputer = MinMaxComputerType::New(); minMaxComputer->SetImage(itkImage); minMaxComputer->Compute(); filter->SetInput(itkImage); filter->SetMaskImage(maskImage); filter->SetRequestedFeatures(requestedFeatures); int rangeOfPixels = params.m_Range; if (rangeOfPixels < 2) rangeOfPixels = 256; if (params.m_UseCtRange) { filter->SetPixelValueMinMax((TPixel)(-1024.5),(TPixel)(3096.5)); filter->SetNumberOfBinsPerAxis(3096.5+1024.5); } else { filter->SetPixelValueMinMax(minMaxComputer->GetMinimum(),minMaxComputer->GetMaximum()); filter->SetNumberOfBinsPerAxis(rangeOfPixels); } filter->SetDistanceValueMinMax(0,rangeOfPixels); filter->Update(); auto featureMeans = filter->GetFeatureMeans (); auto featureStd = filter->GetFeatureStandardDeviations(); std::ostringstream ss; ss << rangeOfPixels; std::string strRange = ss.str(); for (std::size_t i = 0; i < featureMeans->size(); ++i) { switch (i) { case TextureFilterType::SmallZoneEmphasis : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") SmallZoneEmphasis Means",featureMeans->ElementAt(i))); break; case TextureFilterType::LargeZoneEmphasis : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") LargeZoneEmphasis Means",featureMeans->ElementAt(i))); break; case TextureFilterType::GreyLevelNonuniformity : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") GreyLevelNonuniformity Means",featureMeans->ElementAt(i))); break; + case TextureFilterType::GreyLevelNonuniformityNormalized : + featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") GreyLevelNonuniformityNormalized Means",featureMeans->ElementAt(i))); + break; case TextureFilterType::SizeZoneNonuniformity : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") SizeZoneNonuniformity Means",featureMeans->ElementAt(i))); break; + case TextureFilterType::SizeZoneNonuniformityNormalized : + featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") SizeZoneNonuniformityNormalized Means",featureMeans->ElementAt(i))); + break; case TextureFilterType::LowGreyLevelZoneEmphasis : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") LowGreyLevelZoneEmphasis Means",featureMeans->ElementAt(i))); break; case TextureFilterType::HighGreyLevelZoneEmphasis : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") HighGreyLevelZoneEmphasis Means",featureMeans->ElementAt(i))); break; case TextureFilterType::SmallZoneLowGreyLevelEmphasis : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") SmallZoneLowGreyLevelEmphasis Means",featureMeans->ElementAt(i))); break; case TextureFilterType::SmallZoneHighGreyLevelEmphasis : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") SmallZoneHighGreyLevelEmphasis Means",featureMeans->ElementAt(i))); break; case TextureFilterType::LargeZoneLowGreyLevelEmphasis : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") LargeZoneLowGreyLevelEmphasis Means",featureMeans->ElementAt(i))); break; case TextureFilterType::LargeZoneHighGreyLevelEmphasis : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") LargeZoneHighGreyLevelEmphasis Means",featureMeans->ElementAt(i))); break; case TextureFilterType::ZonePercentage : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") ZonePercentage Means",featureMeans->ElementAt(i))); break; case TextureFilterType::GreyLevelVariance : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") GreyLevelVariance Means",featureMeans->ElementAt(i))); break; case TextureFilterType::SizeZoneVariance : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") SizeZoneVariance Means",featureMeans->ElementAt(i))); break; case TextureFilterType::ZoneEntropy : featureList.push_back(std::make_pair("SizeZone. ("+ strRange+") ZoneEntropy Means",featureMeans->ElementAt(i))); break; default: break; } } } mitk::GIFGrayLevelSizeZone::GIFGrayLevelSizeZone(): m_Range(1.0), m_UseCtRange(false), m_Direction(0) { } mitk::GIFGrayLevelSizeZone::FeatureListType mitk::GIFGrayLevelSizeZone::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { FeatureListType featureList; ParameterStruct params; params.m_UseCtRange=m_UseCtRange; params.m_Range = m_Range; params.m_Direction = m_Direction; AccessByItk_3(image, CalculateGrayLevelSizeZoneFeatures, mask, featureList,params); return featureList; } mitk::GIFGrayLevelSizeZone::FeatureNameListType mitk::GIFGrayLevelSizeZone::GetFeatureNames() { FeatureNameListType featureList; featureList.push_back("SizeZone. SmallZoneEmphasis Means"); featureList.push_back("SizeZone. SmallZoneEmphasis Std."); featureList.push_back("SizeZone. LargeZoneEmphasis Means"); featureList.push_back("SizeZone. LargeZoneEmphasis Std."); featureList.push_back("SizeZone. GreyLevelNonuniformity Means"); featureList.push_back("SizeZone. GreyLevelNonuniformity Std."); featureList.push_back("SizeZone. SizeZoneNonuniformity Means"); featureList.push_back("SizeZone. SizeZoneNonuniformity Std."); featureList.push_back("SizeZone. LowGreyLevelZoneEmphasis Means"); featureList.push_back("SizeZone. LowGreyLevelZoneEmphasis Std."); featureList.push_back("SizeZone. HighGreyLevelZoneEmphasis Means"); featureList.push_back("SizeZone. HighGreyLevelZoneEmphasis Std."); featureList.push_back("SizeZone. SmallZoneLowGreyLevelEmphasis Means"); featureList.push_back("SizeZone. SmallZoneLowGreyLevelEmphasis Std."); featureList.push_back("SizeZone. SmallZoneHighGreyLevelEmphasis Means"); featureList.push_back("SizeZone. SmallZoneHighGreyLevelEmphasis Std."); featureList.push_back("SizeZone. LargeZoneHighGreyLevelEmphasis Means"); featureList.push_back("SizeZone. LargeZoneHighGreyLevelEmphasis Std."); return featureList; }