diff options
-rw-r--r-- | build/linux/configure.ac | 4 | ||||
-rw-r--r-- | include/astra/Filters.h | 4 | ||||
-rw-r--r-- | python/astra/data3d_c.pyx | 1 | ||||
-rw-r--r-- | samples/matlab/s014_FBP.m | 2 | ||||
-rw-r--r-- | samples/matlab/s023_FBP_filters.m | 10 | ||||
-rw-r--r-- | samples/python/s014_FBP.py | 2 | ||||
-rw-r--r-- | samples/python/s023_FBP_filters.py | 11 | ||||
-rw-r--r-- | src/FilteredBackProjectionAlgorithm.cpp | 5 | ||||
-rw-r--r-- | src/Filters.cpp | 114 |
9 files changed, 100 insertions, 53 deletions
diff --git a/build/linux/configure.ac b/build/linux/configure.ac index cb478f7..ffb525a 100644 --- a/build/linux/configure.ac +++ b/build/linux/configure.ac @@ -125,9 +125,9 @@ fi AC_ARG_WITH(cuda_compute, [[ --with-cuda-compute=archs comma separated list of CUDA compute models (optional)]],,) if test x"$HAVECUDA" = xyes; then AC_MSG_CHECKING([for nvcc archs]) - dnl 10 11 12 13 20 21 30 32 35 37 50 52 53 60 61 + dnl 10 11 12 13 20 21 30 32 35 37 50 52 53 60 61 62 70 72 75 if test x"$with_cuda_compute" = x; then - with_cuda_compute="20,30,35,50,60" + with_cuda_compute="20,30,35,50,60,70,75" fi ASTRA_FIND_NVCC_ARCHS([$with_cuda_compute],NVCCFLAGS_EXTRA,NVCCARCHS) AC_MSG_RESULT([$NVCCARCHS]) diff --git a/include/astra/Filters.h b/include/astra/Filters.h index a1dec97..2e229b9 100644 --- a/include/astra/Filters.h +++ b/include/astra/Filters.h @@ -28,6 +28,8 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. #ifndef _INC_ASTRA_FILTERS_H #define _INC_ASTRA_FILTERS_H +#include <string> + namespace astra { struct Config; @@ -82,7 +84,7 @@ float *genFilter(const SFilterConfig &_cfg, int _iFFTFourierDetectorCount); // Convert string to filter type. Returns FILTER_ERROR if unrecognized. -E_FBPFILTER convertStringToFilter(const char * _filterType); +E_FBPFILTER convertStringToFilter(const std::string &_filterType); SFilterConfig getFilterConfigForAlgorithm(const Config& _cfg, CAlgorithm *_alg); diff --git a/python/astra/data3d_c.pyx b/python/astra/data3d_c.pyx index d4073ea..4c8aa62 100644 --- a/python/astra/data3d_c.pyx +++ b/python/astra/data3d_c.pyx @@ -277,7 +277,6 @@ def get(i): def get_shared(i): cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem_safe(getObject(i)) - outArr = np.empty((pDataObject.getDepth(),pDataObject.getHeight(), pDataObject.getWidth()),dtype=np.float32,order='C') cdef np.npy_intp shape[3] shape[0] = <np.npy_intp> pDataObject.getDepth() shape[1] = <np.npy_intp> pDataObject.getHeight() diff --git a/samples/matlab/s014_FBP.m b/samples/matlab/s014_FBP.m index 1fc6f90..038aa90 100644 --- a/samples/matlab/s014_FBP.m +++ b/samples/matlab/s014_FBP.m @@ -24,7 +24,7 @@ rec_id = astra_mex_data2d('create', '-vol', vol_geom); cfg = astra_struct('FBP_CUDA'); cfg.ReconstructionDataId = rec_id; cfg.ProjectionDataId = sinogram_id; -cfg.FilterType = 'Ram-Lak'; +cfg.option.FilterType = 'Ram-Lak'; % possible values for FilterType: % none, ram-lak, shepp-logan, cosine, hamming, hann, tukey, lanczos, diff --git a/samples/matlab/s023_FBP_filters.m b/samples/matlab/s023_FBP_filters.m index 4abec7e..d01b0d0 100644 --- a/samples/matlab/s023_FBP_filters.m +++ b/samples/matlab/s023_FBP_filters.m @@ -32,7 +32,7 @@ cfg.ProjectorId = proj_id; % 1. Use a standard Ram-Lak filter -cfg.FilterType = 'ram-lak'; +cfg.option.FilterType = 'ram-lak'; alg_id = astra_mex_algorithm('create', cfg); astra_mex_algorithm('run', alg_id); @@ -53,8 +53,8 @@ filter = kernel(1:halfFilterSize); filter_geom = astra_create_proj_geom('parallel', 1.0, halfFilterSize, [0]); filter_id = astra_mex_data2d('create', '-sino', filter_geom, filter); -cfg.FilterType = 'projection'; -cfg.FilterSinogramId = filter_id; +cfg.option.FilterType = 'projection'; +cfg.option.FilterSinogramId = filter_id; alg_id = astra_mex_algorithm('create', cfg); astra_mex_algorithm('run', alg_id); @@ -77,8 +77,8 @@ kernel(floor(N/2)+1) = 0.5; kernel_geom = astra_create_proj_geom('parallel', 1.0, N, [0]); kernel_id = astra_mex_data2d('create', '-sino', kernel_geom, kernel); -cfg.FilterType = 'rprojection'; -cfg.FilterSinogramId = kernel_id; +cfg.option.FilterType = 'rprojection'; +cfg.option.FilterSinogramId = kernel_id; alg_id = astra_mex_algorithm('create', cfg); astra_mex_algorithm('run', alg_id); diff --git a/samples/python/s014_FBP.py b/samples/python/s014_FBP.py index f7cefd4..1c3a341 100644 --- a/samples/python/s014_FBP.py +++ b/samples/python/s014_FBP.py @@ -49,7 +49,7 @@ rec_id = astra.data2d.create('-vol', vol_geom) cfg = astra.astra_dict('FBP_CUDA') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id -cfg['FilterType'] = 'Ram-Lak' +cfg['option'] = { 'FilterType': 'Ram-Lak' } # possible values for FilterType: # none, ram-lak, shepp-logan, cosine, hamming, hann, tukey, lanczos, diff --git a/samples/python/s023_FBP_filters.py b/samples/python/s023_FBP_filters.py index 11518ac..a67c338 100644 --- a/samples/python/s023_FBP_filters.py +++ b/samples/python/s023_FBP_filters.py @@ -47,11 +47,12 @@ cfg = astra.astra_dict('FBP') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id cfg['ProjectorId'] = proj_id +cfg['option'] = {} # 1. Use a standard Ram-Lak filter -cfg['FilterType'] = 'ram-lak' +cfg['option']['FilterType'] = 'ram-lak' alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id) @@ -71,8 +72,8 @@ filter = np.reshape(kernel[0:halfFilterSize], (1, halfFilterSize)) filter_geom = astra.create_proj_geom('parallel', 1.0, halfFilterSize, [0]); filter_id = astra.data2d.create('-sino', filter_geom, filter); -cfg['FilterType'] = 'projection' -cfg['FilterSinogramId'] = filter_id +cfg['option']['FilterType'] = 'projection' +cfg['option']['FilterSinogramId'] = filter_id alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id) rec_filter = astra.data2d.get(rec_id) @@ -92,8 +93,8 @@ kernel[0, N//2] = 0.5 kernel_geom = astra.create_proj_geom('parallel', 1.0, N, [0]); kernel_id = astra.data2d.create('-sino', kernel_geom, kernel); -cfg['FilterType'] = 'rprojection' -cfg['FilterSinogramId'] = kernel_id +cfg['option']['FilterType'] = 'rprojection' +cfg['option']['FilterSinogramId'] = kernel_id alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id) rec_kernel = astra.data2d.get(rec_id) diff --git a/src/FilteredBackProjectionAlgorithm.cpp b/src/FilteredBackProjectionAlgorithm.cpp index 67a12a2..ea606f7 100644 --- a/src/FilteredBackProjectionAlgorithm.cpp +++ b/src/FilteredBackProjectionAlgorithm.cpp @@ -92,24 +92,28 @@ void CFilteredBackProjectionAlgorithm::clear() bool CFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) { ASTRA_ASSERT(_cfg.self); + ConfigStackCheck<CAlgorithm> CC("FilteredBackProjectionAlgorithm", this, _cfg); // projector XMLNode node = _cfg.self.getSingleNode("ProjectorId"); ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectorId tag specified."); int id = node.getContentInt(); m_pProjector = CProjector2DManager::getSingleton().get(id); + CC.markNodeParsed("ProjectorId"); // sinogram data node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectionDataId tag specified."); id = node.getContentInt(); m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id)); + CC.markNodeParsed("ProjectionDataId"); // volume data node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ReconstructionDataId tag specified."); id = node.getContentInt(); m_pReconstruction = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); + CC.markNodeParsed("ReconstructionDataId"); node = _cfg.self.getSingleNode("ProjectionIndex"); if (node) @@ -153,6 +157,7 @@ bool CFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) delete[] sinogramData2D; delete[] projectionAngles; } + CC.markNodeParsed("ProjectionIndex"); m_filterConfig = getFilterConfigForAlgorithm(_cfg, this); diff --git a/src/Filters.cpp b/src/Filters.cpp index e756052..8f68202 100644 --- a/src/Filters.cpp +++ b/src/Filters.cpp @@ -443,7 +443,7 @@ struct FilterNameMapEntry { E_FBPFILTER m_type; }; -E_FBPFILTER convertStringToFilter(const char * _filterType) +E_FBPFILTER convertStringToFilter(const std::string &_filterType) { static const FilterNameMapEntry map[] = { @@ -474,10 +474,10 @@ E_FBPFILTER convertStringToFilter(const char * _filterType) const FilterNameMapEntry *i; for (i = &map[0]; i->m_name; ++i) - if (stringCompareLowerCase(_filterType, i->m_name)) + if (stringCompareLowerCase(_filterType.c_str(), i->m_name)) return i->m_type; - ASTRA_ERROR("Failed to convert \"%s\" into a filter.",_filterType); + ASTRA_ERROR("Failed to convert \"%s\" into a filter.",_filterType.c_str()); return FILTER_ERROR; } @@ -489,60 +489,100 @@ SFilterConfig getFilterConfigForAlgorithm(const Config& _cfg, CAlgorithm *_alg) SFilterConfig c; + XMLNode node; + // filter type - XMLNode node = _cfg.self.getSingleNode("FilterType"); - if (node) - c.m_eType = convertStringToFilter(node.getContent().c_str()); - else + const char *nodeName = "FilterType"; + node = _cfg.self.getSingleNode(nodeName); + if (_cfg.self.hasOption(nodeName)) { + c.m_eType = convertStringToFilter(_cfg.self.getOption(nodeName)); + CC.markOptionParsed(nodeName); + } else if (node) { + // Fallback: check cfg.FilterType (instead of cfg.option.FilterType) + c.m_eType = convertStringToFilter(node.getContent()); + CC.markNodeParsed(nodeName); + } else { c.m_eType = FILTER_RAMLAK; - CC.markNodeParsed("FilterType"); + } // filter - node = _cfg.self.getSingleNode("FilterSinogramId"); - if (node) - { - int id = node.getContentInt(); + nodeName = "FilterSinogramId"; + int id = -1; + switch (c.m_eType) { + case FILTER_PROJECTION: + case FILTER_SINOGRAM: + case FILTER_RPROJECTION: + case FILTER_RSINOGRAM: + node = _cfg.self.getSingleNode(nodeName); + if (_cfg.self.hasOption(nodeName)) { + id = _cfg.self.getOptionInt(nodeName); + CC.markOptionParsed(nodeName); + } else if (node) { + id = node.getContentInt(); + CC.markNodeParsed(nodeName); + } + break; + default: + break; + } + + if (id != -1) { const CFloat32ProjectionData2D * pFilterData = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id)); c.m_iCustomFilterWidth = pFilterData->getGeometry()->getDetectorCount(); c.m_iCustomFilterHeight = pFilterData->getGeometry()->getProjectionAngleCount(); c.m_pfCustomFilter = new float[c.m_iCustomFilterWidth * c.m_iCustomFilterHeight]; memcpy(c.m_pfCustomFilter, pFilterData->getDataConst(), sizeof(float) * c.m_iCustomFilterWidth * c.m_iCustomFilterHeight); - } - else - { + } else { c.m_iCustomFilterWidth = 0; c.m_iCustomFilterHeight = 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; + nodeName = "FilterParameter"; + c.m_fParameter = -1.0f; + switch (c.m_eType) { + case FILTER_TUKEY: + case FILTER_GAUSSIAN: + case FILTER_BLACKMAN: + case FILTER_KAISER: + node = _cfg.self.getSingleNode(nodeName); + if (_cfg.self.hasOption(nodeName)) { + c.m_fParameter = _cfg.self.getOptionNumerical(nodeName); + CC.markOptionParsed(nodeName); + } else if (node) { + c.m_fParameter = node.getContentNumerical(); + CC.markNodeParsed(nodeName); + } + break; + default: + break; } - 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; + nodeName = "FilterD"; + c.m_fD = 1.0f; + switch (c.m_eType) { + case FILTER_PROJECTION: + case FILTER_SINOGRAM: + case FILTER_RPROJECTION: + case FILTER_RSINOGRAM: + break; + case FILTER_NONE: + case FILTER_ERROR: + break; + default: + node = _cfg.self.getSingleNode(nodeName); + if (_cfg.self.hasOption(nodeName)) { + c.m_fD = _cfg.self.getOptionNumerical(nodeName); + CC.markOptionParsed(nodeName); + } else if (node) { + c.m_fD = node.getContentNumerical(); + CC.markNodeParsed(nodeName); + } + break; } - CC.markNodeParsed("FilterD"); // TODO: Only for some types! - return c; } |