Skip to content

Commit f158edc

Browse files
committed
ENH: do not recompute variables in ComputeAttenuation method
1 parent e4a0665 commit f158edc

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

include/itkAttenuationImageFilter.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,11 @@ class ITK_TEMPLATE_EXPORT AttenuationImageFilter : public ImageToImageFilter<TIn
200200
AttenuationImageFilter();
201201
~AttenuationImageFilter() override = default;
202202

203-
/** Verify inputs and allocate buffers before threaded execution */
203+
204+
void
205+
VerifyPreconditions() const override;
206+
207+
/** Allocate buffers and other initializations before threaded execution. */
204208
void
205209
BeforeThreadedGenerateData() override;
206210

@@ -237,12 +241,20 @@ class ITK_TEMPLATE_EXPORT AttenuationImageFilter : public ImageToImageFilter<TIn
237241

238242
unsigned int m_Direction = 0;
239243

244+
float m_ScanStepMM = 1.0f;
245+
240246
unsigned int m_FixedEstimationDepth = 0;
241247

242248
float m_SamplingFrequencyMHz = 0.0f;
243249

244250
float m_FrequencyBandStartMHz = 0.0f;
245251
float m_FrequencyBandEndMHz = 0.0f;
252+
float m_FrequencyDelta = 0.0f;
253+
254+
// Frequency band to consider for attenuation
255+
unsigned int m_StartComponent = 0;
256+
unsigned int m_EndComponent = 0;
257+
unsigned int m_ConsideredComponents = 1;
246258

247259
bool m_ConsiderNegativeAttenuations = false;
248260

@@ -253,7 +265,7 @@ class ITK_TEMPLATE_EXPORT AttenuationImageFilter : public ImageToImageFilter<TIn
253265
ImageRegionSplitterDirection::Pointer m_RegionSplitter = ImageRegionSplitterDirection::New();
254266

255267
/** Cache mask image reference before threaded execution to reduce calls to GetMaskImage() */
256-
const MaskImageType * m_ThreadedInputMaskImage;
268+
mutable const MaskImageType * m_ThreadedInputMaskImage;
257269

258270
/** Output mask image may be eroded via m_PadUpperBounds and m_PadLowerBounds
259271
* along scan line direction */

include/itkAttenuationImageFilter.hxx

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ AttenuationImageFilter<TInputImage, TOutputImage, TMaskImage>::GetImageRegionSpl
8888

8989
template <typename TInputImage, typename TOutputImage, typename TMaskImage>
9090
void
91-
AttenuationImageFilter<TInputImage, TOutputImage, TMaskImage>::BeforeThreadedGenerateData()
91+
AttenuationImageFilter<TInputImage, TOutputImage, TMaskImage>::VerifyPreconditions() const
9292
{
93-
// Verify inputs
93+
Superclass::VerifyPreconditions();
94+
9495
if (this->GetInputMaskImage() == nullptr)
9596
{
9697
itkExceptionMacro("Filter requires a mask image for inclusion estimates!");
@@ -109,7 +110,12 @@ AttenuationImageFilter<TInputImage, TOutputImage, TMaskImage>::BeforeThreadedGen
109110
{
110111
itkExceptionMacro("RF sampling frequency was not set!");
111112
}
113+
}
112114

115+
template <typename TInputImage, typename TOutputImage, typename TMaskImage>
116+
void
117+
AttenuationImageFilter<TInputImage, TOutputImage, TMaskImage>::BeforeThreadedGenerateData()
118+
{
113119
Superclass::BeforeThreadedGenerateData();
114120

115121
// Initialize metric image
@@ -122,6 +128,19 @@ AttenuationImageFilter<TInputImage, TOutputImage, TMaskImage>::BeforeThreadedGen
122128
m_OutputMaskImage->SetRegions(inputMaskImage->GetLargestPossibleRegion());
123129
m_OutputMaskImage->Allocate();
124130
m_OutputMaskImage->FillBuffer(0.0f);
131+
132+
// Initialize iVars used in ComputeAttenuation()
133+
float nyquistFrequency = m_SamplingFrequencyMHz / 2;
134+
float numComponents = this->GetInput()->GetNumberOfComponentsPerPixel();
135+
m_FrequencyDelta = nyquistFrequency / numComponents;
136+
m_StartComponent = m_FrequencyBandStartMHz / m_FrequencyDelta;
137+
m_EndComponent = m_FrequencyBandEndMHz / m_FrequencyDelta;
138+
if (m_EndComponent == 0) // If m_FrequencyBandEndMHz is not set
139+
{
140+
m_EndComponent = numComponents - 1; // Use all components
141+
}
142+
m_ConsideredComponents = m_EndComponent - m_StartComponent + 1;
143+
m_ScanStepMM = this->GetInput()->GetSpacing()[m_Direction];
125144
}
126145

127146
template <typename TInputImage, typename TOutputImage, typename TMaskImage>
@@ -184,7 +203,7 @@ AttenuationImageFilter<TInputImage, TOutputImage, TMaskImage>::ThreadedGenerateD
184203
target[m_Direction] = start[m_Direction] + m_FixedEstimationDepth;
185204
}
186205

