8 #include "iPenaltyMedianRootPrior.hh" 74 cout <<
"The Median Root Prior (MRP) is implemented for several types of neighborhood. The parameters are described below, and a" << endl;
75 cout <<
"template configuration file for parameters selection can be found in the configuration folder (config/optimizer/MRP.conf)." << endl;
76 cout <<
"The configuration of this penalty can only be done through a configuration file. It is not possible to parameterize it" << endl;
77 cout <<
"directly from the command line. The current implementation is the simplest one, based on the following reference:" << endl;
78 cout <<
"S. Alenius and U Ruotsalainen, \"Bayesian image reconstruction for emission tomography based on the median root prior\"," << endl;
79 cout <<
"European Journal of Nuclear Medicine, vol. 24, pp. 258-265, 1997." << endl;
80 cout <<
"------------" << endl;
81 cout <<
"Neighborhood" << endl;
82 cout <<
"------------" << endl;
83 cout <<
"The neighborhood is set by the 'neighborhood shape' keyword and can be described using one of the following setting:" << endl;
84 cout <<
"[6-nearest]: Consider the 6 nearest neighbors, i.e. 2 along each dimension. In 2D, only 4 in the plane are used." << endl;
85 cout <<
"[box]: Consider all voxels included in a box centered on the voxel of interest. The size of the box is parameterized" << endl;
86 cout <<
" using the 'box neighborhood order' keyword. The side of the box is equal to '2*order+1'. The 8 corner voxels" << endl;
87 cout <<
" can also be excluded from the neighborhood by setting the 'exclude box neighborhood corners' keyword to 1." << endl;
88 cout <<
"[sphere]: Consider all voxels whose center is included in a sphere centered on the voxel of interest and of radius" << endl;
89 cout <<
" provided by the 'sphere neighborhood radius (mm)' keyword." << endl;
100 string key_word =
"";
105 key_word =
"neighborhood shape";
108 Cerr(
"***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
112 if (buffer ==
"sphere")
116 key_word =
"sphere neighborhood radius (mm)";
119 Cerr(
"***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
124 else if (buffer ==
"box")
128 key_word =
"box neighborhood order";
131 Cerr(
"***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
135 key_word =
"exclude box neighborhood corners";
138 Cerr(
"***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
143 else if (buffer ==
"6-nearest")
150 Cerr(
"***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Unknown neighborhood type '" << buffer <<
"' !" << endl);
166 Cerr(
"***** iPenaltyMedianRootPrior::ReadOptionsList() -> Options can be specified only using a configuration file !" << endl);
180 Cerr(
"***** iPenaltyMarkovRandomField::CheckSpecificParameters() -> Should provide a neighborhood type !" << endl);
186 Cerr(
"***** iPenaltyMarkovRandomField::CheckSpecificParameters() -> Provided radius of the sphere neighborhood (" <<
m_neighborhoodSphereRadius <<
") is negative" << endl);
191 Cerr(
"***** iPenaltyMarkovRandomField::CheckSpecificParameters() -> Provided order of the box neighborhood (" <<
m_neighborhoodBoxOrder <<
") is negative" << endl);
208 Cerr(
"***** iPenaltyMedianRootPrior::InitializeSpecific() -> Failed to build the neighborhood !" << endl);
223 Cout(
"iPenaltyMedianRootPrior::InitializeSpecific() -> Use the Median Root Prior" << endl);
229 Cout(
" --> shape of neighborhood: sphere" << endl);
234 Cout(
" --> shape of neighborhood: box" << endl);
240 Cout(
" --> shape of neighborhood: 6-nearest" << endl);
242 Cout(
" --> Max number of voxels in the neighborhood: " << m_neighborhoodMaxNbVoxels << endl);
260 Cerr(
"***** iPenaltyMedianRootPrior::BuildNeighborhoodKernel() -> Neighborhood kernel has already been created !" << endl);
284 m_neighborhoodMaxNbVoxels = (radius_vox_x*2+1) * (radius_vox_y*2+1) * (radius_vox_z*2+1);
289 INTNB nb_voxels_in_neighborhood = 0;
291 for (
INTNB vox_z = -radius_vox_z; vox_z<=radius_vox_z; vox_z++)
292 for (
INTNB vox_y = -radius_vox_y; vox_y<=radius_vox_y; vox_y++)
293 for (
INTNB vox_x = -radius_vox_x; vox_x<=radius_vox_x; vox_x++)
296 FLTNB squareDistance = ((
FLTNB)(vox_x*vox_x))*vox_size_x*vox_size_x
297 + ((
FLTNB)(vox_y*vox_y))*vox_size_y*vox_size_y
298 + ((
FLTNB)(vox_z*vox_z))*vox_size_z*vox_size_z;
305 nb_voxels_in_neighborhood++;
309 m_neighborhoodMaxNbVoxels = nb_voxels_in_neighborhood;
326 INTNB nb_voxels_in_neighborhood = 0;
328 for (
INTNB vox_z = -neighborhood_box_order_z; vox_z<=neighborhood_box_order_z; vox_z++)
340 nb_voxels_in_neighborhood++;
344 m_neighborhoodMaxNbVoxels = nb_voxels_in_neighborhood;
353 m_neighborhoodMaxNbVoxels = 7;
376 Cerr(
"***** iPenaltyMedianRootPrior::BuildNeighborhoodKernel() -> The provided shape of neighborhood (" <<
m_neighborhoodShape <<
") is unknown !" << endl);
396 INTNB index_x = a_voxel % nb_vox_x;
397 INTNB index_y = (a_voxel/nb_vox_x) % nb_vox_y;
398 INTNB index_z = a_voxel / nb_vox_xy;
408 INTNB neighbor_xyz = neighbor_x + neighbor_y*nb_vox_x + neighbor_z*nb_vox_xy;
410 if ( neighbor_x>=0 && neighbor_x<nb_vox_x && neighbor_y>=0 && neighbor_y<nb_vox_y && neighbor_z>=0 && neighbor_z<nb_vox_z && !mp_ImageDimensionsAndQuantification->IsVoxelMasked(neighbor_xyz) )
437 Cerr(
"***** iPenaltyMedianRootPrior::LocalPreProcessingStep() -> A problem occurred while building specific neighborhood of voxel " << a_voxel <<
" !" << endl);
443 Cerr(
"***** iPenaltyMedianRootPrior::LocalPreProcessingStep() -> A problem occurred while computing the median in neighborhood of voxel " << a_voxel <<
" !" << endl);
459 [a_voxel,a_tbf,a_rbf,a_cbf,a_th,
this](
INTNB i1,
INTNB i2)
462 if (i1 == -1)
return false;
463 if (i2 == -1)
return true;
509 FLTNB first_derivative = 0.;
512 return first_derivative;
524 FLTNB second_derivative = 0.;
527 return second_derivative;
int m_penaltyDerivativesOrder
FLTNB GetVoxSizeX()
Get the voxel's size along the X axis, in mm.
FLTNB GetVoxSizeZ()
Get the voxel's size along the Z axis, in mm.
#define MRF_NEIGHBORHOOD_BOX
#define MRF_NEIGHBORHOOD_SPHERE
FLTNB GetVoxSizeY()
Get the voxel's size along the Y axis, in mm.
INTNB GetNbVoxXY()
Get the number of voxels in a slice.
This class is designed to generically described any penalty applied to MAP algorithms.
#define KEYWORD_MANDATORY
int GetNbThreadsForImageComputation()
Get the number of threads used for image operations.
INTNB GetNbVoxX()
Get the number of voxels along the X axis.
INTNB GetNbVoxZ()
Get the number of voxels along the Z axis.
#define MRF_NEIGHBORHOOD_6_NEAREST
int ReadDataASCIIFile(const string &a_file, const string &a_keyword, T *ap_return, int a_nbElts, bool a_mandatoryFlag)
Look for "a_nbElts" elts in the "a_file" file matching the "a_keyword" string passed as parameter a...
oImageSpace * mp_ImageSpace
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
INTNB GetNbVoxY()
Get the number of voxels along the Y axis.
#define KEYWORD_OPTIONAL_ERROR