CASToR  3.0
Tomographic Reconstruction (PET/SPECT/CT)
iPenaltyMedianRootPrior.cc
Go to the documentation of this file.
1 /*
2 This file is part of CASToR.
3 
4  CASToR is free software: you can redistribute it and/or modify it under the
5  terms of the GNU General Public License as published by the Free Software
6  Foundation, either version 3 of the License, or (at your option) any later
7  version.
8 
9  CASToR is distributed in the hope that it will be useful, but WITHOUT ANY
10  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  details.
13 
14  You should have received a copy of the GNU General Public License along with
15  CASToR (in file GNU_GPL.TXT). If not, see <http://www.gnu.org/licenses/>.
16 
17 Copyright 2017-2019 all CASToR contributors listed below:
18 
19  --> Didier BENOIT, Claude COMTAT, Marina FILIPOVIC, Thibaut MERLIN, Mael MILLARDET, Simon STUTE, Valentin VIELZEUF
20 
21 This is CASToR version 3.0.
22 */
23 
31 
32 // =====================================================================
33 // ---------------------------------------------------------------------
34 // ---------------------------------------------------------------------
35 // =====================================================================
36 
38 {
39  // --------------------------
40  // Specific member parameters
41  // --------------------------
46  m_neighborhoodBoxExcludeCorners = 0; // Keep them by default
50  mp_medianValue = NULL;
51  // Derivative order is infinite
52  m_penaltyDerivativesOrder = INT_MAX;
53 }
54 
55 // =====================================================================
56 // ---------------------------------------------------------------------
57 // ---------------------------------------------------------------------
58 // =====================================================================
59 
61 {
62  // Destroy mp_neighborhoodNbVoxels
64  {
66  }
67  // Destroy m2p_neighborhoodIndices
69  {
71  {
73  }
75  }
76  // Destroy m2p_neighborhoodKernel
78  {
79  for (INTNB v=0; v<m_neighborhoodMaxNbVoxels; v++)
80  {
82  }
84  }
85  // Destroy mp_medianValue
86  if (mp_medianValue) free(mp_medianValue);
87 }
88 
89 // =====================================================================
90 // ---------------------------------------------------------------------
91 // ---------------------------------------------------------------------
92 // =====================================================================
93 
95 {
96  cout << "The Median Root Prior (MRP) is implemented for several types of neighborhood. The parameters are described below, and a" << endl;
97  cout << "template configuration file for parameters selection can be found in the configuration folder (config/optimizer/MRP.conf)." << endl;
98  cout << "The configuration of this penalty can only be done through a configuration file. It is not possible to parameterize it" << endl;
99  cout << "directly from the command line. The current implementation is the simplest one, based on the following reference:" << endl;
100  cout << "S. Alenius and U Ruotsalainen, \"Bayesian image reconstruction for emission tomography based on the median root prior\"," << endl;
101  cout << "European Journal of Nuclear Medicine, vol. 24, pp. 258-265, 1997." << endl;
102  cout << "------------" << endl;
103  cout << "Neighborhood" << endl;
104  cout << "------------" << endl;
105  cout << "The neighborhood is set by the 'neighborhood shape' keyword and can be described using one of the following setting:" << endl;
106  cout << "[6-nearest]: Consider the 6 nearest neighbors, i.e. 2 along each dimension. In 2D, only 4 in the plane are used." << endl;
107  cout << "[box]: Consider all voxels included in a box centered on the voxel of interest. The size of the box is parameterized" << endl;
108  cout << " using the 'box neighborhood order' keyword. The side of the box is equal to '2*order+1'. The 8 corner voxels" << endl;
109  cout << " can also be excluded from the neighborhood by setting the 'exclude box neighborhood corners' keyword to 1." << endl;
110  cout << "[sphere]: Consider all voxels whose center is included in a sphere centered on the voxel of interest and of radius" << endl;
111  cout << " provided by the 'sphere neighborhood radius (mm)' keyword." << endl;
112 }
113 
114 // =====================================================================
115 // ---------------------------------------------------------------------
116 // ---------------------------------------------------------------------
117 // =====================================================================
118 
119 int iPenaltyMedianRootPrior::ReadConfigurationFile(const string& a_configurationFile)
120 {
121  string buffer = "";
122  string key_word = "";
123 
124  // -------------------------------------------------------------------
125  // Read the type of neighborhood
126  // -------------------------------------------------------------------
127  key_word = "neighborhood shape";
128  if (ReadDataASCIIFile(a_configurationFile, key_word, &buffer, 1, KEYWORD_MANDATORY))
129  {
130  Cerr("***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
131  return 1;
132  }
133  // Sphere neighborhood
134  if (buffer == "sphere")
135  {
137  // Radius of the sphere
138  key_word = "sphere neighborhood radius (mm)";
139  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_neighborhoodSphereRadius, 1, KEYWORD_MANDATORY))
140  {
141  Cerr("***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
142  return 1;
143  }
144  }
145  // Box neighborhood
146  else if (buffer == "box")
147  {
149  // Order of the box (number of voxels which will be included in each direction)
150  key_word = "box neighborhood order";
151  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_neighborhoodBoxOrder, 1, KEYWORD_MANDATORY))
152  {
153  Cerr("***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
154  return 1;
155  }
156  // Include corners of the box or not (some people do that) (not mandatory as we keep them by default)
157  key_word = "exclude box neighborhood corners";
159  {
160  Cerr("***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
161  return 1;
162  }
163  }
164  // 6-nearest
165  else if (buffer == "6-nearest")
166  {
168  }
169  // Unknown
170  else
171  {
172  Cerr("***** iPenaltyMedianRootPrior::ReadConfigurationFile() -> Unknown neighborhood type '" << buffer << "' !" << endl);
173  return 1;
174  }
175 
176  // Normal end
177  return 0;
178 }
179 
180 // =====================================================================
181 // ---------------------------------------------------------------------
182 // ---------------------------------------------------------------------
183 // =====================================================================
184 
185 int iPenaltyMedianRootPrior::ReadOptionsList(const string& a_optionsList)
186 {
187  // To complicated to do it that way
188  Cerr("***** iPenaltyMedianRootPrior::ReadOptionsList() -> Options can be specified only using a configuration file !" << endl);
189  return 1;
190 }
191 
192 // =====================================================================
193 // ---------------------------------------------------------------------
194 // ---------------------------------------------------------------------
195 // =====================================================================
196 
198 {
199  // Check neighborhood type
201  {
202  Cerr("***** iPenaltyMarkovRandomField::CheckSpecificParameters() -> Should provide a neighborhood type !" << endl);
203  return 1;
204  }
205  // Check some parameters of the neighborhood
207  {
208  Cerr("***** iPenaltyMarkovRandomField::CheckSpecificParameters() -> Provided radius of the sphere neighborhood (" << m_neighborhoodSphereRadius << ") is negative" << endl);
209  return 1;
210  }
212  {
213  Cerr("***** iPenaltyMarkovRandomField::CheckSpecificParameters() -> Provided order of the box neighborhood (" << m_neighborhoodBoxOrder << ") is negative" << endl);
214  return 1;
215  }
216  // Normal end
217  return 0;
218 }
219 
220 // =====================================================================
221 // ---------------------------------------------------------------------
222 // ---------------------------------------------------------------------
223 // =====================================================================
224 
226 {
227  // Build the neighborhood kernel that will be used to facilitate the computation of the neighborhood of each voxel later on
229  {
230  Cerr("***** iPenaltyMedianRootPrior::InitializeSpecific() -> Failed to build the neighborhood !" << endl);
231  return 1;
232  }
233  // Some allocations for the specific neighborhood of each voxel used during computations
237  {
239  }
240  // Allocate the table to store median values for each thread
242  // Verbose
244  {
245  Cout("iPenaltyMedianRootPrior::InitializeSpecific() -> Use the Median Root Prior" << endl);
247  {
248  // Type of neighborhood
250  {
251  Cout(" --> shape of neighborhood: sphere" << endl);
252  Cout(" --> radius of the sphere neighborhood: " << m_neighborhoodSphereRadius << " mm " << endl);
253  }
255  {
256  Cout(" --> shape of neighborhood: box" << endl);
257  Cout(" --> order of the box (number of voxels in each direction): " << m_neighborhoodBoxOrder << endl);
258  if (m_neighborhoodBoxExcludeCorners) Cout(" --> exclude corner voxels" << endl);
259  }
261  {
262  Cout(" --> shape of neighborhood: 6-nearest" << endl);
263  }
264  Cout(" --> Max number of voxels in the neighborhood: " << m_neighborhoodMaxNbVoxels << endl);
265  Cout(" --> penalty energy function derivatives order: " << m_penaltyDerivativesOrder << endl);
266  }
267  }
268  // Normal end
269  return 0;
270 }
271 
272 // =====================================================================
273 // ---------------------------------------------------------------------
274 // ---------------------------------------------------------------------
275 // =====================================================================
276 
278 {
279  // Check if the neighborhood has already been created
281  {
282  Cerr("***** iPenaltyMedianRootPrior::BuildNeighborhoodKernel() -> Neighborhood kernel has already been created !" << endl);
283  return 1;
284  }
285  // Get voxel sizes locally
289  // ========================================================================================================
290  // Note
291  // ========================================================================================================
292  // As opposed to the markov random fields in which we discard the voxel itself from its neighborhood,
293  // when computing the median in MRP, the voxel itself is included in the neighborhood.
294  // ========================================================================================================
295  // Case where the neighborhood is defined by a sphere with radius provided in mm
296  // ========================================================================================================
298  {
299  // Compute the size of the box including the sphere (minimum of 1 voxel radius)
300  INTNB radius_vox_x = max( (INTNB)1 , ((INTNB)(m_neighborhoodSphereRadius/vox_size_x)) );
301  INTNB radius_vox_y = max( (INTNB)1 , ((INTNB)(m_neighborhoodSphereRadius/vox_size_y)) );
302  INTNB radius_vox_z = max( (INTNB)1 , ((INTNB)(m_neighborhoodSphereRadius/vox_size_z)) );
303  // Particular case for 2D reconstruction
304  if (mp_ImageDimensionsAndQuantification->GetNbVoxZ()==1) radius_vox_z = 0;
305  // Precompute the maximum number of voxels in the neighborhood as the box including the sphere
306  m_neighborhoodMaxNbVoxels = (radius_vox_x*2+1) * (radius_vox_y*2+1) * (radius_vox_z*2+1);
307  // Allocate the neighborhood kernel
309  for (INTNB v = 0; v<m_neighborhoodMaxNbVoxels; v++) m2p_neighborhoodKernel[v] = (INTNB*)malloc(3*sizeof(INTNB));
310  // Counter for the number of voxels in the neighborhood
311  INTNB nb_voxels_in_neighborhood = 0;
312  // Loop on increments of voxels indices in box neighborhood
313  for (INTNB vox_z = -radius_vox_z; vox_z<=radius_vox_z; vox_z++)
314  for (INTNB vox_y = -radius_vox_y; vox_y<=radius_vox_y; vox_y++)
315  for (INTNB vox_x = -radius_vox_x; vox_x<=radius_vox_x; vox_x++)
316  {
317  // Compute the square distance between the two voxels
318  FLTNB squareDistance = ((FLTNB)(vox_x*vox_x))*vox_size_x*vox_size_x
319  + ((FLTNB)(vox_y*vox_y))*vox_size_y*vox_size_y
320  + ((FLTNB)(vox_z*vox_z))*vox_size_z*vox_size_z;
321  // Include voxel if the distance from the central voxel is less than the radius
323  {
324  m2p_neighborhoodKernel[nb_voxels_in_neighborhood][MRF_NEIGHBOR_X] = vox_x;
325  m2p_neighborhoodKernel[nb_voxels_in_neighborhood][MRF_NEIGHBOR_Y] = vox_y;
326  m2p_neighborhoodKernel[nb_voxels_in_neighborhood][MRF_NEIGHBOR_Z] = vox_z;
327  nb_voxels_in_neighborhood++;
328  }
329  }
330  // Update the maximum number of voxels in the neighborhood by the exact value
331  m_neighborhoodMaxNbVoxels = nb_voxels_in_neighborhood;
332  m2p_neighborhoodKernel = (INTNB**)realloc(m2p_neighborhoodKernel,m_neighborhoodMaxNbVoxels*sizeof(INTNB*));
333  }
334  // ========================================================================================================
335  // Case where the neighborhood is defined by a box as described in many papers
336  // ========================================================================================================
338  {
339  // Particular case for 2D reconstruction
340  INTNB neighborhood_box_order_z = m_neighborhoodBoxOrder;
341  if (mp_ImageDimensionsAndQuantification->GetNbVoxZ()==1) neighborhood_box_order_z = 0;
342  // Maximum number of voxels in the neighborhood of a voxel with no image boundary constraints
344  // Allocate the neighborhood kernel
346  for (INTNB v = 0; v<m_neighborhoodMaxNbVoxels; v++) m2p_neighborhoodKernel[v] = (INTNB*)malloc(3*sizeof(INTNB));
347  // Counter for the number of voxels in the neighborhood
348  INTNB nb_voxels_in_neighborhood = 0;
349  // Loop on increments of voxels indices in the box neighborhood
350  for (INTNB vox_z = -neighborhood_box_order_z; vox_z<=neighborhood_box_order_z; vox_z++)
351  for (INTNB vox_y = -m_neighborhoodBoxOrder; vox_y<=m_neighborhoodBoxOrder; vox_y++)
352  for (INTNB vox_x = -m_neighborhoodBoxOrder; vox_x<=m_neighborhoodBoxOrder; vox_x++)
353  {
354  // Exclude corner voxels if requested
356  || (vox_y!=-m_neighborhoodBoxOrder && vox_y!=m_neighborhoodBoxOrder)
357  || (vox_z!=-m_neighborhoodBoxOrder && vox_z!=m_neighborhoodBoxOrder))
358  {
359  m2p_neighborhoodKernel[nb_voxels_in_neighborhood][MRF_NEIGHBOR_X] = vox_x;
360  m2p_neighborhoodKernel[nb_voxels_in_neighborhood][MRF_NEIGHBOR_Y] = vox_y;
361  m2p_neighborhoodKernel[nb_voxels_in_neighborhood][MRF_NEIGHBOR_Z] = vox_z;
362  nb_voxels_in_neighborhood++;
363  }
364  }
365  // Update the maximum number of voxels in the neighborhood by the exact value
366  m_neighborhoodMaxNbVoxels = nb_voxels_in_neighborhood;
367  m2p_neighborhoodKernel = (INTNB**)realloc(m2p_neighborhoodKernel,m_neighborhoodMaxNbVoxels*sizeof(INTNB*));
368  }
369  // ========================================================================================================
370  // Case where the neighborhood is defined simply by the 6-nearest neighbors
371  // ========================================================================================================
373  {
374  // Maximum number of voxels in the neighborhood is 6 + 1 (the voxel itself)
376  // Particular case for 2D reconstruction
378  // Allocate the neighborhood kernel
380  for (INTNB v = 0; v<m_neighborhoodMaxNbVoxels; v++) m2p_neighborhoodKernel[v] = (INTNB*)malloc(3*sizeof(INTNB));
381  // The 7 voxels
382  for (INTNB v=0; v<m_neighborhoodMaxNbVoxels; v++) for (INTNB dim=0; dim<3; dim++) m2p_neighborhoodKernel[v][dim] = 0;
388  {
391  }
392  }
393  // ========================================================================================================
394  // Unknown neighborhood type
395  // ========================================================================================================
396  else
397  {
398  Cerr("***** iPenaltyMedianRootPrior::BuildNeighborhoodKernel() -> The provided shape of neighborhood (" << m_neighborhoodShape << ") is unknown !" << endl);
399  return 1;
400  }
401  // Normal end
402  return 0;
403 }
404 
405 // =====================================================================
406 // ---------------------------------------------------------------------
407 // ---------------------------------------------------------------------
408 // =====================================================================
409 
411 {
412  // Get number of voxels locally for code readability
417  // Compute the X, Y and Z components of the current voxel
418  INTNB index_x = a_voxel % nb_vox_x;
419  INTNB index_y = (a_voxel/nb_vox_x) % nb_vox_y;
420  INTNB index_z = a_voxel / nb_vox_xy;
421  // Count the number of valid neighbors
422  mp_neighborhoodNbVoxels[a_th] = 0;
423  // Loop on all possible neighbors in the kernel
424  for (INTNB neigh = 0; neigh<m_neighborhoodMaxNbVoxels; neigh++)
425  {
426  // Compute X, Y and Z indices of this potential neighbor
427  INTNB neighbor_x = index_x + m2p_neighborhoodKernel[neigh][MRF_NEIGHBOR_X];
428  INTNB neighbor_y = index_y + m2p_neighborhoodKernel[neigh][MRF_NEIGHBOR_Y];
429  INTNB neighbor_z = index_z + m2p_neighborhoodKernel[neigh][MRF_NEIGHBOR_Z];
430  // Check if the neighbour is inside the image
431  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 )
432  {
433  // Add the global index of this neighbor to the neighborhood list
434  m2p_neighborhoodIndices[a_th][neigh] = neighbor_x + neighbor_y*nb_vox_x + neighbor_z*nb_vox_xy;
435  // One more neighbor
436  mp_neighborhoodNbVoxels[a_th]++;
437  }
438  // Otherwise, discard it by setting -1
439  else
440  {
441  m2p_neighborhoodIndices[a_th][neigh] = -1;
442  }
443  }
444  // Normal end
445  return 0;
446 }
447 
448 // =====================================================================
449 // ---------------------------------------------------------------------
450 // ---------------------------------------------------------------------
451 // =====================================================================
452 
453 int iPenaltyMedianRootPrior::LocalPreProcessingStep(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
454 {
455  // First build the list of neighbours of this voxel
456  if (BuildSpecificNeighborhood(a_voxel,a_th))
457  {
458  Cerr("***** iPenaltyMedianRootPrior::LocalPreProcessingStep() -> A problem occurred while building specific neighborhood of voxel " << a_voxel << " !" << endl);
459  return 1;
460  }
461  // Compute the median value in this neighborhood
462  if (ComputeMedianInNeighborhood(a_tbf,a_rbf,a_cbf,a_voxel,a_th))
463  {
464  Cerr("***** iPenaltyMedianRootPrior::LocalPreProcessingStep() -> A problem occurred while computing the median in neighborhood of voxel " << a_voxel << " !" << endl);
465  return 1;
466  }
467  // Normal end
468  return 0;
469 }
470 
471 // =====================================================================
472 // ---------------------------------------------------------------------
473 // ---------------------------------------------------------------------
474 // =====================================================================
475 
476 int iPenaltyMedianRootPrior::ComputeMedianInNeighborhood(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
477 {
478  // Sort the neighborhood indices according to increasing intensity values
480  [a_voxel,a_tbf,a_rbf,a_cbf,a_th,this](INTNB i1, INTNB i2)
481  {
482  // This two lines pushes the -1 indices (voxels out of image) at the end
483  if (i1 == -1) return false;
484  if (i2 == -1) return true;
485  return mp_ImageSpace->m4p_image[a_tbf][a_rbf][a_cbf][i1] < mp_ImageSpace->m4p_image[a_tbf][a_rbf][a_cbf][i2];
486  });
487  // There can be an even number of voxels if we are near the border of the image (restrained neighborhood)
488  if (mp_neighborhoodNbVoxels[a_th]%2==0)
489  {
490  // In this case, we take the mean of the tow median voxels
491  mp_medianValue[a_th] = (mp_ImageSpace->m4p_image[a_tbf][a_rbf][a_cbf][m2p_neighborhoodIndices[a_th][mp_neighborhoodNbVoxels[a_th]/2]]
492  + mp_ImageSpace->m4p_image[a_tbf][a_rbf][a_cbf][m2p_neighborhoodIndices[a_th][mp_neighborhoodNbVoxels[a_th]/2-1]])
493  * 0.5;
494  }
495  // Even number of voxels
496  else
497  {
498  // The median is in the middle
499  mp_medianValue[a_th] = mp_ImageSpace->m4p_image[a_tbf][a_rbf][a_cbf][m2p_neighborhoodIndices[a_th][mp_neighborhoodNbVoxels[a_th]/2]];
500  }
501  // Normal end
502  return 0;
503 }
504 
505 // =====================================================================
506 // ---------------------------------------------------------------------
507 // ---------------------------------------------------------------------
508 // =====================================================================
509 
510 FLTNB iPenaltyMedianRootPrior::ComputePenaltyValue(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
511 {
512  // Compute the value of the penalty
513  FLTNB penalty = 0.;
514  if (mp_medianValue[a_th]!=0.) penalty = m_penaltyStrength * 0.5
515  * (mp_ImageSpace->m4p_image[a_tbf][a_rbf][a_cbf][a_voxel]-mp_medianValue[a_th])
516  * (mp_ImageSpace->m4p_image[a_tbf][a_rbf][a_cbf][a_voxel]-mp_medianValue[a_th])
517  / mp_medianValue[a_th];
518  // Return result
519  return penalty;
520 }
521 
522 // =====================================================================
523 // ---------------------------------------------------------------------
524 // ---------------------------------------------------------------------
525 // =====================================================================
526 
527 FLTNB iPenaltyMedianRootPrior::ComputeFirstDerivative(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
528 {
529  // Compute the first derivative
530  FLTNB first_derivative = 0.;
531  if (mp_medianValue[a_th]!=0.) first_derivative = m_penaltyStrength * (mp_ImageSpace->m4p_image[a_tbf][a_rbf][a_cbf][a_voxel]-mp_medianValue[a_th])
532  / mp_medianValue[a_th];
533  return first_derivative;
534 }
535 
536 
537 // =====================================================================
538 // ---------------------------------------------------------------------
539 // ---------------------------------------------------------------------
540 // =====================================================================
541 
542 FLTNB iPenaltyMedianRootPrior::ComputeSecondDerivative(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
543 {
544  // Compute the second derivative of the penalty
545  FLTNB second_derivative = 0.;
546  if (mp_medianValue[a_th]!=0.) second_derivative = m_penaltyStrength / mp_medianValue[a_th];
547  // Return result
548  return second_derivative;
549 }
int m_penaltyDerivativesOrder
Definition: vPenalty.hh:293
#define FLTNB
Definition: gVariables.hh:81
oImageSpace * mp_ImageSpace
Definition: vPenalty.hh:289
FLTNB GetVoxSizeX()
Get the voxel&#39;s size along the X axis, in mm.
FLTNB GetVoxSizeZ()
Get the voxel&#39;s size along the Z axis, in mm.
int BuildSpecificNeighborhood(INTNB a_voxel, int a_th)
FLTNB ComputePenaltyValue(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
Implementation of the pure virtual vPenalty::ComputePenaltyValue()
#define VERBOSE_DETAIL
int ReadOptionsList(const string &a_optionsList)
A function used to read options from a list of options.
void ShowHelpSpecific()
A function used to show help about the child penalty.
FLTNB m_penaltyStrength
Definition: vPenalty.hh:294
~iPenaltyMedianRootPrior()
The destructor of iPenaltyMedianRootPrior.
int InitializeSpecific()
This function is used to initialize specific stuff to the child penalty.
#define MRF_NEIGHBOR_Y
#define MRF_NEIGHBORHOOD_SPHERE
int CheckSpecificParameters()
A private function used to check the parameters settings specific to the child penalty.
int LocalPreProcessingStep(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
A public function computing a local pre-processing step for the penalty.
int m_verbose
Definition: vPenalty.hh:291
FLTNB ComputeFirstDerivative(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
Implementation of the pure virtual vPenalty::ComputeFirstDerivative()
FLTNB GetVoxSizeY()
Get the voxel&#39;s size along the Y axis, in mm.
#define Cerr(MESSAGE)
FLTNB **** m4p_image
Definition: oImageSpace.hh:80
int ReadConfigurationFile(const string &a_configurationFile)
A function used to read options from a configuration file.
Declaration of class iPenaltyMedianRootPrior.
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
Definition: vPenalty.hh:288
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...
Definition: gOptions.cc:129
FLTNB ComputeSecondDerivative(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
Implementation of the pure virtual vPenalty::ComputeSecondDerivative()
#define MRF_NOT_DEFINED
INTNB GetNbVoxXY()
Get the number of voxels in a slice.
This class is designed to generically described any penalty applied to MAP algorithms.
Definition: vPenalty.hh:48
#define VERBOSE_NORMAL
#define MRF_NEIGHBOR_Z
#define KEYWORD_MANDATORY
Definition: gOptions.hh:47
#define KEYWORD_OPTIONAL
Definition: gOptions.hh:49
#define INTNB
Definition: gVariables.hh:92
int ComputeMedianInNeighborhood(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
A private function computing the median in the neighborhood of the provided index.
#define MRF_NEIGHBOR_X
int GetNbThreadsForImageComputation()
Get the number of threads used for image operations.
iPenaltyMedianRootPrior()
The constructor of iPenaltyMedianRootPrior.
#define MRF_NEIGHBORHOOD_BOX
INTNB GetNbVoxX()
Get the number of voxels along the X axis.
INTNB GetNbVoxZ()
Get the number of voxels along the Z axis.
#define Cout(MESSAGE)
#define MRF_NEIGHBORHOOD_6_NEAREST
int BuildNeighborhoodKernel()
A function used to build the neighborhood kernel.
INTNB GetNbVoxY()
Get the number of voxels along the Y axis.
#define KEYWORD_OPTIONAL_ERROR
Definition: gOptions.hh:55