187-
float estimatedAttenuation = ComputeAttenuation(target, start);
206+
float estimatedAttenuation = ComputeAttenuation(target, start);
188207

189208
// Update the corresponding pixel in the metric image
190209
if (estimatedAttenuation > 0.0 || m_ConsiderNegativeAttenuations)
@@ -219,34 +238,22 @@ typename AttenuationImageFilter<TInputImage, TOutputImage, TMaskImage>::OutputPi
219238
AttenuationImageFilter<TInputImage, TOutputImage, TMaskImage>::ComputeAttenuation(const InputIndexType & end,
220239
const InputIndexType & start) const
221240
{
222-
const float nyquistFrequency = m_SamplingFrequencyMHz / 2;
223-
224-
// Number and width of RF spectra frequency bins over the range (0, nyquist_frequency]
225-
const unsigned int numComponents = this->GetInput()->GetNumberOfComponentsPerPixel();
226-
const float frequencyDelta = nyquistFrequency / numComponents;
227-
228-
// Frequency band to consider for attenuation
229-
const unsigned int startComponent = m_FrequencyBandStartMHz / frequencyDelta;
230-
const unsigned int endComponent = m_FrequencyBandEndMHz / frequencyDelta;
231-
const unsigned int consideredComponents = endComponent - startComponent + 1;
232-
233241
// Get RF spectra frequency bins at start and end pixel positions
234242
auto input = this->GetInput();
235243
InputPixelType endSample = input->GetPixel(end);
236244
InputPixelType startSample = input->GetPixel(start);
237245

238246
// Get distance between start and end pixel positions (assume mm units)
239-
const float scanStepMM = input->GetSpacing()[m_Direction];
240247
const unsigned int pixelDistance = end[m_Direction] - start[m_Direction];
241-
float distanceMM = pixelDistance * scanStepMM;
248+
float distanceMM = pixelDistance * m_ScanStepMM;
242249

243-
Eigen::Matrix<float, Eigen::Dynamic, 2> A(consideredComponents, 2);
244-
Eigen::Matrix<float, Eigen::Dynamic, 1> b(consideredComponents);
245-
for (unsigned i = 0; i < consideredComponents; i++)
250+
Eigen::Matrix<float, Eigen::Dynamic, 2> A(m_ConsideredComponents, 2);
251+
Eigen::Matrix<float, Eigen::Dynamic, 1> b(m_ConsideredComponents);
252+
for (unsigned i = 0; i < m_ConsideredComponents; i++)
246253
{
247254
A(i, 0) = 1;
248-
A(i, 1) = (1 + i + startComponent) * frequencyDelta; // x_i = frequency
249-
b(i) = endSample[i + startComponent] / (startSample[i + startComponent] + itk::Math::eps); // y_i = ratio
255+
A(i, 1) = (1 + i + m_StartComponent) * m_FrequencyDelta; // x_i = frequency
256+
b(i) = endSample[i + m_StartComponent] / (startSample[i + m_StartComponent] + itk::Math::eps); // y_i = ratio
250257
}
251258

252259
// from https://eigen.tuxfamily.org/dox/group__LeastSquares.html

0 commit comments

Comments
 (0)