Go to the documentation of this file.00001
00002 #include "rrel_mlesac_obj.h"
00003
00004 #include <vnl/vnl_math.h>
00005
00006 #include <vcl_cstdlib.h>
00007 #include <vcl_cmath.h>
00008
00009
00010 namespace {
00011 inline double sqr( double x ) { return x*x; }
00012 }
00013
00014
00015 rrel_mlesac_obj::rrel_mlesac_obj(unsigned int residual_dof, double outlier_sigma, double outlier_frac)
00016 : outlier_sigma_(outlier_sigma),
00017 outlier_frac_(outlier_frac),
00018 residual_dof_(residual_dof)
00019 {
00020 }
00021
00022 double
00023 rrel_mlesac_obj::fcn( vect_const_iter begin, vect_const_iter end,
00024 vect_const_iter scale,
00025 vnl_vector<double>* ) const
00026 {
00027 double value=0;
00028 double pi,p0,zi;
00029 vect_const_iter begin0 = begin;
00030 unsigned long num_residual = end - begin;
00031 double mult1 = 1.0 / (vcl_sqrt( 2 * vnl_math::pi ));
00032
00033 double inlier_frac = 1.0;
00034 double new_inlier_frac = 1 - outlier_frac_;
00035
00036 const double EPS = 0.01;
00037
00038
00039 while ( new_inlier_frac > EPS && vcl_abs((new_inlier_frac - inlier_frac) / inlier_frac) > EPS) {
00040 begin = begin0;
00041 inlier_frac = new_inlier_frac;
00042 new_inlier_frac = 0;
00043 for (; begin != end; ++begin, ++scale) {
00044 double const1 = vcl_pow(mult1 / (*scale), (int)residual_dof_) ;
00045 pi = inlier_frac * const1 * vcl_exp( - sqr(*begin) / ( 2.0 * sqr(*scale) ) );
00046 p0 = (1 - inlier_frac) / outlier_sigma_;
00047 zi = pi / ( pi + p0 );
00048 new_inlier_frac += zi;
00049 }
00050 new_inlier_frac = new_inlier_frac / num_residual;
00051 }
00052
00053 begin = begin0;
00054
00055 for ( ; begin != end; ++begin) {
00056 double const1 = vcl_pow(mult1 / (*scale), (int)residual_dof_) ;
00057 pi = new_inlier_frac * const1 * vcl_exp( - sqr(*begin) / ( 2.0 * sqr(*scale) ) );
00058 p0= ( 1 - new_inlier_frac ) / outlier_sigma_;
00059 value -= vcl_log( pi + p0 );
00060 }
00061
00062 return value;
00063 }
00064
00065 double
00066 rrel_mlesac_obj::fcn( vect_const_iter begin, vect_const_iter end,
00067 double scale,
00068 vnl_vector<double>* ) const
00069 {
00070 double value=0;
00071 double pi,p0,zi;
00072 vect_const_iter begin0 = begin;
00073 unsigned long num_residual = end - begin;
00074
00075 double inlier_frac = 1.0;
00076 double new_inlier_frac = 1 - outlier_frac_;
00077 double mult1 = 1.0 / (vcl_sqrt( 2 * vnl_math::pi ) * scale);
00078 double const1 = vcl_pow(mult1, (int)residual_dof_) ;
00079 double exp_mult2 = -1.0 / (2.0 * sqr(scale));
00080
00081 const double EPS = 0.01;
00082
00083
00084 while ( new_inlier_frac > EPS && vcl_abs((new_inlier_frac - inlier_frac) / inlier_frac) > EPS) {
00085 begin = begin0;
00086 inlier_frac = new_inlier_frac;
00087 new_inlier_frac = 0;
00088 for (; begin != end; ++begin) {
00089 pi = inlier_frac * const1 * vcl_exp( sqr(*begin) * exp_mult2 );
00090 p0 = (1 - inlier_frac) / outlier_sigma_;
00091 zi = pi / ( pi + p0 );
00092 new_inlier_frac += zi;
00093 }
00094 new_inlier_frac = new_inlier_frac / num_residual;
00095 }
00096
00097 begin = begin0;
00098
00099 for ( ; begin != end; ++begin) {
00100 pi = new_inlier_frac * const1 * vcl_exp( sqr(*begin) * exp_mult2 );
00101 p0= ( 1 - new_inlier_frac ) / outlier_sigma_;
00102 value -= vcl_log( pi + p0 );
00103 }
00104
00105 return value;
00106 }