/home/oan/prosjekt/gotools/segmentation/gpl_distro/lsseg_1.0_gpl/src/SingleRegionAlgorithm.C

Go to the documentation of this file.
00001 //===========================================================================
00002 // The Level-Set Segmentation Library (LSSEG)
00003 //
00004 //
00005 // Copyright (C) 2000-2005 SINTEF ICT, Applied Mathematics, Norway.
00006 //
00007 // This program is free software; you can redistribute it and/or          
00008 // modify it under the terms of the GNU General Public License            
00009 // as published by the Free Software Foundation version 2 of the License. 
00010 //
00011 // This program is distributed in the hope that it will be useful,        
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00014 // GNU General Public License for more details.                           
00015 //
00016 // You should have received a copy of the GNU General Public License      
00017 // along with this program; if not, write to the Free Software            
00018 // Foundation, Inc.,                                                      
00019 // 59 Temple Place - Suite 330,                                           
00020 // Boston, MA  02111-1307, USA.                                           
00021 //
00022 // Contact information: e-mail: tor.dokken@sintef.no                      
00023 // SINTEF ICT, Department of Applied Mathematics,                         
00024 // P.O. Box 124 Blindern,                                                 
00025 // 0314 Oslo, Norway.                                                     
00026 // 
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //
00033 //===========================================================================
00034 //===========================================================================
00035 //                                                                           
00036 // File: SingleRegionAlgorithm.C                                             
00037 //                                                                           
00038 // Created: Tue Feb 21 13:14:07 2006                                         
00039 //                                                                           
00040 // Author: Odd A. Andersen <Odd.Andersen@sintef.no>
00041 //                                                                           
00042 // Revision: $Id: SingleRegionAlgorithm.C,v 1.9 2006/11/13 02:29:28 oan Exp $
00043 //                                                                           
00044 // Description:
00047 //                                                                           
00048 //===========================================================================
00049 
00050 #include "SingleRegionAlgorithm.h"
00051 
00052 #include "BorderCondition.h"
00053 #include <assert.h>
00054 #include <limits>
00055 #include "Mask.h"
00056 #include "simple_tools.h"
00057 #include "level_set.h"
00058 #include "cimg_dependent.h" // for debug purposes
00059 
00060 using namespace std;
00061 
00062 namespace lsseg {
00063 
00064 //===========================================================================
00065 double develop_single_region_2D(Region& reg, int num_iter, int reinit_modulo, const Mask* geom_mask)
00066 //===========================================================================
00067 {
00068     // constants that are candidates to be user-defined
00069     const int MASK_WIDTH = 2;
00070     const BorderCondition bcond = NEUMANN;
00071 
00072     assert(int(reg.phi.dimz()) == 1); // this function is written for the 2D case
00073     assert(!geom_mask || geom_mask->numChannels() == 1);
00074     assert(!geom_mask || reg.phi.size_compatible(*geom_mask));
00075 
00076     LevelSetFunction curv_term(reg.phi, false);
00077     LevelSetFunction norm_term(reg.phi, false);
00078     Mask old_mask, mask(reg.phi, false);
00079     if (geom_mask) {
00080         mask = *geom_mask;
00081     } else {
00082         mask = 1;
00083     }
00084     const double mu = reg.mu;
00085     double time_accum = 0;
00086     for (int i = 0; i < num_iter; ++i) {
00087         
00088         // compute border mask
00089         mask.swap(old_mask);
00090         make_border_mask(reg.phi, mask, MASK_WIDTH, &old_mask);
00091         if (geom_mask) {
00092             mask.intersect(*geom_mask);
00093         }
00094 
00095         // compute curvature-driven force
00096         reg.phi.curvatureTimesGrad2D(curv_term, &mask);
00097 
00098         // compute normal force
00099         reg.fgen->update(reg.phi);
00100         reg.fgen->force(norm_term, &mask);
00101         
00102         double H1, H2;
00103         //display_image(norm_term);
00104         normal_direction_flow_2D(reg.phi, 
00105                                  norm_term, 
00106                                  bcond, 
00107                                  H1, 
00108                                  H2, 
00109                                  &mask, 
00110                                  geom_mask); // change to 2D
00111 
00112         // computing maximum allowed time step
00113         const double dt = double(1) / (4 * reg.mu + H1 + H2);
00114         
00115         const double* nt = norm_term.begin();
00116         const double* ct = curv_term.begin();
00117         const char* msk = mask.begin();
00118         const double* end = reg.phi.end();
00119         for (double* cur = reg.phi.begin(); cur != end; ++cur, ++nt, ++msk, ++ct) {
00120             if (*msk) {
00121                 *cur += dt * (mu * (*ct) + (*nt));
00122             }
00123         }
00124         time_accum += dt;
00125         if (reinit_modulo && ((i+1) % reinit_modulo == 0)) {
00126             reg.phi.reinitialize2D(&mask);
00127         }
00128     }
00129     return time_accum;
00130 }
00131 
00132 //===========================================================================
00133 double develop_single_region_3D(Region& reg, int num_iter, int reinit_modulo, const Mask* geom_mask)
00134 //===========================================================================
00135 {
00136     // constants that are candidates to be user-defined
00137     const int MASK_WIDTH = 2;
00138     const BorderCondition bcond = NEUMANN;
00139 
00140     assert(!geom_mask || geom_mask->numChannels() == 1);
00141     assert(!geom_mask || reg.phi.size_compatible(*geom_mask));
00142 
00143     LevelSetFunction curv_term(reg.phi, false);
00144     LevelSetFunction norm_term(reg.phi, false);
00145     Mask old_mask, mask(reg.phi, false);
00146     if (geom_mask) {
00147         mask = *geom_mask;
00148     } else {
00149         mask = 1;
00150     }
00151 
00152     const double mu = reg.mu;
00153     double time_accum = 0;
00154     for (int i = 0; i < num_iter; ++i) {
00155         
00156         // compute border mask
00157         //make_border_mask(reg.phi, mask, MASK_WIDTH, geom_mask);
00158         mask.swap(old_mask);
00159         make_border_mask(reg.phi, mask, MASK_WIDTH, &old_mask);
00160         if (geom_mask) {
00161             mask.intersect(*geom_mask);
00162         }
00163 
00164         // compute curvature-driven force
00165         reg.phi.curvatureTimesGrad3D(curv_term, &mask);
00166 
00167         // compute normal force
00168         reg.fgen->update(reg.phi);
00169         reg.fgen->force(norm_term, &mask);
00170         
00171         double H1, H2, H3;
00172         //display_image(norm_term);
00173         normal_direction_flow_3D(reg.phi, 
00174                                  norm_term, 
00175                                  bcond, 
00176                                  H1, 
00177                                  H2, 
00178                                  H3,
00179                                  &mask, 
00180                                  geom_mask); // change to 3D
00181 
00182         // computing maximum allowed time step
00183         const double dt = double(1) / (4 * reg.mu + H1 + H2 + H3);
00184         
00185         const double* nt = norm_term.begin();
00186         const double* ct = curv_term.begin();
00187         const char* msk = mask.begin();
00188         const double* end = reg.phi.end();
00189         for (double* cur = reg.phi.begin(); cur != end; ++cur, ++nt, ++msk, ++ct) {
00190             if (*msk) {
00191                 *cur += dt * (mu * (*ct) + (*nt));
00192             }
00193         }
00194         time_accum += dt;
00195         if (reinit_modulo && ((i+1) % reinit_modulo == 0)) {
00196             reg.phi.reinitialize3D(&mask);
00197         }
00198     }
00199     return time_accum;
00200 }
00201 
00202 
00203 
00204 }; // end namespace lsseg
00205 
00206 

Generated on Tue Nov 28 18:35:47 2006 for lsseg by  doxygen 1.4.7