00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef SHAPE_SHAPESTATISTICS_H
00010 #define SHAPE_SHAPESTATISTICS_H
00011
00012 #include <shape/ShapeInterface.hpp>
00013 #include <lapack/linear_algebra.hpp>
00014 #include <core/distribution_utilities.hpp>
00015
00016 #include <map>
00017 #include <boost/shared_ptr.hpp>
00018
00019
00020 namespace imaging
00021 {
00022 namespace shape_statistics_impl
00023 {
00024 void constructor(const std::vector<const ShapeInterface*> shape_ptrs, ShapeInterface & mean_shape, ublas::matrix<float_t> & covariance);
00025 void compute_statistics(const std::map<std::size_t, float_t> & manual_modes, const ublas::matrix<float_t> & covariance, ublas::matrix<float_t> & root_of_covariance);
00026 }
00027
00037 template <class shape_t>
00038 class ShapeStatistics
00039 {
00040 const static std::size_t SHAPE_DIMENSION = shape_t::SHAPE_DIMENSION;
00041
00042 ublas::matrix<float_t> _covariance;
00043 ublas::matrix<float_t> _root_of_covariance;
00044
00045 shape_t _mean_shape;
00046
00047 std::map<std::size_t, float_t> _manual_modes;
00048
00049 public:
00050
00052 ShapeStatistics(const shape_t & mean_shape) :
00053 _mean_shape(mean_shape),
00054 _covariance(ublas::identity_matrix<float_t>(mean_shape.dimension())),
00055 _root_of_covariance(ublas::identity_matrix<float_t>(mean_shape.dimension())) {}
00056
00058 ShapeStatistics(const std::vector<shape_t> & shapes)
00059 {
00060 std::vector<const ShapeInterface *> shape_ptrs(shapes.size());
00061 for(size_t i = 0; i < shapes.size(); ++i)
00062 shape_ptrs[i] = &(shapes[i]);
00063
00064 shape_statistics_impl::constructor(shape_ptrs, _mean_shape, _covariance);
00065 }
00066
00068 ShapeStatistics(const std::vector< boost::shared_ptr<shape_t> > & shapes)
00069 {
00070 std::vector<const ShapeInterface *> shape_ptrs(shapes.size());
00071 for(size_t i = 0; i < shapes.size(); ++i)
00072 shape_ptrs[i] = shapes[i].get();
00073
00074 shape_statistics_impl::constructor(shape_ptrs, _mean_shape, _covariance);
00075 }
00076
00078 void set_mode_manually(std::size_t mode, float_t deviation)
00079 {
00080 _manual_modes.insert(std::pair<std::size_t, float_t>(mode, deviation));
00081 }
00082
00084 void compute_statistics()
00085 {
00086 shape_statistics_impl::compute_statistics(_manual_modes, _covariance, _root_of_covariance);
00087 }
00088
00090 void shape_vector(const ublas::vector<float_t> & coefficients, ublas::vector<float_t> & vector) const
00091 {
00092 vector.resize(dimension());
00093 vector = prod(_root_of_covariance, coefficients);
00094 }
00095
00097 void shape_vector(const ublas::vector<float_t> & coefficients, ublas::vector<float_t> & vector, float_t & squared_distance) const
00098 {
00099 vector.resize(dimension());
00100 vector = prod(_root_of_covariance, coefficients);
00101
00102 squared_distance = 0.0;
00103 for(std::size_t i = 0; i < coefficients.size(); ++i)
00104 if(_manual_modes.count(i) == 0)
00105 squared_distance += square(coefficients(i));
00106 }
00107
00109 void shape_sample(const ublas::vector<float_t> & coefficients, shape_t & out_shape) const
00110 {
00111 float_t squared_distance;
00112 shape_sample(coefficients, out_shape, squared_distance);
00113 }
00114
00116 void shape_sample(const ublas::vector<float_t> & coefficients, shape_t & out_shape, float_t & squared_distance) const
00117 {
00118 ublas::vector<float_t> sample_vector(_mean_shape.dimension());
00119 shape_vector(coefficients, sample_vector, squared_distance);
00120
00121 _mean_shape.exponential(sample_vector, out_shape);
00122 }
00123
00125 void gradient(const ublas::vector<float_t> & coefficients, ublas::vector<float_t> & gradient) const
00126 {
00127 gradient.resize(_mean_shape.dimension());
00128
00129 gradient = 2 * coefficients;
00130
00131 for(std::map<std::size_t, float_t>::const_iterator iter = _manual_modes.begin(); iter != _manual_modes.end(); ++iter)
00132 gradient(iter->first) = 0.0;
00133 }
00134
00136 void random_shape_sample(float_t sample_radius, shape_t & out_shape, float_t & squared_distance) const
00137 {
00138 ublas::vector<float_t> coefficients(_covariance.size1());
00139
00140 for(std::size_t i = 0; i < coefficients.size(); ++i)
00141 {
00142 if(_manual_modes.count(i) > 0)
00143 coefficients(i) = symmetric_uniform_distribution();
00144 else
00145 coefficients(i) = sample_radius * normal_distribution();
00146 }
00147
00148 shape_sample(coefficients, out_shape, squared_distance);
00149 }
00150
00152 const shape_t & mean_shape() const { return _mean_shape; }
00153
00155 shape_t & mode_shape(std::size_t mode, float_t offset, shape_t & out_shape) const
00156 {
00157 float_t distance_from_mean;
00158
00159 ublas::vector<float_t> coefficients(_covariance.size1());
00160
00161 coefficients = ublas::scalar_vector<float_t>(coefficients.size(), 0.0);
00162
00163 coefficients(mode) = offset;
00164
00165 shape_sample(coefficients, out_shape, distance_from_mean);
00166
00167 return out_shape;
00168 }
00169
00171 size_t dimension() const
00172 {
00173 return _mean_shape.dimension();
00174 }
00175
00176 };
00177
00178 }
00179
00180
00181 #endif