GeodesicActiveContourStep.hpp

00001 #ifndef EQUATION_GEODESICACTIVECONTOURSTEP_H
00002 #define EQUATION_GEODESICACTIVECONTOURSTEP_H
00003 
00004 #include <core/utilities.hpp>
00005 #include <fem/equation/SimpleEquationInterface.hpp>
00006 #include <boost/shared_ptr.hpp>
00007 
00008 namespace imaging
00009 {
00033   template<class fem_types>
00034   class GeodesicActiveContourStep : public SimpleEquationInterface<fem_types>
00035   {
00036     boost::shared_ptr< ublas::vector<float_t> > _edges_ptr;
00037     boost::shared_ptr< ublas::vector<float_t> > _initial_function_ptr;
00038     float_t _step_size;
00039     float_t _epsilon;
00040     float_t _edge_parameter;
00041     float_t _balloon_force;
00042     
00043     float_t regularized_abs(const ublas::fixed_vector<float_t, fem_types::data_dimension > & gradient) const
00044     {
00045       return sqrt(square(_epsilon) + inner_prod(gradient, gradient));
00046     }
00047 
00048   public:
00049     typedef ublas::fixed_matrix<float_t, fem_types::data_dimension, fem_types::data_dimension> matrix_coefficient_t;
00050 
00052     const ublas::vector<float_t> & edges() const { return *_edges_ptr; }
00053     
00055     void set_edges(boost::shared_ptr< ublas::vector<float_t> > edges_ptr) { _edges_ptr = edges_ptr; }
00056     
00058     const ublas::vector<float_t> & initial_function() const { return *_initial_function_ptr; }
00059     
00061     void set_initial_function(boost::shared_ptr< ublas::vector<float_t> > initial_function_ptr) { _initial_function_ptr = initial_function_ptr; }
00062     
00064     float_t step_size() const { return _step_size; }
00065     
00067     void set_step_size(float_t step_size) { _step_size = step_size; }
00068     
00070     float_t epsilon() const { return _epsilon;}
00071     
00073     void set_epsilon(float_t epsilon) { _epsilon = epsilon; }
00074     
00076     float_t edge_parameter() const { return _edge_parameter;}
00077     
00079     void set_edge_parameter(float_t edge_parameter) { _edge_parameter = edge_parameter; }
00080     
00082     float_t balloon_force() const { return _balloon_force;}
00083     
00085     void set_balloon_force(float_t balloon_force) { _balloon_force = balloon_force; }
00086     
00087     static const size_t boundary_data_type = SimpleEquationInterface<fem_types>::NO_BOUNDARY_DATA;
00088 
00089     static const bool a_active = false;
00090     static const bool b_active = false;
00091     static const bool c_active = true;
00092     static const bool f_active = true;
00093     static const bool g_active = false;
00094     
00095     void stiffness_matrix(std::size_t integrator_node,
00096                           const FemKernel<fem_types> & kernel,
00097                           matrix_coefficient_t & A,
00098                           ublas::fixed_vector<float_t, fem_types::data_dimension> & a,
00099                           ublas::fixed_vector<float_t, fem_types::data_dimension> & b,
00100                           float_t & c) const
00101     { 
00102       float_t local_edge;
00103       ublas::fixed_vector<float_t, fem_types::data_dimension > local_gradient;
00104       
00105       kernel.grid().interpolate_value(integrator_node, *_edges_ptr, kernel, local_edge);
00106       kernel.grid().interpolate_gradient(integrator_node, *_initial_function_ptr, kernel, local_gradient);
00107       
00108       A = _step_size * exp(- _edge_parameter * square(local_edge)) / regularized_abs(local_gradient) *
00109                 ublas::identity_matrix<float_t>(fem_types::data_dimension);
00110       
00111       c = 1.0 / regularized_abs(local_gradient);        
00112       
00113     }
00114     
00115     void force_vector(std::size_t integrator_node,
00116                       const FemKernel<fem_types> & kernel,
00117                       float_t & f,
00118                       ublas::fixed_vector<float_t, fem_types::data_dimension> & g) const
00119     {
00120     
00121       float_t local_edge, local_value;
00122       ublas::fixed_vector<float_t, fem_types::data_dimension > local_gradient;
00123       
00124       kernel.grid().interpolate_value(integrator_node, *_edges_ptr, kernel, local_edge);
00125       kernel.grid().interpolate_value(integrator_node, *_initial_function_ptr, kernel, local_value);
00126       kernel.grid().interpolate_gradient(integrator_node, *_initial_function_ptr, kernel, local_gradient);
00127       
00128       f =  local_value / regularized_abs(local_gradient) + _step_size * exp(- _edge_parameter * square(local_edge)) * _balloon_force;
00129     }
00130     
00131     bool sanity_check_stiffness_matrix(const FemKernel<fem_types> & kernel, std::string & error_message) const
00132     { 
00133       if(! (_edges_ptr && _initial_function_ptr))
00134         return false;
00135         
00136       if(_edges_ptr->size() != kernel.grid().n_nodes())
00137         return false;
00138         
00139       if(_initial_function_ptr->size() != kernel.grid().n_nodes())
00140         return false;
00141         
00142       return true;
00143     }
00144     
00145     bool sanity_check_force_vector(const FemKernel<fem_types> & kernel, std::string & error_message) const
00146     { 
00147       if(! (_edges_ptr && _initial_function_ptr))
00148         return false;
00149         
00150       if(_edges_ptr->size() != kernel.grid().n_nodes())
00151         return false;
00152         
00153       if(_initial_function_ptr->size() != kernel.grid().n_nodes())
00154         return false;
00155         
00156       return true;
00157     }
00158   };
00159 
00160 }
00161 
00162 
00163 #endif

Generated on Tue Feb 10 10:01:30 2009 for imaging2 by  doxygen 1.5.5