contrib/oxl/mvl/FMatrixComputeLMedSq.cxx
Go to the documentation of this file.
00001 #include "FMatrixComputeLMedSq.h"
00002 #include <mvl/HomgOperator2D.h>
00003 #include <vgl/vgl_homg_point_2d.h>
00004 #include <vgl/vgl_homg_line_2d.h>
00005 #include <vgl/algo/vgl_homg_operators_2d.h>
00006 #include <vcl_algorithm.h>
00007 
00008 FMatrixComputeLMedSq::FMatrixComputeLMedSq(bool rank2_truncate, int size)
00009 {
00010   rank2_truncate_ = rank2_truncate;
00011   double std = 1.4826*(1.0 + 5.0/(size - 7));
00012   // This gives the inlier thresh^2 minus the Median term (M)
00013   inthresh_ = (2.5*std)*(2.5*std);
00014 }
00015 
00016 FMatrixComputeLMedSq::~FMatrixComputeLMedSq() {}
00017 
00018 double FMatrixComputeLMedSq::calculate_term(vcl_vector<double>& residuals, vcl_vector<bool>& inlier_list, int& count)
00019 {
00020   double M = median(residuals);
00021   double thresh = inthresh_;
00022   thresh *= M;
00023   for (unsigned int i = 0; i < residuals.size(); i++) {
00024     if (residuals[i] < thresh) {
00025       inlier_list[i] = true;
00026       count++;
00027     } else {
00028       inlier_list[i] = false;
00029     }
00030   }
00031   return M;
00032 }
00033 
00034 double FMatrixComputeLMedSq::calculate_residual(vgl_homg_point_2d<double>& one,
00035                                                 vgl_homg_point_2d<double>& two,
00036                                                 FMatrix* F)
00037 {
00038   vgl_homg_line_2d<double> l1 = F->image2_epipolar_line(one);
00039   vgl_homg_line_2d<double> l2 = F->image1_epipolar_line(two);
00040   return vgl_homg_operators_2d<double>::perp_dist_squared(two, l1)
00041       +  vgl_homg_operators_2d<double>::perp_dist_squared(one, l2);
00042 }
00043 
00044 double FMatrixComputeLMedSq::calculate_residual(HomgPoint2D& one, HomgPoint2D& two, FMatrix* F)
00045 {
00046   HomgLine2D l1 = F->image2_epipolar_line(one);
00047   HomgLine2D l2 = F->image1_epipolar_line(two);
00048   return HomgOperator2D::perp_dist_squared(two, l1)
00049        + HomgOperator2D::perp_dist_squared(one, l2);
00050 }
00051 
00052 double FMatrixComputeLMedSq::median(vcl_vector<double> residuals)
00053 {
00054   vcl_sort(residuals.begin(), residuals.end());
00055   int size = residuals.size();
00056   int s2 = size / 2;
00057   return size == 0 ? 0.0 : size%2 ? residuals[s2] :
00058          (residuals[s2] + residuals[s2-1]) * 0.5;
00059 }