Skip to content
Snippets Groups Projects
Commit df670fe6 authored by Jordi Inglada's avatar Jordi Inglada
Browse files

REFAC: use a struct for histogram summary

for code readability and avoid passign the vector to the method, which
may allow changing the histogram implementation
parent 84b7f434
No related branches found
No related tags found
No related merge requests found
...@@ -169,22 +169,31 @@ protected: ...@@ -169,22 +169,31 @@ protected:
const KernelIteratorType kernelEnd) ITK_OVERRIDE; const KernelIteratorType kernelEnd) ITK_OVERRIDE;
void GenerateOutputInformation() ITK_OVERRIDE; void GenerateOutputInformation() ITK_OVERRIDE;
//Type to store the useful information from the label histogram
struct HistoSummary
{
unsigned int freqCenterLabel;
unsigned int majorityFreq;
PixelType majorityLabel;
unsigned int secondFreq;
PixelType secondLabel;
};
//Functor sort histogram in decreasing order
struct CompareHistoFequencies
{
typedef std::pair<PixelType, unsigned int> HistoValueType;
bool operator()(const HistoValueType& a, const HistoValueType& b)
{
return a.second > b.second;
}
};
//Get a histogram of frequencies of labels with the 2 highest frequencies sorted in decreasing order //Get a histogram of frequencies of labels with the 2 highest frequencies sorted in decreasing order
// and return the frequency of the label of the center pixel // and return the frequency of the label of the center pixel
unsigned int FillNeighborhoodHistogram(std::vector<std::pair<PixelType, unsigned int> >& histoNeigh, const HistoSummary FillNeighborhoodHistogram(const NeighborhoodIteratorType &nit,
const NeighborhoodIteratorType &nit, const KernelIteratorType kernelBegin,
const KernelIteratorType kernelBegin, const KernelIteratorType kernelEnd) const;
const KernelIteratorType kernelEnd) const;
struct CompareHistoFequencies
{
typedef std::pair<PixelType, unsigned int> HistoValueType;
bool operator()(const HistoValueType& a, const HistoValueType& b)
{
return a.second > b.second;
}
};
private: private:
NeighborhoodMajorityVotingImageFilter(const Self&); //purposely not implemented NeighborhoodMajorityVotingImageFilter(const Self&); //purposely not implemented
......
...@@ -51,37 +51,31 @@ typename NeighborhoodMajorityVotingImageFilter<TInputImage, TOutputImage, ...@@ -51,37 +51,31 @@ typename NeighborhoodMajorityVotingImageFilter<TInputImage, TOutputImage,
const KernelIteratorType kernelEnd) const KernelIteratorType kernelEnd)
{ {
const PixelType centerPixel = nit.GetCenterPixel(); const PixelType centerPixel = nit.GetCenterPixel();
PixelType majorityLabel = centerPixel; //Value of the more representative pixels in the neighborhood
unsigned int majorityFreq = 1; //Number of pixels with the more representative value (majorityLabel) in the neighborhood
if (centerPixel != m_LabelForNoDataPixels) if (centerPixel != m_LabelForNoDataPixels)
{ {
std::vector< std::pair<PixelType, unsigned int> > histoNeighVec;
//Get a histogram of label frequencies where the 2 highest are at the beginning and sorted //Get a histogram of label frequencies where the 2 highest are at the beginning and sorted
const unsigned int freqCenterLabel = this->FillNeighborhoodHistogram(histoNeighVec, nit, kernelBegin, kernelEnd); const HistoSummary histoSummary = this->FillNeighborhoodHistogram(nit, kernelBegin, kernelEnd);
if(m_OnlyIsolatedPixels && freqCenterLabel > m_IsolatedThreshold) if(m_OnlyIsolatedPixels && histoSummary.freqCenterLabel > m_IsolatedThreshold)
{ {
//If we want to filter only isolated pixels, keep the label if //If we want to filter only isolated pixels, keep the label if
//there are enough pixels with the center label to consider that //there are enough pixels with the center label to consider that
//it is not isolated //it is not isolated
majorityLabel = centerPixel; return centerPixel;
} }
else else
{ {
//Extraction of the more representative Label in the neighborhood (majorityLabel) and its Frequency (majorityFreq)
majorityFreq = histoNeighVec[0].second; //Frequency
majorityLabel = histoNeighVec[0].first; //Label
//If the majorityLabel is NOT unique in the neighborhood //If the majorityLabel is NOT unique in the neighborhood
if(histoNeighVec[1].second == majorityFreq && histoNeighVec[1].first != majorityLabel) if(histoSummary.secondFreq == histoSummary.majorityFreq && histoSummary.secondLabel != histoSummary.majorityLabel)
{ {
if (m_KeepOriginalLabelBool == true) if (m_KeepOriginalLabelBool == true)
{ {
majorityLabel = centerPixel; return centerPixel;
} }
else else
{ {
majorityLabel = m_LabelForUndecidedPixels; return m_LabelForUndecidedPixels;
} }
} }
...@@ -93,19 +87,19 @@ typename NeighborhoodMajorityVotingImageFilter<TInputImage, TOutputImage, ...@@ -93,19 +87,19 @@ typename NeighborhoodMajorityVotingImageFilter<TInputImage, TOutputImage,
//If (centerPixel == m_LabelForNoDataPixels) //If (centerPixel == m_LabelForNoDataPixels)
else else
{ {
majorityLabel = m_LabelForNoDataPixels; return m_LabelForNoDataPixels;
} }
return majorityLabel; return centerPixel;
} }
template<class TInputImage, class TOutputImage, class TKernel> template<class TInputImage, class TOutputImage, class TKernel>
unsigned int NeighborhoodMajorityVotingImageFilter<TInputImage, const typename NeighborhoodMajorityVotingImageFilter<TInputImage, TOutputImage,
TOutputImage, TKernel>::HistoSummary NeighborhoodMajorityVotingImageFilter<TInputImage,
TKernel>::FillNeighborhoodHistogram(std::vector<std::pair<PixelType, unsigned int> >& histoNeighVec, TOutputImage,
const NeighborhoodIteratorType &nit, TKernel>::FillNeighborhoodHistogram(const NeighborhoodIteratorType &nit,
const KernelIteratorType kernelBegin, const KernelIteratorType kernelBegin,
const KernelIteratorType kernelEnd) const const KernelIteratorType kernelEnd) const
{ {
std::map<PixelType, unsigned int> histoNeigh; std::map<PixelType, unsigned int> histoNeigh;
PixelType centerPixel = nit.GetCenterPixel(); PixelType centerPixel = nit.GetCenterPixel();
...@@ -124,11 +118,20 @@ unsigned int NeighborhoodMajorityVotingImageFilter<TInputImage, ...@@ -124,11 +118,20 @@ unsigned int NeighborhoodMajorityVotingImageFilter<TInputImage,
histoNeigh[label] += 1; histoNeigh[label] += 1;
} }
} }
std::vector< std::pair<PixelType, unsigned int> > histoNeighVec;
std::copy(histoNeigh.begin(), histoNeigh.end(), std::back_inserter(histoNeighVec)); std::copy(histoNeigh.begin(), histoNeigh.end(), std::back_inserter(histoNeighVec));
const typename std::vector<std::pair<PixelType, unsigned int> >::iterator histoIt = histoNeighVec.begin(); const typename std::vector<std::pair<PixelType, unsigned int> >::iterator histoIt = histoNeighVec.begin();
std::nth_element(histoNeighVec.begin(), histoIt+1, std::nth_element(histoNeighVec.begin(), histoIt+1,
histoNeighVec.end(), CompareHistoFequencies()); histoNeighVec.end(), CompareHistoFequencies());
return histoNeigh[centerPixel]; typename NeighborhoodMajorityVotingImageFilter<TInputImage, TOutputImage,
TKernel>::HistoSummary result;
result.freqCenterLabel = histoNeigh[centerPixel];
result.majorityFreq = histoNeighVec[0].first;
result.majorityLabel = histoNeighVec[0].second;
result.secondFreq = histoNeighVec[1].first;
result.secondLabel = histoNeighVec[1].second;
return result;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment