summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/astra/Filters.h4
-rw-r--r--samples/matlab/s014_FBP.m2
-rw-r--r--samples/matlab/s023_FBP_filters.m10
-rw-r--r--samples/python/s014_FBP.py2
-rw-r--r--samples/python/s023_FBP_filters.py11
-rw-r--r--src/FilteredBackProjectionAlgorithm.cpp5
-rw-r--r--src/Filters.cpp114
7 files changed, 98 insertions, 50 deletions
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/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;
}