/******************************************************************** ** 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/SoftPosit.cpp ** ** Module : ICLGeom ** ** Authors: Christian Groszewski ** ** ** ** ** ** 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 using namespace icl::utils; using namespace icl::math; #ifdef ICL_HAVE_QT using namespace icl::qt; #endif namespace icl{ namespace geom{ const double SoftPosit::betaUpdate = 1.05; const double SoftPosit::betaZero = 0.0004; #ifdef ICL_HAVE_QT SoftPosit::SoftPosit():dw(0){ ROT.setBounds(3,3); T.setBounds(1,3); R1.setBounds(1,3); R2.setBounds(1,3); R3.setBounds(1,3); eye2_2.setBounds(2,2); eye2_2.at(0,0) = 1.0; eye2_2.at(1,1) = 1.0; draw = false; } #else SoftPosit::SoftPosit(){ ROT.setBounds(3,3); T.setBounds(1,3); R1.setBounds(1,3); R2.setBounds(1,3); R3.setBounds(1,3); eye2_2.setBounds(2,2); eye2_2.at(0,0) = 1.0; eye2_2.at(1,1) = 1.0; draw = false; } #endif SoftPosit::~SoftPosit(){} void SoftPosit::init(){ nbWorldPts = 7; nbImagePts = 8; Tz = 0.0; Tx = 0.0; Ty = 0.0; beta = betaZero; betaFinal=0.5; ////////////////////////////// alpha = 1.0; //9.21*noiseStd*noiseStd + 1; } void SoftPosit::softPosit(DynMatrix imagePts, DynMatrix worldPts, double beta0, int noiseStd, DynMatrix initRot, DynMatrix initTrans, double focalLength, DynMatrix center, bool draw){ col1.setBounds(1,imagePts.rows()); col2.setBounds(1,imagePts.rows()); betaFinal=0.5; // Max allowed error per world point int maxDelta = sqrt(alpha)/2; // Update rate on beta. double epsilon0 = 0.01; // % Used to initialize assignement matrix. int minBetaCount = 20; nbImagePts = imagePts.rows(); nbWorldPts = worldPts.rows(); distMat=DynMatrix(nbWorldPts,nbImagePts); //das ist dann gamma double max = iclMax(nbImagePts,nbWorldPts); double scale = 1.0/(max + 1); centeredImage.setBounds(imagePts.cols(),imagePts.rows()); for(unsigned int i=0;i imageOnes(1,nbImagePts,1); DynMatrix homogeneousWorldPts(4,nbWorldPts) ; for(unsigned int i=0;i temp(1,4,1); for(unsigned int i=0;i<3;++i){ temp.at(0,i)=ROT.at(i,2)/T.at(0,2); } DynMatrix wk = homogeneousWorldPts * temp; #ifdef ICL_HAVE_QT //DynMatrix projWorldPts = proj3dto2d(worldPts, rot, trans, focalLength, 1, center); if(draw){ proj3dto2d(worldPts, ROT, T, focalLength,1,center,pts2d); //visualize(w,imagePts, imageAdj, pts2d, worldAdj); visualize(imagePts, pts2d); } #endif //First two rows of the camera matrices (for both perspective and SOP). Note: //the scale factor is s = f/Tz = 1/Tz since f = 1. These are column 4-vectors. double t1[] = {ROT(0,0)/T.at(0,2),ROT(1,0)/T.at(0,2),ROT(2,0)/T.at(0,2), T.at(0,0)/T.at(0,2)}; double t2[] = {ROT(0,1)/T.at(0,2),ROT(1,1)/T.at(0,2),ROT(2,1)/T.at(0,2), T.at(0,1)/T.at(0,2)}; r1T = DynMatrix(1,4,t1); r2T = DynMatrix(1,4,t2); r3T.setBounds(1,4); int betaCount = 0; int poseConverged = 0; int assignConverged = 0; // int foundPose = 0; beta = beta0; DynMatrix r1Tr2T(2,3); assignMat = DynMatrix(nbWorldPts+1,nbImagePts+1,1+epsilon0); while ((beta < betaFinal) && !assignConverged){ projectedU = homogeneousWorldPts * r1T; projectedV = homogeneousWorldPts * r2T; replicatedProjectedU = imageOnes * projectedU.transp(); replicatedProjectedV = imageOnes * projectedV.transp(); col1 = centeredImage.col(0); wkxj = col1 * wk.transp(); col2 = centeredImage.col(1); wkyj = col2 * wk.transp(); //TODO optimize DynMatrix temp1 = replicatedProjectedU - wkxj; DynMatrix temp2 = replicatedProjectedV - wkyj; for(unsigned int i=0;i(nbWorldPts,1); for(unsigned int i=0;i(4,4); DynMatrix temp11(1,4); DynMatrix temp22(4,1); DynMatrix temp33(4,4); DynMatrix temp44(4,4); for (unsigned int k = 0;k 1e10){ std::cout << "cond L to small\n"; return; } invL = L.inv(); //poseConverged = 0; //TODO optimize weightedUi = DynMatrix(1,4); weightedVi = DynMatrix(1,4); DynMatrix temp55(1,4); DynMatrix temp66(1,4); for(unsigned int j = 0;j temp001(1,3); r3T.mult(1/Tz,temp001); wk = homogeneousWorldPts * temp001; //delta = sqrt(sum(sum(assignMat(1:nbImagePts,1:nbWorldPts) .* distMat))/nbWorldPts); temp001.setBounds(nbWorldPts,nbImagePts,false); for(unsigned int i=0;iminBetaCount) assignConverged = 1; else assignConverged = 0; T.at(0,0) = Tx; T.at(0,1) = Ty; T.at(0,2) = Tz; for(unsigned int i=0;i<3;++i){ ROT.at(i,0) = R1.at(0,i); ROT.at(i,1) = R2.at(0,i); ROT.at(i,2) = R3.at(0,i); } // if(delta < maxDelta && betaCount > minBetaCount) // foundPose = 1; //else // foundPose = 0; #ifdef ICL_HAVE_QT if(draw){ proj3dto2d(worldPts, ROT, T, focalLength, 1, center,pts2d); //visualize(w,imagePts, imageAdj, pts2d, worldAdj); visualize(imagePts,pts2d); } #endif } //SHOW(ROT); //SHOW(T); } #ifdef ICL_HAVE_QT void SoftPosit::softPosit(DynMatrix imagePts, DynMatrix imageAdj, DynMatrix worldPts, DynMatrix worldAdj, double beta0, int noiseStd, DynMatrix initRot, DynMatrix initTrans, double focalLength, ICLDrawWidget &w, DynMatrix center, bool draw){ dw = &w; iAdj = imageAdj; wAdj = worldAdj; softPosit(imagePts, worldPts, beta0, noiseStd, initRot, initTrans, focalLength, center); } #endif void SoftPosit::softPosit(std::vector imagePts, std::vector > worldPts, double beta0, int noiseStd, DynMatrix initRot, DynMatrix initTrans, double focalLength, DynMatrix center){ DynMatrix imagePt(2,imagePts.size()); for(unsigned int i=0; i worldPt(3,worldPts.size()); for(unsigned int i=0; i imagePts, DynMatrix imageAdj, std::vector > worldPts, DynMatrix worldAdj, double beta0, int noiseStd, DynMatrix initRot, DynMatrix initTrans, double focalLength, ICLDrawWidget &w, DynMatrix center,bool draw){ DynMatrix imagePt(2,imagePts.size()); for(unsigned int i=0; i worldPt(3,worldPts.size()); for(unsigned int i=0; i& SoftPosit::cross(DynMatrix &x, DynMatrix &y, DynMatrix &r){ if(x.cols()==1 && y.cols()==1 && x.rows()==3 && y.rows()==3){ r.at(0,0) = x.at(0,1)*y.at(0,2)-x.at(0,2)*y.at(0,1); r.at(0,1) = x.at(0,2)*y.at(0,0)-x.at(0,0)*y.at(0,2); r.at(0,2) = x.at(0,0)*y.at(0,1)-x.at(0,1)*y.at(0,0); } return r; } void SoftPosit::proj3dto2d(DynMatrix pts3d, DynMatrix &rot, DynMatrix &trans, double flength, int objdim, DynMatrix ¢er, DynMatrix &pts2d){ //3D point matrix must be 3xN. if (objdim == 1){ pts3d = pts3d.transp(); } //number of 3D points. unsigned int numpts = pts3d.cols(); DynMatrix newtrans(numpts,3); for(unsigned int i=0;i campts = rot*pts3d+newtrans; for(unsigned int i=0;i cent(numpts,2); for(unsigned int i=0;i &assignMat, DynMatrix &pos, DynMatrix &ratios){ unsigned int nrows = assignMat.rows()-1; double vmax =0.0; unsigned int imax=0; bool isMaxInRow = true; double cr = 0.0; double rr = 0.0; for(unsigned int k = 0;k &SoftPosit::sinkhornImp(DynMatrix &M){ int iMaxIterSinkhorn=60; double fEpsilon2 = 0.001; int iNumSinkIter = 0; unsigned int nbRows = M.rows(); unsigned int nbCols = M.cols(); double fMdiffSum = fEpsilon2 + 1; DynMatrix ratios; DynMatrix posmax; maxPosRatio(M,posmax,ratios); DynMatrix Mprev; DynMatrix McolSums; DynMatrix MrowSums; DynMatrix ones(1,M.cols(),1.0); DynMatrix MrowSumsRep; DynMatrix McolSumsRep; while(std::abs(fMdiffSum) > fEpsilon2 && iNumSinkIter < iMaxIterSinkhorn){ McolSums = DynMatrix(M.cols(),1); MrowSums = DynMatrix(1,M.rows()); Mprev = M; for(unsigned int j=0;j &assignMat){ int num = 0; int nrows = assignMat.rows(); double vmax = 0.0; int imax = 0; bool isMaxInRow = true; for(unsigned int k = 0 ;k &A){ DynMatrix U; DynMatrix V; DynMatrix s; A.svd(U,s,V); double n1 = max(s); (A.inv()).svd(U,s,V); double n2 = max(s); return n1 * n2; } double SoftPosit::max(DynMatrix s){ double max = s.at(0,0); for(unsigned int i=0;i & imagePts, const DynMatrix &projWorldPts, unsigned int delay){ dw->color(255,0,0,1); dw->linewidth(2); // dw->lock(); //dw->reset(); float offsetx=dw->size().rwidth()/2.0; float offsety=dw->size().rheight()/2.0; for(unsigned int i=0;iline(projWorldPts.at(0,i)+offsetx, projWorldPts.at(1,i)+offsety, projWorldPts.at(0,j)+offsetx, projWorldPts.at(1,j)+offsety); } } } dw->color(0,0,255,255); for(unsigned int i=0;iline(imagePts.at(0,i)+offsetx, imagePts.at(1,i)+offsety, imagePts.at(0,j)+offsetx, imagePts.at(1,j)+offsety); } } } //dw->unlock(); dw->render();//update(); Thread::msleep(delay); } void SoftPosit::visualize(ICLDrawWidget &w,const DynMatrix & imagePts, const DynMatrix &imageAdj, const DynMatrix &projWorldPts, const DynMatrix &worldAdj, unsigned int delay){ w.color(255,0,0,1); w.linewidth(2); // w.lock(); //w.reset(); float offsetx=w.size().rwidth()/2.0; float offsety=w.size().rheight()/2.0; for(unsigned int i=0;i