summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cuda/2d/fbp.cu32
-rw-r--r--cuda/2d/fft.cu8
-rw-r--r--cuda/3d/fdk.cu4
-rw-r--r--include/astra/CudaFilteredBackProjectionAlgorithm.h6
-rw-r--r--include/astra/Filters.h21
-rw-r--r--include/astra/cuda/2d/fbp.h4
-rw-r--r--include/astra/cuda/2d/fft.h4
-rw-r--r--src/CudaFilteredBackProjectionAlgorithm.cpp83
-rw-r--r--src/Filters.cpp96
9 files changed, 140 insertions, 118 deletions
diff --git a/cuda/2d/fbp.cu b/cuda/2d/fbp.cu
index 7a8d2e9..1574ccc 100644
--- a/cuda/2d/fbp.cu
+++ b/cuda/2d/fbp.cu
@@ -88,7 +88,7 @@ bool FBP::init()
return true;
}
-bool FBP::setFilter(astra::E_FBPFILTER _eFilter, const float * _pfHostFilter /* = NULL */, int _iFilterWidth /* = 0 */, float _fD /* = 1.0f */, float _fFilterParameter /* = -1.0f */)
+bool FBP::setFilter(const astra::SFilterConfig &_cfg)
{
if (D_filter)
{
@@ -96,7 +96,7 @@ bool FBP::setFilter(astra::E_FBPFILTER _eFilter, const float * _pfHostFilter /*
D_filter = 0;
}
- if (_eFilter == astra::FILTER_NONE)
+ if (_cfg.m_eType == astra::FILTER_NONE)
return true; // leave D_filter set to 0
@@ -108,7 +108,7 @@ bool FBP::setFilter(astra::E_FBPFILTER _eFilter, const float * _pfHostFilter /*
allocateComplexOnDevice(dims.iProjAngles, iFreqBinCount, (cufftComplex**)&D_filter);
- switch(_eFilter)
+ switch(_cfg.m_eType)
{
case astra::FILTER_NONE:
// handled above
@@ -130,7 +130,7 @@ bool FBP::setFilter(astra::E_FBPFILTER _eFilter, const float * _pfHostFilter /*
case astra::FILTER_FLATTOP:
case astra::FILTER_PARZEN:
{
- genCuFFTFilter(_eFilter, _fD, dims.iProjAngles, pHostFilter, iFFTRealDetCount, iFreqBinCount, _fFilterParameter);
+ genCuFFTFilter(_cfg, dims.iProjAngles, pHostFilter, iFFTRealDetCount, iFreqBinCount);
uploadComplexArrayToDevice(dims.iProjAngles, iFreqBinCount, pHostFilter, (cufftComplex*)D_filter);
break;
@@ -138,11 +138,11 @@ bool FBP::setFilter(astra::E_FBPFILTER _eFilter, const float * _pfHostFilter /*
case astra::FILTER_PROJECTION:
{
// make sure the offered filter has the correct size
- assert(_iFilterWidth == iFreqBinCount);
+ assert(_cfg.m_iCustomFilterWidth == iFreqBinCount);
for(int iFreqBinIndex = 0; iFreqBinIndex < iFreqBinCount; iFreqBinIndex++)
{
- float fValue = _pfHostFilter[iFreqBinIndex];
+ float fValue = _cfg.m_pfCustomFilter[iFreqBinIndex];
for(int iProjectionIndex = 0; iProjectionIndex < (int)dims.iProjAngles; iProjectionIndex++)
{
@@ -156,13 +156,13 @@ bool FBP::setFilter(astra::E_FBPFILTER _eFilter, const float * _pfHostFilter /*
case astra::FILTER_SINOGRAM:
{
// make sure the offered filter has the correct size
- assert(_iFilterWidth == iFreqBinCount);
+ assert(_cfg.m_iCustomFilterWidth == iFreqBinCount);
for(int iFreqBinIndex = 0; iFreqBinIndex < iFreqBinCount; iFreqBinIndex++)
{
for(int iProjectionIndex = 0; iProjectionIndex < (int)dims.iProjAngles; iProjectionIndex++)
{
- float fValue = _pfHostFilter[iFreqBinIndex + iProjectionIndex * _iFilterWidth];
+ float fValue = _cfg.m_pfCustomFilter[iFreqBinIndex + iProjectionIndex * _cfg.m_iCustomFilterWidth];
pHostFilter[iFreqBinIndex + iProjectionIndex * iFreqBinCount].x = fValue;
pHostFilter[iFreqBinIndex + iProjectionIndex * iFreqBinCount].y = 0.0f;
@@ -178,16 +178,16 @@ bool FBP::setFilter(astra::E_FBPFILTER _eFilter, const float * _pfHostFilter /*
float * pfHostRealFilter = new float[iRealFilterElementCount];
memset(pfHostRealFilter, 0, sizeof(float) * iRealFilterElementCount);
- int iUsedFilterWidth = min(_iFilterWidth, iFFTRealDetCount);
- int iStartFilterIndex = (_iFilterWidth - iUsedFilterWidth) / 2;
+ int iUsedFilterWidth = min(_cfg.m_iCustomFilterWidth, iFFTRealDetCount);
+ int iStartFilterIndex = (_cfg.m_iCustomFilterWidth - iUsedFilterWidth) / 2;
int iMaxFilterIndex = iStartFilterIndex + iUsedFilterWidth;
- int iFilterShiftSize = _iFilterWidth / 2;
+ int iFilterShiftSize = _cfg.m_iCustomFilterWidth / 2;
for(int iDetectorIndex = iStartFilterIndex; iDetectorIndex < iMaxFilterIndex; iDetectorIndex++)
{
int iFFTInFilterIndex = (iDetectorIndex + iFFTRealDetCount - iFilterShiftSize) % iFFTRealDetCount;
- float fValue = _pfHostFilter[iDetectorIndex];
+ float fValue = _cfg.m_pfCustomFilter[iDetectorIndex];
for(int iProjectionIndex = 0; iProjectionIndex < (int)dims.iProjAngles; iProjectionIndex++)
{
@@ -213,11 +213,11 @@ bool FBP::setFilter(astra::E_FBPFILTER _eFilter, const float * _pfHostFilter /*
float* pfHostRealFilter = new float[iRealFilterElementCount];
memset(pfHostRealFilter, 0, sizeof(float) * iRealFilterElementCount);
- int iUsedFilterWidth = min(_iFilterWidth, iFFTRealDetCount);
- int iStartFilterIndex = (_iFilterWidth - iUsedFilterWidth) / 2;
+ int iUsedFilterWidth = min(_cfg.m_iCustomFilterWidth, iFFTRealDetCount);
+ int iStartFilterIndex = (_cfg.m_iCustomFilterWidth - iUsedFilterWidth) / 2;
int iMaxFilterIndex = iStartFilterIndex + iUsedFilterWidth;
- int iFilterShiftSize = _iFilterWidth / 2;
+ int iFilterShiftSize = _cfg.m_iCustomFilterWidth / 2;
for(int iDetectorIndex = iStartFilterIndex; iDetectorIndex < iMaxFilterIndex; iDetectorIndex++)
{
@@ -225,7 +225,7 @@ bool FBP::setFilter(astra::E_FBPFILTER _eFilter, const float * _pfHostFilter /*
for(int iProjectionIndex = 0; iProjectionIndex < (int)dims.iProjAngles; iProjectionIndex++)
{
- float fValue = _pfHostFilter[iDetectorIndex + iProjectionIndex * _iFilterWidth];
+ float fValue = _cfg.m_pfCustomFilter[iDetectorIndex + iProjectionIndex * _cfg.m_iCustomFilterWidth];
pfHostRealFilter[iFFTInFilterIndex + iProjectionIndex * iFFTRealDetCount] = fValue;
}
}
diff --git a/cuda/2d/fft.cu b/cuda/2d/fft.cu
index 4454746..864e325 100644
--- a/cuda/2d/fft.cu
+++ b/cuda/2d/fft.cu
@@ -300,13 +300,13 @@ void genIdenFilter(int _iProjectionCount, cufftComplex * _pFilter,
}
}
-void genCuFFTFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
+void genCuFFTFilter(const SFilterConfig &_cfg, int _iProjectionCount,
cufftComplex * _pFilter, int _iFFTRealDetectorCount,
- int _iFFTFourierDetectorCount, float _fParameter /* = -1.0f */)
+ int _iFFTFourierDetectorCount)
{
- float * pfFilt = astra::genFilter(_eFilter, _fD, _iProjectionCount,
+ float * pfFilt = astra::genFilter(_cfg, _iProjectionCount,
_iFFTRealDetectorCount,
- _iFFTFourierDetectorCount, _fParameter);
+ _iFFTFourierDetectorCount);
for(int iDetectorIndex = 0; iDetectorIndex < _iFFTFourierDetectorCount; iDetectorIndex++)
{
diff --git a/cuda/3d/fdk.cu b/cuda/3d/fdk.cu
index 194d2fb..014529b 100644
--- a/cuda/3d/fdk.cu
+++ b/cuda/3d/fdk.cu
@@ -253,7 +253,9 @@ bool FDK_Filter(cudaPitchedPtr D_projData,
memset(pHostFilter, 0, sizeof(cufftComplex) * dims.iProjAngles * iHalfFFTSize);
if (pfFilter == 0){
- astraCUDA::genCuFFTFilter(astra::FILTER_RAMLAK, 1.0f, dims.iProjAngles, pHostFilter, iPaddedDetCount, iHalfFFTSize);
+ astra::SFilterConfig filter;
+ filter.m_eType = astra::FILTER_RAMLAK;
+ astraCUDA::genCuFFTFilter(filter, dims.iProjAngles, pHostFilter, iPaddedDetCount, iHalfFFTSize);
} else {
for (int i = 0; i < dims.iProjAngles * iHalfFFTSize; i++) {
pHostFilter[i].x = pfFilter[i];
diff --git a/include/astra/CudaFilteredBackProjectionAlgorithm.h b/include/astra/CudaFilteredBackProjectionAlgorithm.h
index 974914a..8ef5a57 100644
--- a/include/astra/CudaFilteredBackProjectionAlgorithm.h
+++ b/include/astra/CudaFilteredBackProjectionAlgorithm.h
@@ -46,11 +46,7 @@ public:
static std::string type;
private:
- E_FBPFILTER m_eFilter;
- float * m_pfFilter;
- int m_iFilterWidth; // number of elements per projection direction in filter
- float m_fFilterParameter; // some filters allow for parameterization (value < 0.0f -> no parameter)
- float m_fFilterD; // frequency cut-off
+ SFilterConfig m_filterConfig;
bool m_bShortScan; // short-scan mode for fan beam
public:
diff --git a/include/astra/Filters.h b/include/astra/Filters.h
index ff3f5c8..eec2ba2 100644
--- a/include/astra/Filters.h
+++ b/include/astra/Filters.h
@@ -30,6 +30,9 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
namespace astra {
+struct Config;
+class CAlgorithm;
+
enum E_FBPFILTER
{
FILTER_ERROR, //< not a valid filter
@@ -58,14 +61,28 @@ enum E_FBPFILTER
};
+struct SFilterConfig {
+ E_FBPFILTER m_eType;
+ float m_fD;
+ float m_fParameter;
+
+ float *m_pfCustomFilter;
+ int m_iCustomFilterWidth;
+
+ SFilterConfig() : m_eType(FILTER_ERROR), m_fD(1.0f), m_fParameter(-1.0f),
+ m_pfCustomFilter(0), m_iCustomFilterWidth(0) { };
+};
+
// Generate filter of given size and parameters. Returns newly allocated array.
-float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
+float *genFilter(const SFilterConfig &_cfg, int _iProjectionCount,
int _iFFTRealDetectorCount,
- int _iFFTFourierDetectorCount, float _fParameter = -1.0f);
+ int _iFFTFourierDetectorCount);
// Convert string to filter type. Returns FILTER_ERROR if unrecognized.
E_FBPFILTER convertStringToFilter(const char * _filterType);
+SFilterConfig getFilterConfigForAlgorithm(const Config& _cfg, CAlgorithm *_alg);
+
}
#endif
diff --git a/include/astra/cuda/2d/fbp.h b/include/astra/cuda/2d/fbp.h
index 7febe69..1adf3b1 100644
--- a/include/astra/cuda/2d/fbp.h
+++ b/include/astra/cuda/2d/fbp.h
@@ -75,9 +75,7 @@ public:
// FILTER_COSINE, FILTER_HAMMING, and FILTER_HANN)
// have a D variable, which gives the cutoff point in the frequency domain.
// Setting this value to 1.0 will include the whole filter
- bool setFilter(astra::E_FBPFILTER _eFilter,
- const float * _pfHostFilter = NULL,
- int _iFilterWidth = 0, float _fD = 1.0f, float _fFilterParameter = -1.0f);
+ bool setFilter(const astra::SFilterConfig &_cfg);
bool setShortScan(bool ss) { m_bShortScan = ss; return true; }
diff --git a/include/astra/cuda/2d/fft.h b/include/astra/cuda/2d/fft.h
index f5f8477..33612a0 100644
--- a/include/astra/cuda/2d/fft.h
+++ b/include/astra/cuda/2d/fft.h
@@ -60,9 +60,9 @@ void applyFilter(int _iProjectionCount, int _iFreqBinCount,
int calcFFTFourierSize(int _iFFTRealSize);
-void genCuFFTFilter(astra::E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
+void genCuFFTFilter(const astra::SFilterConfig &_cfg, int _iProjectionCount,
cufftComplex * _pFilter, int _iFFTRealDetectorCount,
- int _iFFTFourierDetectorCount, float _fParameter = -1.0f);
+ int _iFFTFourierDetectorCount);
void genIdenFilter(int _iProjectionCount, cufftComplex * _pFilter,
int _iFFTRealDetectorCount, int _iFFTFourierDetectorCount);
diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp
index 9ebbd60..90b831e 100644
--- a/src/CudaFilteredBackProjectionAlgorithm.cpp
+++ b/src/CudaFilteredBackProjectionAlgorithm.cpp
@@ -45,15 +45,12 @@ CCudaFilteredBackProjectionAlgorithm::CCudaFilteredBackProjectionAlgorithm()
{
m_bIsInitialized = false;
CCudaReconstructionAlgorithm2D::_clear();
- m_pfFilter = NULL;
- m_fFilterParameter = -1.0f;
- m_fFilterD = 1.0f;
}
CCudaFilteredBackProjectionAlgorithm::~CCudaFilteredBackProjectionAlgorithm()
{
- delete[] m_pfFilter;
- m_pfFilter = NULL;
+ delete[] m_filterConfig.m_pfCustomFilter;
+ m_filterConfig.m_pfCustomFilter = NULL;
}
bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)
@@ -71,59 +68,7 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)
if (!m_bIsInitialized)
return false;
-
- // filter type
- XMLNode node = _cfg.self.getSingleNode("FilterType");
- if (node)
- m_eFilter = convertStringToFilter(node.getContent().c_str());
- else
- m_eFilter = FILTER_RAMLAK;
- CC.markNodeParsed("FilterType");
-
- // filter
- node = _cfg.self.getSingleNode("FilterSinogramId");
- if (node)
- {
- int id = node.getContentInt();
- const CFloat32ProjectionData2D * pFilterData = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));
- m_iFilterWidth = pFilterData->getGeometry()->getDetectorCount();
- int iFilterProjectionCount = pFilterData->getGeometry()->getProjectionAngleCount();
-
- m_pfFilter = new float[m_iFilterWidth * iFilterProjectionCount];
- memcpy(m_pfFilter, pFilterData->getDataConst(), sizeof(float) * m_iFilterWidth * iFilterProjectionCount);
- }
- else
- {
- m_iFilterWidth = 0;
- m_pfFilter = NULL;
- }
- CC.markNodeParsed("FilterSinogramId"); // TODO: Only for some types!
-
- // filter parameter
- node = _cfg.self.getSingleNode("FilterParameter");
- if (node)
- {
- float fParameter = node.getContentNumerical();
- m_fFilterParameter = fParameter;
- }
- else
- {
- m_fFilterParameter = -1.0f;
- }
- CC.markNodeParsed("FilterParameter"); // TODO: Only for some types!
-
- // D value
- node = _cfg.self.getSingleNode("FilterD");
- if (node)
- {
- float fD = node.getContentNumerical();
- m_fFilterD = fD;
- }
- else
- {
- m_fFilterD = 1.0f;
- }
- CC.markNodeParsed("FilterD"); // TODO: Only for some types!
+ m_filterConfig = getFilterConfigForAlgorithm(_cfg, this);
// Fan beam short scan mode
if (m_pSinogram && dynamic_cast<CFanFlatProjectionGeometry2D*>(m_pSinogram->getGeometry())) {
@@ -153,8 +98,8 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(CFloat32ProjectionData2D *
m_pReconstruction = _pReconstruction;
m_iGPUIndex = _iGPUIndex;
- m_eFilter = _eFilter;
- m_iFilterWidth = _iFilterWidth;
+ m_filterConfig.m_eType = _eFilter;
+ m_filterConfig.m_iCustomFilterWidth = _iFilterWidth;
m_bShortScan = false;
// success
@@ -167,7 +112,7 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(CFloat32ProjectionData2D *
{
int iFilterElementCount = 0;
- if((_eFilter != FILTER_SINOGRAM) && (_eFilter != FILTER_RSINOGRAM))
+ if((m_filterConfig.m_eType != FILTER_SINOGRAM) && (m_filterConfig.m_eType != FILTER_RSINOGRAM))
{
iFilterElementCount = _iFilterWidth;
}
@@ -176,15 +121,15 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(CFloat32ProjectionData2D *
iFilterElementCount = m_pSinogram->getAngleCount();
}
- m_pfFilter = new float[iFilterElementCount];
- memcpy(m_pfFilter, _pfFilter, iFilterElementCount * sizeof(float));
+ m_filterConfig.m_pfCustomFilter = new float[iFilterElementCount];
+ memcpy(m_filterConfig.m_pfCustomFilter, _pfFilter, iFilterElementCount * sizeof(float));
}
else
{
- m_pfFilter = NULL;
+ m_filterConfig.m_pfCustomFilter = NULL;
}
- m_fFilterParameter = _fFilterParameter;
+ m_filterConfig.m_fParameter = _fFilterParameter;
return check();
}
@@ -196,7 +141,7 @@ void CCudaFilteredBackProjectionAlgorithm::initCUDAAlgorithm()
astraCUDA::FBP* pFBP = dynamic_cast<astraCUDA::FBP*>(m_pAlgo);
- bool ok = pFBP->setFilter(m_eFilter, m_pfFilter, m_iFilterWidth, m_fFilterD, m_fFilterParameter);
+ bool ok = pFBP->setFilter(m_filterConfig);
if (!ok) {
ASTRA_ERROR("CCudaFilteredBackProjectionAlgorithm: Failed to set filter");
ASTRA_ASSERT(ok);
@@ -215,11 +160,11 @@ bool CCudaFilteredBackProjectionAlgorithm::check()
ASTRA_CONFIG_CHECK(m_pSinogram, "FBP_CUDA", "Invalid Projection Data Object.");
ASTRA_CONFIG_CHECK(m_pReconstruction, "FBP_CUDA", "Invalid Reconstruction Data Object.");
- ASTRA_CONFIG_CHECK(m_eFilter != FILTER_ERROR, "FBP_CUDA", "Invalid filter name.");
+ ASTRA_CONFIG_CHECK(m_filterConfig.m_eType != FILTER_ERROR, "FBP_CUDA", "Invalid filter name.");
- if((m_eFilter == FILTER_PROJECTION) || (m_eFilter == FILTER_SINOGRAM) || (m_eFilter == FILTER_RPROJECTION) || (m_eFilter == FILTER_RSINOGRAM))
+ if((m_filterConfig.m_eType == FILTER_PROJECTION) || (m_filterConfig.m_eType == FILTER_SINOGRAM) || (m_filterConfig.m_eType == FILTER_RPROJECTION) || (m_filterConfig.m_eType == FILTER_RSINOGRAM))
{
- ASTRA_CONFIG_CHECK(m_pfFilter, "FBP_CUDA", "Invalid filter pointer.");
+ ASTRA_CONFIG_CHECK(m_filterConfig.m_pfCustomFilter, "FBP_CUDA", "Invalid filter pointer.");
}
// check initializations
diff --git a/src/Filters.cpp b/src/Filters.cpp
index 30b2f24..bbd7cfd 100644
--- a/src/Filters.cpp
+++ b/src/Filters.cpp
@@ -29,15 +29,18 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
#include "astra/Logging.h"
#include "astra/Fourier.h"
#include "astra/Filters.h"
+#include "astra/Config.h"
+#include "astra/Float32ProjectionData2D.h"
+#include "astra/AstraObjectManager.h"
#include <utility>
#include <cstring>
namespace astra {
-float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
+float *genFilter(const SFilterConfig &_cfg, int _iProjectionCount,
int _iFFTRealDetectorCount,
- int _iFFTFourierDetectorCount, float _fParameter /* = -1.0f */)
+ int _iFFTFourierDetectorCount)
{
float * pfFilt = new float[_iFFTFourierDetectorCount];
float * pfW = new float[_iFFTFourierDetectorCount];
@@ -86,7 +89,7 @@ float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
pfW[iDetectorIndex] = M_PI * 2.0f * fRelIndex;
}
- switch(_eFilter)
+ switch(_cfg.m_eType)
{
case FILTER_RAMLAK:
{
@@ -98,7 +101,7 @@ float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
// filt(2:end) = filt(2:end) .* (sin(w(2:end)/(2*d))./(w(2:end)/(2*d)))
for(int iDetectorIndex = 1; iDetectorIndex < _iFFTFourierDetectorCount; iDetectorIndex++)
{
- pfFilt[iDetectorIndex] = pfFilt[iDetectorIndex] * (sinf(pfW[iDetectorIndex] / 2.0f / _fD) / (pfW[iDetectorIndex] / 2.0f / _fD));
+ pfFilt[iDetectorIndex] = pfFilt[iDetectorIndex] * (sinf(pfW[iDetectorIndex] / 2.0f / _cfg.m_fD) / (pfW[iDetectorIndex] / 2.0f / _cfg.m_fD));
}
break;
}
@@ -107,7 +110,7 @@ float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
// filt(2:end) = filt(2:end) .* cos(w(2:end)/(2*d))
for(int iDetectorIndex = 1; iDetectorIndex < _iFFTFourierDetectorCount; iDetectorIndex++)
{
- pfFilt[iDetectorIndex] = pfFilt[iDetectorIndex] * cosf(pfW[iDetectorIndex] / 2.0f / _fD);
+ pfFilt[iDetectorIndex] = pfFilt[iDetectorIndex] * cosf(pfW[iDetectorIndex] / 2.0f / _cfg.m_fD);
}
break;
}
@@ -116,7 +119,7 @@ float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
// filt(2:end) = filt(2:end) .* (.54 + .46 * cos(w(2:end)/d))
for(int iDetectorIndex = 1; iDetectorIndex < _iFFTFourierDetectorCount; iDetectorIndex++)
{
- pfFilt[iDetectorIndex] = pfFilt[iDetectorIndex] * ( 0.54f + 0.46f * cosf(pfW[iDetectorIndex] / _fD));
+ pfFilt[iDetectorIndex] = pfFilt[iDetectorIndex] * ( 0.54f + 0.46f * cosf(pfW[iDetectorIndex] / _cfg.m_fD));
}
break;
}
@@ -125,14 +128,14 @@ float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
// filt(2:end) = filt(2:end) .*(1+cos(w(2:end)./d)) / 2
for(int iDetectorIndex = 1; iDetectorIndex < _iFFTFourierDetectorCount; iDetectorIndex++)
{
- pfFilt[iDetectorIndex] = pfFilt[iDetectorIndex] * (1.0f + cosf(pfW[iDetectorIndex] / _fD)) / 2.0f;
+ pfFilt[iDetectorIndex] = pfFilt[iDetectorIndex] * (1.0f + cosf(pfW[iDetectorIndex] / _cfg.m_fD)) / 2.0f;
}
break;
}
case FILTER_TUKEY:
{
- float fAlpha = _fParameter;
- if(_fParameter < 0.0f) fAlpha = 0.5f;
+ float fAlpha = _cfg.m_fParameter;
+ if(_cfg.m_fParameter < 0.0f) fAlpha = 0.5f;
float fN = (float)_iFFTFourierDetectorCount;
float fHalfN = fN / 2.0f;
float fEnumTerm = fAlpha * fHalfN;
@@ -204,8 +207,8 @@ float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
}
case FILTER_GAUSSIAN:
{
- float fSigma = _fParameter;
- if(_fParameter < 0.0f) fSigma = 0.4f;
+ float fSigma = _cfg.m_fParameter;
+ if(_cfg.m_fParameter < 0.0f) fSigma = 0.4f;
float fN = (float)_iFFTFourierDetectorCount;
float fQuotient = (fN - 1.0f) / 2.0f;
@@ -245,8 +248,8 @@ float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
}
case FILTER_BLACKMAN:
{
- float fAlpha = _fParameter;
- if(_fParameter < 0.0f) fAlpha = 0.16f;
+ float fAlpha = _cfg.m_fParameter;
+ if(_cfg.m_fParameter < 0.0f) fAlpha = 0.16f;
float fA0 = (1.0f - fAlpha) / 2.0f;
float fA1 = 0.5f;
float fA2 = fAlpha / 2.0f;
@@ -356,8 +359,8 @@ float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
}
case FILTER_KAISER:
{
- float fAlpha = _fParameter;
- if(_fParameter < 0.0f) fAlpha = 3.0f;
+ float fAlpha = _cfg.m_fParameter;
+ if(_cfg.m_fParameter < 0.0f) fAlpha = 3.0f;
float fPiTimesAlpha = M_PI * fAlpha;
float fNMinusOne = (float)(_iFFTFourierDetectorCount - 1);
float fDenom = (float)j0((double)fPiTimesAlpha);
@@ -406,7 +409,7 @@ float *genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount,
}
// filt(w>pi*d) = 0;
- float fPiTimesD = M_PI * _fD;
+ float fPiTimesD = M_PI * _cfg.m_fD;
for(int iDetectorIndex = 0; iDetectorIndex < _iFFTFourierDetectorCount; iDetectorIndex++)
{
float fWValue = pfW[iDetectorIndex];
@@ -480,5 +483,66 @@ E_FBPFILTER convertStringToFilter(const char * _filterType)
}
+SFilterConfig getFilterConfigForAlgorithm(const Config& _cfg, CAlgorithm *_alg)
+{
+ ConfigStackCheck<CAlgorithm> CC("getFilterConfig", _alg, _cfg);
+
+ SFilterConfig c;
+
+ // filter type
+ XMLNode node = _cfg.self.getSingleNode("FilterType");
+ if (node)
+ c.m_eType = convertStringToFilter(node.getContent().c_str());
+ else
+ c.m_eType = FILTER_RAMLAK;
+ CC.markNodeParsed("FilterType");
+
+ // filter
+ node = _cfg.self.getSingleNode("FilterSinogramId");
+ if (node)
+ {
+ int id = node.getContentInt();
+ const CFloat32ProjectionData2D * pFilterData = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));
+ c.m_iCustomFilterWidth = pFilterData->getGeometry()->getDetectorCount();
+ int iFilterProjectionCount = pFilterData->getGeometry()->getProjectionAngleCount();
+
+ c.m_pfCustomFilter = new float[c.m_iCustomFilterWidth * iFilterProjectionCount];
+ memcpy(c.m_pfCustomFilter, pFilterData->getDataConst(), sizeof(float) * c.m_iCustomFilterWidth * iFilterProjectionCount);
+ }
+ else
+ {
+ c.m_iCustomFilterWidth = 0;
+ c.m_pfCustomFilter = NULL;
+ }
+ CC.markNodeParsed("FilterSinogramId"); // TODO: Only for some types!
+
+ // filter parameter
+ node = _cfg.self.getSingleNode("FilterParameter");
+ if (node)
+ {
+ float fParameter = node.getContentNumerical();
+ c.m_fParameter = fParameter;
+ }
+ else
+ {
+ c.m_fParameter = -1.0f;
+ }
+ CC.markNodeParsed("FilterParameter"); // TODO: Only for some types!
+
+ // D value
+ node = _cfg.self.getSingleNode("FilterD");
+ if (node)
+ {
+ float fD = node.getContentNumerical();
+ c.m_fD = fD;
+ }
+ else
+ {
+ c.m_fD = 1.0f;
+ }
+ CC.markNodeParsed("FilterD"); // TODO: Only for some types!
+
+ return c;
+}
}