sac_model_oriented_line.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2009 Radu Bogdan Rusu <rusu -=- cs.tum.edu>
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright
00012  *       notice, this list of conditions and the following disclaimer in the
00013  *       documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  * $Id$
00028  *
00029  */
00030 
00036 #include <door_handle_detector/sample_consensus/sac_model_oriented_line.h>
00037 #include <door_handle_detector/geometry/angles.h>
00038 #include <door_handle_detector/geometry/point.h>
00039 #include <door_handle_detector/geometry/nearest.h>
00040 
00041 namespace sample_consensus
00042 {
00044 
00051   void
00052     SACModelOrientedLine::selectWithinDistance (const std::vector<double> &model_coefficients, double threshold, std::vector<int> &inliers)
00053   {
00054     double sqr_threshold = threshold * threshold;
00055 
00056     // Obtain the line direction
00057     geometry_msgs::Point32 p3, p4;
00058     p3.x = model_coefficients.at (3) - model_coefficients.at (0);
00059     p3.y = model_coefficients.at (4) - model_coefficients.at (1);
00060     p3.z = model_coefficients.at (5) - model_coefficients.at (2);
00061 
00062     double angle_error = cloud_geometry::angles::getAngle3D (axis_, p3);
00063 
00064     // Check whether the current line model satisfies our angle threshold criterion with respect to the given axis
00065     if (angle_error >  eps_angle_)
00066     {
00067       inliers.resize (0);
00068       return;
00069     }
00070 
00071     int nr_p = 0;
00072     inliers.resize (indices_.size ());
00073     // Iterate through the 3d points and calculate the distances from them to the plane
00074     for (unsigned int i = 0; i < indices_.size (); i++)
00075     {
00076       // Calculate the distance from the point to the line
00077       // D = ||(P2-P1) x (P1-P0)|| / ||P2-P1|| = norm (cross (p2-p1, p2-p0)) / norm(p2-p1)
00078       // P1, P2 = line points, P0 = query point
00079       // P1P2 = <x2-x1, y2-y1, z2-z1> = <x3, y3, z3>
00080       // P1P0 = < x-x1,  y-y1, z-z1 > = <x4, y4, z4>
00081       // P1P2 x P1P0 = < y3*z4 - z3*y4, -(x3*z4 - x4*z3), x3*y4 - x4*y3 >
00082       //             = < (y2-y1)*(z-z1) - (z2-z1)*(y-y1), -[(x2-x1)*(z-z1) - (x-x1)*(z2-z1)], (x2-x1)*(y-y1) - (x-x1)*(y2-y1) >
00083       p4.x = model_coefficients.at (3) - cloud_->points.at (indices_.at (i)).x;
00084       p4.y = model_coefficients.at (4) - cloud_->points.at (indices_.at (i)).y;
00085       p4.z = model_coefficients.at (5) - cloud_->points.at (indices_.at (i)).z;
00086 
00087       // P1P2 = sqrt (x3^2 + y3^2 + z3^2)
00088       // a = sqrt [(y3*z4 - z3*y4)^2 + (x3*z4 - x4*z3)^2 + (x3*y4 - x4*y3)^2]
00089       //double distance = SQR_NORM (cANN::cross (p4, p3)) / SQR_NORM (p3);
00090       geometry_msgs::Point32 c = cloud_geometry::cross (p4, p3);
00091       double sqr_distance = (c.x * c.x + c.y * c.y + c.z * c.z) / (p3.x * p3.x + p3.y * p3.y + p3.z * p3.z);
00092 
00093       if (sqr_distance < sqr_threshold)
00094       {
00095         // Returns the indices of the points whose squared distances are smaller than the threshold
00096         inliers[nr_p] = indices_[i];
00097         nr_p++;
00098       }
00099     }
00100     inliers.resize (nr_p);
00101     return;
00102   }
00103 
00105 
00109   void
00110     SACModelOrientedLine::getDistancesToModel (const std::vector<double> &model_coefficients, std::vector<double> &distances)
00111   {
00112     // Obtain the line direction
00113     geometry_msgs::Point32 p3, p4;
00114     p3.x = model_coefficients.at (3) - model_coefficients.at (0);
00115     p3.y = model_coefficients.at (4) - model_coefficients.at (1);
00116     p3.z = model_coefficients.at (5) - model_coefficients.at (2);
00117 
00118     double angle_error = cloud_geometry::angles::getAngle3D (axis_, p3);
00119 
00120     // Check whether the current line model satisfies our angle threshold criterion with respect to the given axis
00121     if (angle_error >  eps_angle_)
00122     {
00123       distances.resize (0);
00124       return;
00125     }
00126 
00127     distances.resize (indices_.size ());
00128     // Iterate through the 3d points and calculate the distances from them to the plane
00129     for (unsigned int i = 0; i < indices_.size (); i++)
00130     {
00131       // Calculate the distance from the point to the line
00132       // D = ||(P2-P1) x (P1-P0)|| / ||P2-P1|| = norm (cross (p2-p1, p2-p0)) / norm(p2-p1)
00133       p4.x = model_coefficients.at (3) - cloud_->points.at (indices_.at (i)).x;
00134       p4.y = model_coefficients.at (4) - cloud_->points.at (indices_.at (i)).y;
00135       p4.z = model_coefficients.at (5) - cloud_->points.at (indices_.at (i)).z;
00136 
00137       geometry_msgs::Point32 c = cloud_geometry::cross (p4, p3);
00138       distances[i] = sqrt (c.x * c.x + c.y * c.y + c.z * c.z) / (p3.x * p3.x + p3.y * p3.y + p3.z * p3.z);
00139     }
00140     return;
00141   }
00142 
00143 }


door_handle_detector
Author(s): Radu Bogdan Rusu, Marius
autogenerated on Wed Dec 11 2013 14:17:01