/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLGeom/src/ICLGeom/RansacBasedPoseEstimator.cpp ** ** Module : ICLGeom ** ** Authors: Christof Elbrechter ** ** ** ** ** ** GNU LESSER GENERAL PUBLIC LICENSE ** ** This file may be used under the terms of the GNU Lesser General ** ** Public License version 3.0 as published by the ** ** ** ** Free Software Foundation and appearing in the file LICENSE.LGPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the license requirements will ** ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** ********************************************************************/ #include #include #include #include #include namespace icl{ namespace geom{ using namespace math; using namespace utils; struct RansacBasedPoseEstimator::Data{ // int iterations; //int minPoints; //float maxError; //float minPointsForGoodModel; Camera camera; CoplanarPointPoseEstimator pe; std::vector lastConsensusSet; }; #if 0 static icl64f err_coplanar_verbose(const std::vector &m, const std::vector &p, const Camera &cam){ std::cout << "model: [" << m[0] << ", " << m[1] << ", " << m[2] << ", " << m[3] << ", " << m[4] << ", " << m[5] << "]" << std::endl; Mat T = create_hom_4x4(m[0],m[1],m[2],m[3],m[4],m[5]); SHOW(T); SHOW(T * Vec(p[2],p[3],0,1)); Point32f q = cam.project(T * Vec(p[2], p[3], 0, 1)); SHOW(q); icl64f err = sqr(p[0] - q[0]) + sqr(p[1] - q[1]); return err; } #endif icl64f RansacBasedPoseEstimator::err_coplanar(const std::vector &m, const std::vector &p){ Mat T = create_hom_4x4(m[0],m[1],m[2],m[3],m[4],m[5]); Point32f q = m_data->camera.project(T * Vec(p[2], p[3], 0, 1)); icl64f err = sqr(p[0] - q[0]) + sqr(p[1] - q[1]); return err; } #if 0 static icl64f mean_error(const std::vector > &pts, const std::vector &m, Function &, const std::vector &> err_coplanar, const Camera &cam){ //std::cout << "mean error "; icl64f err = 0; for(size_t i=0;i RansacBasedPoseEstimator::fit_coplanar(const std::vector > &pts){ //DEBUG_LOG("------------- fitting on " << pts.size() << " point"); //std::cout << "Points:: ["; std::vector curr(pts.size()),templ(pts.size()); for(size_t i=0;i" << templ[i] << (i < pts.size()-1 ? ",": "]\n"); } Mat T = m_data->pe.getPose(pts.size(), templ.data(), curr.data(), m_data->camera); //SHOW(T); Vec3 e = extract_euler_angles(T); std::vector p(6); p[0] = e[0]; p[1] = e[1]; p[2] = e[2]; p[3] = T(3,0); p[4] = T(3,1); p[5] = T(3,2); /* std::cout << "model: [" << p[0] << ", " << p[1] << ", " << p[2] << ", " << p[3] << ", " << p[4] << ", " << p[5] << "] " << std::endl; std::cout << "(Err: " << mean_error(pts, p, function(this,&RansacBasedPoseEstimator::err_coplanar), m_data->camera) << ")"<< std::endl; */ return p; } RansacBasedPoseEstimator::RansacBasedPoseEstimator(const geom::Camera &camera, int iterations, int minPoints, float maxErr, float minPointsForGoodModel, bool storeLastConsensusSet){ m_data = new Data; addProperty("iterations","range","[1,1000000]:1",str(iterations)); addProperty("min points","range","[1,1000000]:1",str(minPoints)); addProperty("max error","range","[0,10e30]",str(maxErr)); addProperty("min points for good model", "range", "[0,10000000]:1",str(minPointsForGoodModel)); addProperty("debug output","flag","",false); addProperty("store last consensus set","flag","",storeLastConsensusSet); addChildConfigurable(&m_data->pe,"pose estimator"); setPropertyValue("pose estimator.algorithm","HomographyBasedOnly"); m_data->camera = camera; } void RansacBasedPoseEstimator::setStoreLastConsensusSet(bool on){ setPropertyValue("store last consensus set",on); } std::vector RansacBasedPoseEstimator::getLastConsensusSet() throw (utils::ICLException){ bool hasSet = getPropertyValue("store last consensus set"); if(!hasSet) throw utils::ICLException("RansacBasedPoseEstimator::getLastConsensusSet() even though " "'store last consensus set' property was not set to 'true'"); return m_data->lastConsensusSet; } RansacBasedPoseEstimator::~RansacBasedPoseEstimator(){ delete m_data; } void RansacBasedPoseEstimator::setIterations(int iterations){ setPropertyValue("iterations",iterations); } void RansacBasedPoseEstimator::setMinPoints(int minPoints){ setPropertyValue("min points",minPoints); } void RansacBasedPoseEstimator::setMaxError(float maxError){ setPropertyValue("max error",maxError); } void RansacBasedPoseEstimator::setMinPointsForGoodModel(float f){ setPropertyValue("min points for good model", f); } RansacBasedPoseEstimator::Result RansacBasedPoseEstimator::fit(const std::vector &templ, const std::vector &curr){ int iterations = getPropertyValue("iterations"); int maxError = getPropertyValue("max error"); int minPoints = getPropertyValue("min points"); int minPointsForGoodModel = getPropertyValue("min points for good model"); bool dbg = getPropertyValue("debug output"); RansacFitter<> ransac(minPoints, iterations, function(this,&RansacBasedPoseEstimator::fit_coplanar), function(this,&RansacBasedPoseEstimator::err_coplanar), maxError, minPointsForGoodModel); RansacFitter<>::DataSet data(curr.size(), std::vector(4,0)); for(size_t i=0;i " << templ[i]); //} } if(dbg){ DEBUG_LOG("using these parameters:"); SHOW(minPoints); SHOW(iterations); SHOW(maxError); SHOW(minPointsForGoodModel); SHOW(curr.size()); SHOW(data.size()); } const RansacFitter<>::Result &res = ransac.fit(data); if(getPropertyValue("store last consensus set")){ m_data->lastConsensusSet.resize(res.consensusSet.size()); for(size_t i=0;ilastConsensusSet.size();++i){ m_data->lastConsensusSet[i] = Point32f(res.consensusSet[i][0], res.consensusSet[i][1]); } } if(res.found()){ const std::vector &m = res.model; Mat T = create_hom_4x4(m[0],m[1],m[2],m[3],m[4],m[5]); if(dbg){ DEBUG_LOG("result was found: \n" << T << "\n"); } Result r = { T, true, (float)res.error }; return r; }else{ if(dbg){ DEBUG_LOG("result was not found"); } } Result r = { Mat::id(), false, float(-1) }; return r; } RansacBasedPoseEstimator::Result RansacBasedPoseEstimator::fit(const std::vector &modelPoints, const std::vector &imagePoints){ throw ICLException("RansacBasedPoseEstimator::fit is not yet implemented for non-planar targets"); Result r = { Mat::id(), false, float(-1) }; return r; } } }