Skip to content

Commit badec6c

Browse files
committed
ENH: Use BinaryFunctor for "digitializing" input image
Use a thread filter to perform digitizing and masking of the input image into histograms bins. Created a class scoped functor to perform the per-pixel operation.
1 parent 950d181 commit badec6c

File tree

2 files changed

+85
-28
lines changed

2 files changed

+85
-28
lines changed

include/itkCoocurrenceTextureFeaturesImageFilter.h

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,11 @@ class ITK_TEMPLATE_EXPORT CoocurrenceTextureFeaturesImageFilter:public ImageToIm
100100

101101
typedef TInputImage InputImageType;
102102
typedef TOutputImage OutputImageType;
103+
typedef TInputImage MaskImageType;
104+
typedef TInputImage DigitalisedImageType;
103105

104106
typedef typename InputImageType::PixelType PixelType;
107+
typedef typename MaskImageType::PixelType MaskPixelType;
105108
typedef typename InputImageType::IndexType IndexType;
106109
typedef typename InputImageType::PointType PointType;
107110

@@ -226,7 +229,8 @@ class ITK_TEMPLATE_EXPORT CoocurrenceTextureFeaturesImageFilter:public ImageToIm
226229
virtual void UpdateOutputInformation() ITK_OVERRIDE;
227230

228231
private:
229-
typename InputImageType::Pointer m_DigitalisedInputImageg;
232+
typename DigitalisedImageType::Pointer m_DigitalisedInputImageg;
233+
230234
NeighborhoodRadiusType m_NeighborhoodRadius;
231235
OffsetVectorPointer m_Offsets;
232236
unsigned int m_NumberOfBinsPerAxis;
@@ -236,6 +240,62 @@ class ITK_TEMPLATE_EXPORT CoocurrenceTextureFeaturesImageFilter:public ImageToIm
236240
typename TInputImage::SpacingType m_Spacing;
237241
bool m_Normalize;
238242

243+
244+
struct PreProcessingFunctor
245+
{
246+
PreProcessingFunctor()
247+
: m_NumberOfBinsPerAxis(256),
248+
m_MaskValue(1),
249+
m_Min(NumericTraits<PixelType>::min()),
250+
m_Max(NumericTraits<PixelType>::max()){}
251+
252+
PreProcessingFunctor(unsigned int numberOfBinsPerAxis,
253+
PixelType maskValue,
254+
PixelType min,
255+
PixelType max)
256+
: m_NumberOfBinsPerAxis(numberOfBinsPerAxis),
257+
m_MaskValue(maskValue),
258+
m_Min(min),
259+
m_Max(max){}
260+
261+
~PreProcessingFunctor() {}
262+
263+
bool operator!=(const PreProcessingFunctor& other) const
264+
{
265+
return (m_NumberOfBinsPerAxis != other.m_NumberOfBinsPerAxis)
266+
|| (m_MaskValue != other.m_MaskValue)
267+
|| (m_Min != other.m_Min)
268+
|| (m_Max != other.m_Max);
269+
}
270+
271+
bool operator==(const PreProcessingFunctor & other) const
272+
{
273+
return !( *this != other );
274+
}
275+
276+
inline typename DigitalisedImageType::PixelType operator()(const MaskPixelType & maskPixel,
277+
const PixelType & inputPixel) const
278+
{
279+
if(maskPixel != m_MaskValue)
280+
{
281+
return this->m_Min - 10;
282+
}
283+
else if (inputPixel < this->m_Min || inputPixel >= m_Max)
284+
{
285+
return m_Min - 1;
286+
}
287+
else
288+
{
289+
return (inputPixel - m_Min)/((m_Max-m_Min)/ (float)m_NumberOfBinsPerAxis);
290+
}
291+
}
292+
293+
unsigned int m_NumberOfBinsPerAxis;
294+
295+
PixelType m_MaskValue;
296+
PixelType m_Min;
297+
PixelType m_Max;
298+
};
239299
};
240300
} // end of namespace Statistics
241301
} // end of namespace itk

include/itkCoocurrenceTextureFeaturesImageFilter.hxx

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "itkCoocurrenceTextureFeaturesImageFilter.h"
2222
#include "itkRegionOfInterestImageFilter.h"
2323
#include "itkNeighborhoodAlgorithm.h"
24+
#include "itkBinaryFunctorImageFilter.h"
2425

2526
namespace itk
2627
{
@@ -77,35 +78,31 @@ void
7778
CoocurrenceTextureFeaturesImageFilter<TInputImage, TOutputImage>
7879
::BeforeThreadedGenerateData()
7980
{
80-
const InputImageType * maskPointer = this->GetMaskImage();
81-
this->m_DigitalisedInputImageg = InputImageType::New();
82-
this->m_DigitalisedInputImageg->SetRegions(this->GetInput()->GetRequestedRegion());
83-
this->m_DigitalisedInputImageg->CopyInformation(this->GetInput());
84-
this->m_DigitalisedInputImageg->Allocate();
85-
typedef itk::ImageRegionIterator< InputImageType> IteratorType;
86-
IteratorType digitIt( this->m_DigitalisedInputImageg, this->m_DigitalisedInputImageg->GetLargestPossibleRegion() );
87-
typedef itk::ImageRegionConstIterator< InputImageType> ConstIteratorType;
88-
ConstIteratorType inputIt( this->GetInput(), this->GetInput()->GetLargestPossibleRegion() );
89-
unsigned int binNumber;
90-
while( !inputIt.IsAtEnd() )
81+
82+
typename TInputImage::Pointer input = InputImageType::New();
83+
input->Graft(const_cast<TInputImage *>(this->GetInput()));
84+
85+
typedef PreProcessingFunctor PPFType;
86+
PPFType ppf(m_NumberOfBinsPerAxis, m_InsidePixelValue, m_Min, m_Max);
87+
88+
typedef BinaryFunctorImageFilter< MaskImageType, InputImageType, InputImageType, PPFType> BinaryFunctorType;
89+
typename BinaryFunctorType::Pointer functorF = BinaryFunctorType::New();
90+
if (this->GetMaskImage() != ITK_NULLPTR)
9191
{
92-
if( maskPointer && maskPointer->GetPixel( inputIt.GetIndex() ) != this->m_InsidePixelValue )
93-
{
94-
digitIt.Set(this->m_Min - 10);
95-
}
96-
else if(inputIt.Get() < this->m_Min || inputIt.Get() >= this->m_Max)
97-
{
98-
digitIt.Set(this->m_Min - 1);
99-
}
100-
else
101-
{
102-
binNumber = ( inputIt.Get() - m_Min)/( (m_Max - m_Min) / (float)m_NumberOfBinsPerAxis );
103-
digitIt.Set(binNumber);
104-
}
105-
++inputIt;
106-
++digitIt;
92+
typename TInputImage::Pointer mask = MaskImageType::New();
93+
mask->Graft(const_cast<TInputImage *>(this->GetMaskImage()));
94+
functorF->SetInput1(mask);
10795
}
108-
m_Spacing = this->GetInput()->GetSpacing();
96+
else
97+
{
98+
functorF->SetConstant1(m_InsidePixelValue);
99+
}
100+
functorF->SetInput2(input);
101+
functorF->SetFunctor(ppf);
102+
functorF->SetNumberOfThreads(this->GetNumberOfThreads());
103+
104+
functorF->Update();
105+
m_DigitalisedInputImageg = functorF->GetOutput();
109106

110107
// Support VectorImages by setting number of components on output.
111108
OutputImageType * outputPtr = this->GetOutput();

0 commit comments

Comments
 (0)