Skip to content

Commit 4b6b444

Browse files
committed
BUG: ZScore computations invalid for small values
Images with small values have standard deviations that could be smaller than 1.0, but be perfectly valid. For the case when the standard deviation is zero, set all the z-score values to zero.
1 parent c001c43 commit 4b6b444

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

include/itkNonLocalPatchBasedImageFilter.hxx

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,21 @@ NonLocalPatchBasedImageFilter<TInputImage, TOutputImage>::VectorizeImagePatch(co
112112

113113
if (normalize)
114114
{
115+
// Convert the current image patch to a z-score.
115116
RealType mean = 0.0;
116117
RealType standardDeviation = 0.0;
117118
this->GetMeanAndStandardDeviationOfVectorizedImagePatch(patchVector, mean, standardDeviation);
118-
119-
standardDeviation = std::max(standardDeviation, NumericTraits<RealType>::OneValue());
120-
121-
typename InputImagePixelVectorType::iterator it;
122-
for (it = patchVector.begin(); it != patchVector.end(); ++it)
119+
if (standardDeviation < NumericTraits<RealType>::epsilon())
120+
{
121+
for (auto & it : patchVector)
122+
{
123+
it = 0.;
124+
}
125+
}
126+
const auto inv_standardDeviation = 1. / standardDeviation;
127+
for (auto & it : patchVector)
123128
{
124-
*it = (*it - mean) / standardDeviation;
129+
it = (it - mean) * inv_standardDeviation;
125130
}
126131
}
127132
return patchVector;
@@ -138,13 +143,13 @@ NonLocalPatchBasedImageFilter<TInputImage, TOutputImage>::GetMeanAndStandardDevi
138143
RealType sumOfSquares = 0.0;
139144
RealType count = 0.0;
140145

141-
typename InputImagePixelVectorType::const_iterator it;
142-
for (it = patchVector.begin(); it != patchVector.end(); ++it)
146+
for (const auto it : patchVector)
143147
{
144-
if (std::isfinite(*it))
148+
if (std::isfinite(it)) // Silently skip non-finite values used to indicate
149+
// out-of-bounds.
145150
{
146-
sum += *it;
147-
sumOfSquares += itk::Math::sqr(*it);
151+
sum += it;
152+
sumOfSquares += itk::Math::sqr(it);
148153
count += itk::NumericTraits<RealType>::OneValue();
149154
}
150155
}
@@ -204,13 +209,11 @@ NonLocalPatchBasedImageFilter<TInputImage, TOutputImage>::ComputeNeighborhoodPat
204209
{
205210
return NumericTraits<RealType>::max();
206211
}
207-
208212
if (this->m_SimilarityMetric == SimilarityMetricEnum::PEARSON_CORRELATION)
209213
{
210-
RealType varianceX = sumOfSquaresX - itk::Math::sqr(sumX) / N;
211-
varianceX = std::max(varianceX, static_cast<RealType>(1.0e-6));
212-
213-
RealType measure = itk::Math::sqr(sumXY) / varianceX;
214+
const RealType varianceX = sumOfSquaresX - itk::Math::sqr(sumX) / N;
215+
const RealType measure =
216+
(varianceX > std::numeric_limits<RealType>::epsilon()) ? itk::Math::sqr(sumXY) / varianceX : 0.;
214217
if (sumXY > 0)
215218
{
216219
return -measure;

0 commit comments

Comments
 (0)