diff options
-rw-r--r-- | cuda/2d/fbp.cu | 32 | ||||
-rw-r--r-- | cuda/2d/fft.cu | 8 | ||||
-rw-r--r-- | cuda/3d/fdk.cu | 4 | ||||
-rw-r--r-- | include/astra/CudaFilteredBackProjectionAlgorithm.h | 6 | ||||
-rw-r--r-- | include/astra/Filters.h | 21 | ||||
-rw-r--r-- | include/astra/cuda/2d/fbp.h | 4 | ||||
-rw-r--r-- | include/astra/cuda/2d/fft.h | 4 | ||||
-rw-r--r-- | src/CudaFilteredBackProjectionAlgorithm.cpp | 83 | ||||
-rw-r--r-- | src/Filters.cpp | 96 |
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; +} } |