CASToR  2.0
Tomographic Reconstruction (PET/SPECT/CT)
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
oImageConvolverManager.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-2018 all CASToR contributors listed below:
18 
19  --> current contributors: Thibaut MERLIN, Simon STUTE, Didier BENOIT, Claude COMTAT, Marina FILIPOVIC, Mael MILLARDET
20  --> past contributors: Valentin VIELZEUF
21 
22 This is CASToR version 2.0.
23 */
24 
32 #include "sAddonManager.hh"
33 
34 // =====================================================================
35 // ---------------------------------------------------------------------
36 // ---------------------------------------------------------------------
37 // =====================================================================
38 
40 {
41  // Image dimensions
43  // Options
44  m_options = {};
45  // Image convolver objects and associated bool
47  m2p_ImageConvolvers = NULL;
48  mp_applyForward = NULL;
49  mp_applyBackward = NULL;
50  mp_applyIntra = NULL;
51  mp_applyPost = NULL;
52  // Booleans
53  m_checked = false;
54  m_initialized = false;
55  // Verbosity
56  m_verbose = -1;
57 }
58 
59 // =====================================================================
60 // ---------------------------------------------------------------------
61 // ---------------------------------------------------------------------
62 // =====================================================================
63 
65 {
66  // Delete object
68  {
69  for (int c=0; c<m_nbImageConvolvers; c++) if (m2p_ImageConvolvers[c]) delete m2p_ImageConvolvers[c];
70  free(m2p_ImageConvolvers);
71  }
72 }
73 
74 // =====================================================================
75 // ---------------------------------------------------------------------
76 // ---------------------------------------------------------------------
77 // =====================================================================
78 
80 {
81  // Check image dimensions
83  {
84  Cerr("***** oImageConvolverManager::CheckParameters() -> No image dimensions provided !" << endl);
85  return 1;
86  }
87  // Check verbosity
88  if (m_verbose<0)
89  {
90  Cerr("***** oImageConvolverManager::CheckParameters() -> Wrong verbosity level provided !" << endl);
91  return 1;
92  }
93  // All set
94  m_checked = true;
95  // Normal end
96  return 0;
97 }
98 
99 // =====================================================================
100 // ---------------------------------------------------------------------
101 // ---------------------------------------------------------------------
102 // =====================================================================
103 
105 {
106  // Return when using MPI and mpi_rank is not 0
107  #ifdef CASTOR_MPI
108  int mpi_rank = 0;
109  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
110  if (mpi_rank!=0) return;
111  #endif
112  // Show help
113  cout << "------------------------------------------------------------------" << endl;
114  cout << "----- How to use an image convolver" << endl;
115  cout << "------------------------------------------------------------------" << endl;
116  cout << endl;
117  cout << "An image convolver is called through the -conv option. The provided argument describes the convolver to be used, its options," << endl;
118  cout << "and when to include it within the algorithm. The syntax of the argument must obey one of the three following options:" << endl;
119  cout << " conv::when (in this case, the default configuration file of the convolver is used to set the options values)" << endl;
120  cout << " conv:file.conf::when (in this case, the provided configuration is used)" << endl;
121  cout << " conv,param1,param2,...::when (in this case, the options values are directly provided in the argument)" << endl;
122  cout << "In any case, the description of the options specific to each convolver, their order in the list and their configuration" << endl;
123  cout << "files syntax are provided in the specific help of each convolver." << endl;
124  cout << "The 'when' parameter is an argument describing when to include the convolver within the algorithm. It is a list of keywords" << endl;
125  cout << "separating by commas. The following keywords can be used:" << endl;
126  cout << " forward (include convolver into forward model; a convolution of the current estimate is forward-projected)" << endl;
127  cout << " backward (include convolver into backward model; a convolution of the correction terms is used for the update)" << endl;
128  cout << " post (apply convolver before saving the image; the convolved image is not put back as the estimate for the next update)" << endl;
129  cout << " psf (include both 'forward' and 'backward'; the standard image-based PSF modelling)" << endl;
130  cout << " sieve (include both 'psf' and 'post'; the standard method of sieve)" << endl;
131  cout << " intra (apply convolver to the updated image and use it as the current estimate for the next update)" << endl;
132  cout << endl;
133 }
134 
135 // =====================================================================
136 // ---------------------------------------------------------------------
137 // ---------------------------------------------------------------------
138 // =====================================================================
139 
141 {
142  // Check if parameters have been checked
143  if (!m_checked)
144  {
145  Cerr("***** oImageConvolverManager::Initialize() -> Parameters have not been checked ! Please call CheckParameters() before." << endl);
146  return 1;
147  }
148  // Case with no options (no convolver)
149  if (m_options.size()==0)
150  {
151  m_initialized = true;
152  return 0;
153  }
154  // Verbose
155  if (m_verbose>=1) Cout("oImageConvolverManager::Initialize() -> Initialize image convolvers" << endl);
156  // Parse image convolver options and initialize them
158  {
159  Cerr("***** oImageConvolverManager::Initialize() -> A problem occured while parsing image convolvers options and initializing them !" << endl);
160  return 1;
161  }
162  // All set
163  m_initialized = true;
164  // Normal end
165  return 0;
166 }
167 
168 // =====================================================================
169 // ---------------------------------------------------------------------
170 // ---------------------------------------------------------------------
171 // =====================================================================
172 
174 {
175  // ==============================================================
176  // First get the number of convolvers from the list of options
177  // ==============================================================
178 
180 
181  // Allocate the tables
183  mp_applyForward = (bool*)malloc(m_nbImageConvolvers*sizeof(bool));
184  mp_applyBackward = (bool*)malloc(m_nbImageConvolvers*sizeof(bool));
185  mp_applyIntra = (bool*)malloc(m_nbImageConvolvers*sizeof(bool));
186  mp_applyPost = (bool*)malloc(m_nbImageConvolvers*sizeof(bool));
187 
188  // ==============================================================
189  // Then we loop over all convolvers, read options and initialize
190  // ==============================================================
191 
192  // This is for the automatic initialization of the convolvers
193  typedef vImageConvolver *(*maker_image_convolver) ();
194  // Get image convolver's list from addon manager
195  std::map <string,maker_image_convolver> list = sAddonManager::GetInstance()->mp_listOfImageConvolvers;
196 
197  // Start the loop
198  for (int c=0; c<m_nbImageConvolvers; c++)
199  {
200  // Default initializations
201  m2p_ImageConvolvers[c] = NULL;
202  mp_applyForward[c] = false;
203  mp_applyBackward[c] = false;
204  mp_applyIntra[c] = false;
205  mp_applyPost[c] = false;
206 
207  // ___________________________________________________________________________________
208  // Search for a double-colon and isolate the convolver's options from the 'when' actions
209 
210  size_t double_colon = m_options[c].find_first_of("::");
211 
212  // Send an error if no double-colon
213  if (double_colon==string::npos)
214  {
215  Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> Wrong syntax in the " << c+1 << "th image convolver !" << endl);
216  Cerr(" No double-colon \"::\" found." << endl);
217  ShowCommonHelp();
218  return 1;
219  }
220 
221  // Separate the two arguments
222  string conv_part_options = m_options[c].substr(0,double_colon);
223  string when_part_options = m_options[c].substr(double_colon+2);
224 
225  // ___________________________________________________________________________________
226  // Get the image convolver name in the options and isolate the actual image convolver's options
227 
228  // Useful strings
229  string convolver = "";
230  string list_options = "";
231  string file_options = "";
232 
233  // Search for a colon ":", this indicates that a configuration file is provided after the image convolver name
234  size_t colon = conv_part_options.find_first_of(":");
235  size_t comma = conv_part_options.find_first_of(",");
236 
237  // Case 1: we have a colon
238  if (colon!=string::npos)
239  {
240  // Get the image convolver name before the colon
241  convolver = conv_part_options.substr(0,colon);
242  // Get the configuration file after the colon
243  file_options = conv_part_options.substr(colon+1);
244  // List of options is empty
245  list_options = "";
246  }
247  // Case 2: we have a comma
248  else if (comma!=string::npos)
249  {
250  // Get the image convolver name before the first comma
251  convolver = conv_part_options.substr(0,comma);
252  // Get the list of options after the first comma
253  list_options = conv_part_options.substr(comma+1);
254  // Configuration file is empty
255  file_options = "";
256  }
257  // Case 3: no colon and no comma (a single image convolver name)
258  else
259  {
260  // Get the image convolver name
261  convolver = conv_part_options;
262  // List of options is empty
263  list_options = "";
264  // Build the default configuration file
265  file_options = sOutputManager::GetInstance()->GetPathToConfigDir() + "/convolver/" + convolver + ".conf";
266  }
267 
268  // ___________________________________________________________________________________
269  // Read the 'when' actions
270 
271  // Loop while commas are found
272  while ((comma=when_part_options.find_first_of(",")) != string::npos)
273  {
274  // Extract the first option
275  string option = when_part_options.substr(0,comma);
276  // Extract the rest
277  when_part_options = when_part_options.substr(comma+1);
278  // Check the meaning of the option
279  if (option=="forward") {mp_applyForward[c] = true;}
280  else if (option=="backward") {mp_applyBackward[c] = true;}
281  else if (option=="post") {mp_applyPost[c] = true;}
282  else if (option=="psf") {mp_applyForward[c] = true; mp_applyBackward[c] = true;}
283  else if (option=="sieve") {mp_applyForward[c] = true; mp_applyBackward[c] = true; mp_applyPost[c] = true;}
284  else if (option=="intra") {mp_applyIntra[c] = true;}
285  else
286  {
287  Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> Unknown keyword '" << option << "' provided in options list !" << endl);
288  ShowCommonHelp();
289  return 1;
290  }
291  }
292  // Last option
293  if (when_part_options=="forward") {mp_applyForward[c] = true;}
294  else if (when_part_options=="backward") {mp_applyBackward[c] = true;}
295  else if (when_part_options=="post") {mp_applyPost[c] = true;}
296  else if (when_part_options=="psf") {mp_applyForward[c] = true; mp_applyBackward[c] = true;}
297  else if (when_part_options=="sieve") {mp_applyForward[c] = true; mp_applyBackward[c] = true; mp_applyPost[c] = true;}
298  else if (when_part_options=="intra") {mp_applyIntra[c] = true;}
299  else
300  {
301  Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> Unknown keyword '" << when_part_options << "' provided in options list !" << endl);
302  ShowCommonHelp();
303  return 1;
304  }
305 
306  // ______________________________________________________________________________
307  // Create convolver and call associated functions
308 
309  // Create the image convolver
310  if (list[convolver]) m2p_ImageConvolvers[c] = list[convolver]();
311  else
312  {
313  Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> Image convolver '" << convolver << "' does not exist !" << endl);
315  return 1;
316  }
317  // Set parameters
320  // Provide configuration file if any
321  if (file_options!="" && m2p_ImageConvolvers[c]->ReadConfigurationFile(file_options))
322  {
323  Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> A problem occured while reading and checking configuration file for image convolver '" << convolver << "' !" << endl);
324  return 1;
325  }
326  // Provide options if any
327  if (list_options!="" && m2p_ImageConvolvers[c]->ReadOptionsList(list_options))
328  {
329  Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> A problem occured while parsing and reading options list for image convolver '" << convolver << "' !" << endl);
330  return 1;
331  }
332  // Check parameters
334  {
335  Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> A problem occured while checking parameters for image convolver '" << convolver << "' !" << endl);
336  return 1;
337  }
338  // Initialize the image convolver
340  {
341  Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> A problem occured while initializing image convolver '" << convolver << "' !" << endl);
342  return 1;
343  }
344  }
345 
346  // Normal end
347  return 0;
348 }
349 
350 // =====================================================================
351 // ---------------------------------------------------------------------
352 // ---------------------------------------------------------------------
353 // =====================================================================
354 
356 {
357  #ifdef CASTOR_DEBUG
358  // Check if initialized
359  if (!m_initialized)
360  {
361  Cerr("***** oImageConvolverManager::ConvolveForward() -> Called while not initialized !" << endl);
362  return 1;
363  }
364  #endif
365  // Loop on convolvers
366  for (int c=0; c<m_nbImageConvolvers; c++)
367  {
368  // Apply it only if asked for
369  if (mp_applyForward[c])
370  {
371  // Verbose
372  if (m_verbose>=2)
373  {
374  if (m_nbImageConvolvers>1) Cout("oImageConvolverManager::ConvolveForward() -> Apply convolution " << c+1 << " to forward image" << endl);
375  else Cout("oImageConvolverManager::ConvolveForward() -> Apply convolution to forward image" << endl);
376  }
377  // Loop on basis functions
379  {
381  {
383  {
384  // Get the pointer to the image
385  FLTNB* image = ap_ImageSpace->m4p_forwardImage[tb][rb][cb];
386  // Apply convolution
388  }
389  }
390  }
391  }
392  }
393  // Normal end
394  return 0;
395 }
396 
397 // =====================================================================
398 // ---------------------------------------------------------------------
399 // ---------------------------------------------------------------------
400 // =====================================================================
401 
403 {
404  #ifdef CASTOR_DEBUG
405  // Check if initialized
406  if (!m_initialized)
407  {
408  Cerr("***** oImageConvolverManager::ConvolveBackward() -> Called while not initialized !" << endl);
409  return 1;
410  }
411  #endif
412  // Loop on convolvers
413  for (int c=0; c<m_nbImageConvolvers; c++)
414  {
415  // Apply it only if asked for
416  if (mp_applyBackward[c])
417  {
418  // Verbose
419  if (m_verbose>=2)
420  {
421  if (m_nbImageConvolvers>1)
422  {
423  if (ap_ImageSpace->IsLoadedSensitivity()) Cout("oImageConvolverManager::ConvolveBackward() -> Apply convolution " << c+1 << " to backward image" << endl);
424  else Cout("oImageConvolverManager::ConvolveBackward() -> Apply convolution " << c+1 << " to backward and sensitivity images" << endl);
425  }
426  else
427  {
428  if (ap_ImageSpace->IsLoadedSensitivity()) Cout("oImageConvolverManager::ConvolveBackward() -> Apply convolution to backward image" << endl);
429  else Cout("oImageConvolverManager::ConvolveBackward() -> Apply convolution to backward and sensitivity images" << endl);
430  }
431  }
432  // Deal with backward images, loop on number of images
433  for (int img=0; img<ap_ImageSpace->GetNbBackwardImages(); img++)
434  {
435  // Loop on basis functions
437  {
439  {
441  {
442  // Get the pointer to the image
443  int thread_0 = 0;
444  FLTNB* image = ap_ImageSpace->m6p_backwardImage[img][thread_0][tb][rb][cb];
445  // Apply convolution
447  }
448  }
449  }
450  }
451  // Deal with sensitivity images for histogram reconstructions
452  if (!ap_ImageSpace->IsLoadedSensitivity())
453  {
454  // Loop on frames and gates
455  for (int fr=0; fr<mp_ImageDimensionsAndQuantification->GetNbTimeFrames(); fr++)
456  {
457  for (int rg=0; rg<mp_ImageDimensionsAndQuantification->GetNb1stMotImgsForLMS(fr); rg++)
458  {
460  {
461  // Get the pointer to the image
462  int thread_0 = 0;
463  FLTNB* image = ap_ImageSpace->m5p_sensitivity[thread_0][fr][rg][cg];
464  // Apply convolution
466  }
467  }
468  }
469  }
470  }
471  }
472  // Normal end
473  return 0;
474 }
475 
476 // =====================================================================
477 // ---------------------------------------------------------------------
478 // ---------------------------------------------------------------------
479 // =====================================================================
480 
482 {
483  #ifdef CASTOR_DEBUG
484  // Check if initialized
485  if (!m_initialized)
486  {
487  Cerr("***** oImageConvolverManager::ConvolveIntra() -> Called while not initialized !" << endl);
488  return 1;
489  }
490  #endif
491  // Loop on convolvers
492  for (int c=0; c<m_nbImageConvolvers; c++)
493  {
494  // Apply it only if asked for
495  if (mp_applyIntra[c])
496  {
497  // Verbose
498  if (m_verbose>=2)
499  {
500  if (m_nbImageConvolvers>1) Cout("oImageConvolverManager::ConvolveIntra() -> Apply convolution " << c+1 << " to current image" << endl);
501  else Cout("oImageConvolverManager::ConvolveIntra() -> Apply convolution to current image" << endl);
502  }
503  // Loop on basis functions
505  {
507  {
509  {
510  // Get the pointer to the image
511  FLTNB* image = ap_ImageSpace->m4p_image[tb][rb][cb];
512  // Apply convolution
514  }
515  }
516  }
517  }
518  }
519  // Normal end
520  return 0;
521 }
522 
523 // =====================================================================
524 // ---------------------------------------------------------------------
525 // ---------------------------------------------------------------------
526 // =====================================================================
527 
529 {
530  #ifdef CASTOR_DEBUG
531  // Check if initialized
532  if (!m_initialized)
533  {
534  Cerr("***** oImageConvolverManager::ConvolveSensitivity() -> Called while not initialized !" << endl);
535  return 1;
536  }
537  #endif
538  // Loop on convolvers
539  for (int c=0; c<m_nbImageConvolvers; c++)
540  {
541  // Apply it only if asked for
542  if (mp_applyBackward[c])
543  {
544  // Verbose
545  if (m_verbose>=2)
546  {
547  if (m_nbImageConvolvers>1) Cout("oImageConvolverManager::ConvolveSensitivity() -> Apply convolution " << c+1 << " to sensitivity image" << endl);
548  else Cout("oImageConvolverManager::ConvolveSensitivity() -> Apply convolution to sensitivity image" << endl);
549  }
550  // Loop on frames and gates
551  for (int fr=0; fr<mp_ImageDimensionsAndQuantification->GetNbTimeFrames(); fr++)
552  {
553  for (int rg=0; rg<mp_ImageDimensionsAndQuantification->GetNb1stMotImgsForLMS(fr); rg++)
554  {
556  {
557  // Get the pointer to the image
558  int thread_0 = 0;
559  FLTNB* image = ap_ImageSpace->m5p_sensitivity[thread_0][fr][rg][cg];
560  // Apply convolution
562  }
563  }
564  }
565  }
566  }
567  // Normal end
568  return 0;
569 }
570 
571 // =====================================================================
572 // ---------------------------------------------------------------------
573 // ---------------------------------------------------------------------
574 // =====================================================================
575 
577 {
578  #ifdef CASTOR_DEBUG
579  // Check if initialized
580  if (!m_initialized)
581  {
582  Cerr("***** oImageConvolverManager::ConvolvePost() -> Called while not initialized !" << endl);
583  return 1;
584  }
585  #endif
586  // Loop on convolvers
587  for (int c=0; c<m_nbImageConvolvers; c++)
588  {
589  // Apply it only if asked for
590  if (mp_applyPost[c])
591  {
592  // Verbose
593  if (m_verbose>=2)
594  {
595  if (m_nbImageConvolvers>1) Cout("oImageConvolverManager::ConvolvePost() -> Apply convolution " << c+1 << " to output image" << endl);
596  else Cout("oImageConvolverManager::ConvolvePost() -> Apply convolution to output image" << endl);
597  }
598 
599  // Loop on frames and respiratory/cardiac gates
600  for (int fr=0; fr<mp_ImageDimensionsAndQuantification->GetNbTimeFrames(); fr++)
601  {
602  for (int rg=0; rg<mp_ImageDimensionsAndQuantification->GetNbRespGates(); rg++)
603  {
604  for (int cg=0; cg<mp_ImageDimensionsAndQuantification->GetNbCardGates(); cg++)
605  {
606  // Get the pointer to the output image
607  FLTNB* image = ap_ImageSpace->m4p_outputImage[fr][rg][cg];
608  // Apply convolution
610  }
611  }
612  }
613  }
614  }
615  // Normal end
616  return 0;
617 }
618 
619 // =====================================================================
620 // ---------------------------------------------------------------------
621 // ---------------------------------------------------------------------
622 // =====================================================================
int ParseOptionsAndInitializeImageConvolvers()
A function used to parse options and initialize image convolvers.
FLTNB **** m4p_forwardImage
Definition: oImageSpace.hh:88
int GetNbCardBasisFunctions()
Get the number of cardiac basis functions.
#define FLTNB
Definition: gVariables.hh:81
int GetNb1stMotImgsForLMS(int a_fr)
call the eponym function from the oDynamicDataManager object
bool IsLoadedSensitivity()
Definition: oImageSpace.hh:636
int ConvolveForward(oImageSpace *ap_ImageSpace)
A function used to apply convolvers onto the forward image of the oImageSpace.
int CheckParameters()
A function used to check the parameters settings.
oImageConvolverManager()
The constructor of oImageConvolverManager.
int GetNbTimeBasisFunctions()
Get the number of time basis functions.
static sOutputManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
int ConvolvePost(oImageSpace *ap_ImageSpace)
A function used to apply convolvers onto the output image of the oImageSpace.
int ConvolveIntra(oImageSpace *ap_ImageSpace)
A function used to apply convolvers onto the current image of the oImageSpace.
static sAddonManager * GetInstance()
Declaration of class oImageConvolverManager.
#define Cerr(MESSAGE)
FLTNB ****** m6p_backwardImage
Definition: oImageSpace.hh:95
FLTNB **** m4p_image
Definition: oImageSpace.hh:81
const string & GetPathToConfigDir()
Return the path to the CASTOR config directory.
FLTNB **** m4p_outputImage
Definition: oImageSpace.hh:144
int GetNbBackwardImages()
Definition: oImageSpace.hh:630
int ConvolveBackward(oImageSpace *ap_ImageSpace)
A function used to apply convolvers onto the backward images of the oImageSpace.
int ApplyConvolutionTranspose(FLTNB *ap_image)
A public function used to apply the transpose convolution module on the provided image.
static void ShowCommonHelp()
This function does not take any parameter and is used to display some help about the syntax of the op...
~oImageConvolverManager()
The destructor of oImageConvolverManager.
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
int ApplyConvolution(FLTNB *ap_image)
A public function used to apply the convolution module on the provided image.
int GetNbCardGates()
Get the number of cardiac gates.
This class holds all the matrices in the image domain that can be used in the algorithm: image...
Definition: oImageSpace.hh:61
std::map< string, maker_image_convolver > mp_listOfImageConvolvers
int GetNbTimeFrames()
Get the number of time frames.
int GetNb2ndMotImgsForLMS()
call the eponym function from the oDynamicDataManager object
void SetVerbose(int a_verbose)
Set the member m_verboseLevel to the provided value.
int GetNbRespGates()
Get the number of respiratory gates.
#define Cout(MESSAGE)
int ConvolveSensitivity(oImageSpace *ap_ImageSpace)
A function used to apply convolvers onto the sensitivity image of the oImageSpace.
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
Set the member mp_ImageDimensionsAndQuantification to the provided value.
vImageConvolver ** m2p_ImageConvolvers
int GetNbRespBasisFunctions()
Get the number of respiratory basis functions.
FLTNB ***** m5p_sensitivity
Definition: oImageSpace.hh:105
Declaration of class sAddonManager.
This abstract class is the generic image convolver class used by the oImageConvolverManager.
int Initialize()
A function used to initialize the manager and all image convolvers it manages.
void ShowHelpImageConvolver()
Show help about all implemented image convolvers.